0
votes

Although this question has been asked a few times but I didn't get help from the ones I saw. So here goes,

I have a mock json file inside my assets folder: recipe.json

Here's the recipe.dart which acts as my Model Class:

class RecipeModel {
  final String id;
  final String name;
  final String videoLink;
  final String author;
  final String category;
  final String time;
  RecipeModel({
    required this.id,
    required this.name,
    required this.videoLink,
    required this.author,
    required this.category,
    required this.time,
  });

  factory RecipeModel.fromJson(Map<String, dynamic> json) {
    return RecipeModel(
      id: json['id'],
      name: json['name'],
      videoLink: json['videoLink'],
      author: json['author'],
      category: json['category'],
      time: json['time'],
    );
  }
}

And here's HomeScreen.dart:

  Future<List<RecipeModel>> getRecipeData() async {
    // var response = await http.get(
    //   Uri.https("jsonplaceholder.typicode.com", 'users'),
    // );
    String response = await DefaultAssetBundle.of(context)
        .loadString('assets/json/recipe.json');
    var result = json.decode(response);
    List<RecipeModel> recipes = [];
    for (var u in result) {
      RecipeModel recipe = RecipeModel(
        id: u['id'] ?? "",
        name: u['name'] ?? "",
        videoLink: u['videoLink'] ?? "",
        author: u['author'] ?? "",
        category: u['category'] ?? "",
        time: u['time'] ?? "",
      );
      recipes.add(recipe);
    }

    print(recipes.length);

    return recipes;
  }

  @override
  void initState() {
    super.initState();
    getRecipeData();
  }

As you can see I want to fetch the data as soon as the page loads and keep said data in a list which I then can use in a gridview. But everytime the screen loads I get this error:

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>

I followed saw some tutorials which completely ignored anything related to Models which I don't want. What am I missing here? What do I need to do to get the result in a list which I can then use inside a gridview?

my json data is somewhat like this:

{
  "data":
  [
    {.....},
    {.....}
  ]
}
2
Result is map and not a list, as the result is the data, and the data is a list, so first extract the data from the map, and then iterate over the list. - Chance

2 Answers

1
votes

Result is a map and not a list, as the result is the data, and the data is a list, so first extract the data from the map, and then iterate over the list.

Future<List<RecipeModel>> getRecipeData() async {
  // var response = await http.get(
  //   Uri.https("jsonplaceholder.typicode.com", 'users'),
  // );
  String response = await DefaultAssetBundle.of(context)
      .loadString('assets/json/recipe.json');
  var result = json.decode(response);

  var resultList = result["data"];

  List<RecipeModel> recipes = [];
  for (var u in resultList) {
    RecipeModel recipe = RecipeModel(
      id: u['id'] ?? "",
      name: u['name'] ?? "",
      videoLink: u['videoLink'] ?? "",
      author: u['author'] ?? "",
      category: u['category'] ?? "",
      time: u['time'] ?? "",
    );
    recipes.add(recipe);
  }

  print(recipes.length);

  return recipes;
}

If you have any doubts about the type of data you are receiving, just check the runtimeType.

print(result.runtimeType)

1
votes

Change this:

for (var u in result)

To this:

for (var u in result["data"])