skip to Main Content

I’m trying to fetch data from internet and I’m wondering why it’s shows a white screen and I think the problem at the return in web services class but I can’t figure out how can I solve it.

This is the model class:

class Character {
     late int id;
     late String name;
     late String status;
     late String species;
     late String type;
     late String gender;
     late String image;
     late String url;
     late String created;

    Character.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    status = json['status'];
    species = json['species'];
    type = json['type'];
    gender = json['gender'];
    image = json['image'];
    url = json['url'];
    created = json['created'];
  }
}

repo class

Future<List<Character>> getAllCharacters() async {
    final characters = await charactersWebServices.getAllCharacters();
    return characters
        .map((character) => Character.fromJson(character))
        .toList();
  }
}

web services class

Future<List<dynamic>> getAllCharacters() async {
    try {
      Response response = await dio.get('character');
      print(response.data.toString());
      return response.data;
    } catch (e) {
      print(e.toString());
      return [];
    }
  }
}

and the JSON file:

{
"info": {
    "count": 826,
    "pages": 42,
    "next": "https://rickandmortyapi.com/api/character?page=2",
    "prev": null
},
"results": [
    {
        "id": 1,
        "name": "Rick Sanchez",
        "status": "Alive",
        "species": "Human",
        "type": "",
        "gender": "Male",
        "origin": {
            "name": "Earth (C-137)",
            "url": "https://rickandmortyapi.com/api/location/1"
        },
        "location": {
            "name": "Citadel of Ricks",
            "url": "https://rickandmortyapi.com/api/location/3"
        },
        "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg",

2

Answers


  1. It’s really simple,
    What is the response you’re getting from dio’s response.data object?
    it’s

    {
    "info": {
        "count": 826,
        "pages": 42,
        "next": "https://rickandmortyapi.com/api/character?page=2",
        "prev": null
    },
    "results": [
        {
            "id": 1,
            "name": "Rick Sanchez",
            "status": "Alive",
            "species": "Human",
            "type": "",
            "gender": "Male",
            "origin": {
                "name": "Earth (C-137)",
                "url": "https://rickandmortyapi.com/api/location/1"
            },
            "location": {
                "name": "Citadel of Ricks",
                "url": "https://rickandmortyapi.com/api/location/3"
            },
            "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg",
    ]}
    

    And what you exactly need? You need the data in results (as per my understanding)

    So first of all, the return of you method getAllCharacters() should be Map<String, dynamic> instead of List,

    Secondly,

    final characters = await charactersWebServices.getAllCharacters();
    return characters
        .map((character) => Character.fromJson(character))
        .toList();
    

    Will Change to:

    final characters = await charactersWebServices.getAllCharacters();
    return characters['results']
        !.map((character) => Character.fromJson(character))
        .toList();
    

    this way, you can access the list of characters which is in the ‘result’ field of your response, you were trying to force your response to cast to List but actually it was a Map, and since it’s a map, we can simply get the results with characters[‘results’].

    Note: characters[‘results’]!.map() may result in error if the result is null, it’s upto you to handle that result and return the correct output.

    Login or Signup to reply.
  2. In your code you say Future<List<dynamic>> but the error says that the value being returned from response.data is not a List<dynamic>> but rather a Map<String, dynamic> as it seems in your json file. So you either need to add response.data to a list, or change the Future return type.

    In your json file I can see that there is a Map of {"info": map<string, dynamic>}
    and {"results": map<string, dynamic>} and your Character.fromJson(character) is referring to values inside the "result" map so I will adjust your Future type and specify that you want the "result" part of your json in your return.

    Future<List<Map<String, dynamic>>> getAllCharacters() async {
      try {
        Response response = await dio.get('character');
        print(response.data.toString()); 
        return List<Map<String, dynamic>>.from(response.data['results']);
      } catch (e) {
        print(e.toString());
        return [];
      }
    }
    

    This should now extract the "results" array from the list of maps as a Map<String, dynamic>

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search