0

I am trying to fetch data from an api (in this case jsonplaceholder). The response of the data is a list of maps. I am trying to retrieve the id, title, and body as example.

I have this code which works:

Future<List<Post>> fetchPosts() async {
    final res = await http.get(
      Uri.parse('https://jsonplaceholder.typicode.com/posts'),
    );

    final List<dynamic> parsedPosts = json.decode(res.body);
    return parsedPosts.map((parsedPost) {
      return Post.fromMap(parsedPost);
    }).toList();
  }

However, I would like to make use of the dart data class generator extension. The snippet they provide for json serialization for my model is this:

class Post {
  final String title;
  final String body;
  final int id;

  Post({
    required this.title,
    required this.body,
    required this.id,
  });

  Map<String, dynamic> toMap() {
    return {
      'title': title,
      'body': body,
      'id': id,
    };
  }

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

  String toJson() => json.encode(toMap());

  factory Post.fromJson(String source) => Post.fromMap(json.decode(source));
}

What's interesting here is they do the decoding in the class itself. This is where I am getting stuck. I am not sure how to fetch the data in the same manner as I did without the snippet provided by this extension.

Maybe I am just completely misunderstanding but I figured the idea was to loop over the results on the get request and then inside that, call the fromjson method. However, the res.body is considered a string and I believe the json.decode is actually what allows us to loop over it.

I've tried just assigning a variable to the post.fromjson with the res.body passed in and that doesn't work either.

Quicktype seems to have this syntax as well but their explanation isn't very helpful on how to actually utilize it.

// To parse this JSON data, do
//
//     final post = postFromMap(jsonString);

I have no clue what postFromMap is referring to. I'd appreciate any help :)

Edit: This is pretty much what I'm trying to achieve: https://stackoverflow.com/a/62244941/9453618

However, I get error Unhandled Exception: type 'List' is not a subtype of type 'Map<String, dynamic>'

Dan
  • 37
  • 1
  • 4

1 Answers1

0

Try below code, I think your problem has been solved.

Or If you get data from API refer my answer here or here or here hope it's helpful to you

Declare API call function :

  Future<List<dynamic>> getJobsData() async {
    String url = 'https://jsonplaceholder.typicode.com/posts';
    var response = await http.get(Uri.parse(url), headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    });
    return json.decode(response.body);
  }

Your Widget :

 Column(
    children: [
      Expanded(
        child: Center(
          child: FutureBuilder<List<dynamic>>(
            future: getJobsData(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: ListView.builder(
                    itemCount: snapshot.data.length,
                    itemBuilder: (context, index) {
                      var title = snapshot.data[index]['title'];
                      var body = snapshot.data[index]['body'];
                      var id = snapshot.data[index]['id'];
                      var userId = snapshot.data[index]['userId'];
                      return Card(
                        shape: RoundedRectangleBorder(
                          side: BorderSide(color: Colors.green.shade300),
                          borderRadius: BorderRadius.circular(15.0),
                        ),
                        child: Column(
                          children: [
                            ListTile(
                              leading: Text(id.toString()),
                              title: Text(title),
                              subtitle: Text(
                                body,
                              ),
                              trailing: Text(userId.toString()),
                            ),
                          ],
                        ),
                      );
                    },
                  ),
                );
              }
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    ],
  ),

Your Screen Result : enter image description here

Ravindra S. Patil
  • 11,757
  • 3
  • 13
  • 40
  • This isn't my question. I am having issues with utilizing the fromJson method that the extension provides `factory Post.fromJson(String source) => Post.fromMap(json.decode(source));` – Dan Sep 13 '21 at 07:45
  • try [this](https://stackoverflow.com/a/68533647/13997210) my answer – Ravindra S. Patil Sep 13 '21 at 07:52