1

I'm facing the same issue since i start coding yesterday on my project which has a part of getting some of json data from a given api.

My api link is: http://alkadhum-col.edu.iq/wp-json/wp/v2/posts?_embed

I'm working on flutter SDK and i'm confused why it is not working with me!, my job is to get only link, title, and source_url objects but i cannot get it.

I tried the following code in flutter documentation
https://flutter.dev/docs/cookbook/networking/fetch-data and after some of modification according to my needs didn't got any data.

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<Post> fetchPost() async {
  final response =
      await http.get('http://alkadhum-col.edu.iq/wp-json/wp/v2/posts/');

  if (response.statusCode == 200) {
    // If the call to the server was successful, parse the JSON
    return Post.fromJson(json.decode(response.body));
  } else {
    // If that call was not successful, throw an error.
    throw Exception('Failed to load post');
  }
}

class Post {

  final int id;
  String title;
  String link;


  Post({this.id, this.title, this.link});

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      id: json['id'],
      title: json['title'].toString(),
      link: json['link'].toString()
    );
  }
}

void main() => runApp(MyApp(post: fetchPost()));

class MyApp extends StatelessWidget {
  final Future<Post> post;

  MyApp({Key key, this.post}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fetch Data Example'),
        ),
        body: Center(
          child: FutureBuilder<Post>(
            future: post,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data.link);
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }

              // By default, show a loading spinner
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

I only got the meesage below:
Type List dynamic is not a subtype of type Map String, dynamic

Any help will be appreciated.
Thanks in advance.

5 Answers 5

7

Your JSON response is of type List<dynamic> but you are taking response in Map String, dynamic but you can do something like this

     import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:clickmeetplay/iam/user/postbean.dart';
import 'package:http/http.dart' as http;

class PostHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Scaffold(body: PostScreen(),),);
  }
}

class PostScreen extends StatefulWidget {
  @override
  _PostScreenState createState() => _PostScreenState();
}

class _PostScreenState extends State<PostScreen> {

  List<Post> _postList =new List<Post>();

  Future<List<Post> > fetchPost() async {
    final response =
    await http.get('http://alkadhum-col.edu.iq/wp-json/wp/v2/posts/');

    if (response.statusCode == 200) {
      // If the call to the server was successful, parse the JSON
      List<dynamic> values=new List<dynamic>();
      values = json.decode(response.body);
      if(values.length>0){
        for(int i=0;i<values.length;i++){
          if(values[i]!=null){
            Map<String,dynamic> map=values[i];
            _postList .add(Post.fromJson(map));
            debugPrint('Id-------${map['id']}');
          }
        }
      }
      return _postList;

    } else {
      // If that call was not successful, throw an error.
      throw Exception('Failed to load post');
    }
  }
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  @override
  void initState() {

    fetchPost();

  }
}

Bean class

class Post {

  final int id;
  String title;
  String link;


  Post({this.id, this.title, this.link});

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
        id: json['id'],
        title: json['title'].toString(),
        link: json['link'].toString()
    );
  }
}

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

I'm getting 14 errors and this not working to me, the name Post isn't a type and it cannot be used as a type argument. This is one of the errors.
Adding PostHome to runApp in main function and it is working well now.
How can i print them on the screen not only in the console?
You have to user listview inside your view.
How to use that?
1

You need to change your class. you need to create your class structure as per the JSON response.

class Post {
  int id;
  String title;
  String link;

  Post({this.id, this.title, this.link});

  factory Post.fromJson(Map<String, dynamic> json) {
     return Post(
         id: json['id'],
         title: title = json['title'] != null ? new Title.fromJson(json['title']) : null;
         link: json['link'].toString()
        );
    }
 }


class Title {
    String rendered;

    Title({this.rendered});

     Title.fromJson(Map<String, dynamic> json) {
          rendered = json['rendered'];
      }

       Map<String, dynamic> toJson() {
          final Map<String, dynamic> data = new Map<String, dynamic>();
          data['rendered'] = this.rendered;
          return data;
        }
  }

Then, in your API method. As the response, you are getting is a JSON array. So, take that in a list and cast the response into your JSON class.

Future<List<Post>> fetchPost() async {
  final response =
        await http.get('http://alkadhum-col.edu.iq/wp-json/wp/v2/posts/');

     if (response.statusCode == 200) {
       // If the call to the server was successful, parse the JSON
        var lst = response.body as List;
        return lst.map((d) => Post.fromJson(d)).toList();
      } else {
        // If that call was not successful, throw an error.
          throw Exception('Failed to load post');
      }
 }

You can always use tools like https://javiercbk.github.io/json_to_dart/ to create Dart classes from complex JSON. Which saves a lot of time.

1 Comment

The linked JSON to Dart tool worked amazingly for my complex JSON conversion. Thanks!
0

You can use the http package in Flutter to make an HTTP GET request to the API endpoint, and then parse the JSON response using the dart:convert library's jsonDecode function. Here's an example:

import 'package:http/http.dart' as http;
import 'dart:convert';

final response = await http.get(Uri.parse('https://example.com/api/data'));
final jsonData = jsonDecode(response.body);

Comments

-1

Try below code:

factory Post.fromMap(Map<String, dynamic> json) {
  return Post(
    id: json['id'],
    title: json['title'].cast<String>(),
    link: json['link'].cast<String>()
  );
}

Comments

-1
**Create Api Class**

    class ApiUtils {
      static String baseUrl = "http://example/";
    }

**Create Model**

    class EventModel {
      String title;
    
      EventModel({this.title});
    
      EventModel.fromJson(Map<String, dynamic> json) {
        title = json['Title'] ?? "";
      
      }
    }

**Create Service**

    import 'package:http/http.dart' as http;
    import 'package:NoticeModel.dart';
    import 'dart:convert';
    
    class NoticeService {
      bool error = false;
      bool loading = true;
      var notice;
      bool noticeDetailserror = false;
      bool noticeetailsloading = true;
    
      Future<void> getNotice(dynamic input) async {
        try {
          noticeDetailserror = false;
    
          http.Response response = await http.post(ApiUtils.noticeApi,
              body: input, headers: {'Content-type': 'application/json'});
    
          Map data = jsonDecode(response.body);
          if (data["Status"] == true) {
            notice = data["Data"];
            notice = notice.map((_data) {
              return new NoticeModel.fromJson(_data);
            }).toList();
            print(notice);
            noticeetailsloading = false;
          } else {
            throw data;
          }
        } catch (e) {
          print(e);
          noticeetailsloading = false;
          noticeDetailserror = true;
        }
      }
    }

**Main Page**

 

    var body =
          json.encode({"IsActive": true, "IsDelete": false, "CompanyId": 18});
      List<dynamic> data;
      var count = 0;
      bool loading = true;
      bool error = false;
    
      void getNoticeDetails() async {
        setState(() {
          error = false;
          loading = true;
        });
    
        // SharedPreferences prefs = await SharedPreferences.getInstance();
    
        NoticeService instance = NoticeService();
        await instance.getNotice(body);
        data = instance.notice;
        if (instance.noticeDetailserror == false) {
          setState(() {
            count = data.length;
            loading = false;
          });
        } else {
          setState(() {
            loading = false;
            error = true;
          });
    
          Toast.show("Error Getting Data", context,
              duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
        }
      }
    
      @override
      void initState() {
        super.initState();
        getNoticeDetails();
      }
    
    body: loading == true
              ? LinearProgressIndicator()
              : error == true
                  ? RetryWidget(
                      onRetry: getNoticeDetails,
                    )
                  : SafeArea(
    SizedBox(
                                      width: 270,
                                          child: Text(
                                            data[index].title ?? "",
                                            maxLines: 1,
                                            overflow: TextOverflow.ellipsis,
                                            style: TextStyle(
                                              fontSize: 18,
                                              color: Colors.grey,
                                              fontWeight: FontWeight.bold,
                                            ),
                                          ),
                                        ),
    )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.