error: type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>' when I run it

1,170

A few notes:

  1. As per your error error:

    type 'List' is not a subtype of type 'Map<String, dynamic>'

    That´s cause do to the response, you are actually receiving a list.

[ /// <--- square bracket means list as you probably know.
  {
  "restaurants": [
  1. On menu class you are treating foods and drinks as property values and not lists

original Input

class Menus {
  late Foods foods;
  late Drinks drinks;

  Menus({
    required this.foods,
    required this.drinks,
  });

  Menus.fromJson(Map<String, dynamic> json) {
    foods = Foods.fromJson(json['foods']);
    drinks = Drinks.fromJson(json['drinks']);
  }
}

new Input

class Menus {
  late List<Foods> foods = <Foods>[];
  late List<Drinks> drinks = <Drinks>[];

  Menus({
    required this.foods,
    required this.drinks,
  });

  Menus.fromJson(Map<String, dynamic> json) {
    for (final _foods in json["foods"]) {
      foods.add(Foods.fromJson(_foods));
    }
    for (final _drinks in json["drinks"]) {
      drinks.add(Drinks.fromJson(_drinks));
    }
  }
}
  1. If food and drinks is just a list of strings many prefer to treat them as a List<Map<String, String>, and avoid creating class when the map is more than enough to perform most common queries, such as add, update the value search by key. This will reduce class implementation while on the opposite side you can create a class that will manage most common operations of list maps... meaning any another map will use those methods.

Example

void updateValueKeyFromList(list, key, newValue){
   list.update(key, existingValue, newValue);
}
  1. When you have lists always try to initiate them empty
late List<Drinks> drinks = <Drinks>[]; ///empty list

I actually do not know the correct response from your api, but this might help you get an idea

import 'dart:convert';

void main() {
  final restaurants = RestaurantDetail.fromJson(apiResponse).restaurants;
  for (final _restaurant in restaurants){
     print(_restaurant.id);
  }
 
}

class RestaurantDetail {
  late List<Restaurant> restaurants = <Restaurant>[];

  RestaurantDetail({required this.restaurants});

  RestaurantDetail.fromJson(Map<String, dynamic> json) {
    for (final _restaurant in json["restaurants"]) {
      restaurants.add(Restaurant.fromJson(_restaurant));
    }
  }
}

class Restaurant {
  late String id;
  late String name;
  late String description;
  late String pictureId;
  late String city;
  late double rating;
  late Menus menus;

  Restaurant({
    required this.id,
    required this.name,
    required this.description,
    required this.pictureId,
    required this.city,
    required this.rating,
    required this.menus,
  });

  Restaurant.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    description = json['description'];
    pictureId = json['pictureId'];
    city = json['city'];
    rating = json['rating'];
    menus = Menus.fromJson(json['menus']);
  }
}

class Menus {
  late List<Foods> foods = <Foods>[];
  late List<Drinks> drinks = <Drinks>[];

  Menus({
    required this.foods,
    required this.drinks,
  });

  Menus.fromJson(Map<String, dynamic> json) {
    for (final _foods in json["foods"]) {
      foods.add(Foods.fromJson(_foods));
    }
    for (final _drinks in json["drinks"]) {
      drinks.add(Drinks.fromJson(_drinks));
    }
  }
}

class Foods {
  late String name;

  Foods({required this.name});

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

class Drinks {
  late String name;

  Drinks({required this.name});

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

List<RestaurantDetail> parseRestaurant(String? json) {
  if (json == null) {
    return [];
  }

  final List parsed = jsonDecode(json);
  return parsed.map((json) => RestaurantDetail.fromJson(json)).toList();
}

Map<String, dynamic> apiResponse = {
  "restaurants": [
    {
      "id": "rqdv5juczeskfw1e867",
      "name": "Melting Pot",
      "description":
          "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.",
      "pictureId": "https://restaurant-api.dicoding.dev/images/medium/14",
      "city": "Medan",
      "rating": 4.2,
      "menus": {
        "foods": [
          {"name": "Paket rosemary"},
          {"name": "Toastie salmon"},
          {"name": "Bebek crepes"},
          {"name": "Salad lengkeng"}
        ],
        "drinks": [
          {"name": "Es krim"},
          {"name": "Sirup"},
          {"name": "Jus apel"},
          {"name": "Jus jeruk"},
          {"name": "Coklat panas"},
          {"name": "Air"},
          {"name": "Es kopi"},
          {"name": "Jus alpukat"},
          {"name": "Jus mangga"},
          {"name": "Teh manis"},
          {"name": "Kopi espresso"},
          {"name": "Minuman soda"},
          {"name": "Jus tomat"}
        ]
      }
    }
  ]
};

Share:
1,170
muhammad alam nur haris
Author by

muhammad alam nur haris

Updated on January 01, 2023

Comments

  • muhammad alam nur haris
    muhammad alam nur haris over 1 year

    I want to display my JSON data on my homepage but I have a problem. when I run an error message appears 'The following _TypeError was thrown building FutureBuilder(dirty, state: _FutureBuilderState#d0e99):' and (error: type 'List' is not a subtype of type 'Map<String, dynamic>' when I run it). I've been trying to find but I can't solve the problem.

    Below is my sample JSON snippet (note: this is local JSON):

    {
      "restaurants": [{
          "id": "rqdv5juczeskfw1e867",
          "name": "Melting Pot",
          "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.",
          "pictureId": "https://restaurant-api.dicoding.dev/images/medium/14",
          "city": "Medan",
          "rating": 4.2,
          "menus": {
            "foods": [{
                "name": "Paket rosemary"
              },
              {
                "name": "Toastie salmon"
              },
              {
                "name": "Bebek crepes"
              },
              {
                "name": "Salad lengkeng"
              }
            ],
            "drinks": [{
                "name": "Es krim"
              },
              {
                "name": "Sirup"
              },
              {
                "name": "Jus apel"
              },
              {
                "name": "Jus jeruk"
              },
              {
                "name": "Coklat panas"
              },
              {
                "name": "Air"
              },
              {
                "name": "Es kopi"
              },
              {
                "name": "Jus alpukat"
              },
              {
                "name": "Jus mangga"
              },
              {
                "name": "Teh manis"
              },
              {
                "name": "Kopi espresso"
              },
              {
                "name": "Minuman soda"
              },
              {
                "name": "Jus tomat"
              }
            ]
          }
        },
    ]
    }
    

    Below is my restaurant file:

    import 'dart:convert';
    
    class RestaurantDetail {
      late Restaurant restaurants;
    
      RestaurantDetail({required this.restaurants});
    
      RestaurantDetail.fromJson(Map<String, dynamic> json) {
        restaurants = Restaurant.fromJson(json['restaurants']);
      }
    }
    
    class Restaurant {
      late String id;
      late String name;
      late String description;
      late String pictureId;
      late String city;
      late double rating;
      late Menus menus;
    
      Restaurant({
        required this.id,
        required this.name,
        required this.description,
        required this.pictureId,
        required this.city,
        required this.rating,
        required this.menus,
      });
    
      Restaurant.fromJson(Map<String, dynamic> json) {
        id = json['id'];
        name = json['name'];
        description = json['description'];
        pictureId = json['pictureId'];
        city = json['city'];
        rating = json['rating'];
        menus = Menus.fromJson(json['menus']);
      }
    }
    
    class Menus {
      late Foods foods;
      late Drinks drinks;
    
      Menus({
        required this.foods,
        required this.drinks,
      });
    
      Menus.fromJson(Map<String, dynamic> json) {
        foods = Foods.fromJson(json['foods']);
        drinks = Drinks.fromJson(json['drinks']);
      }
    }
    
    class Foods {
      late String name;
    
      Foods({required this.name});
    
      Foods.fromJson(Map<String, dynamic> json) {
        name = json['name'];
      }
    }
    
    class Drinks {
      late String name;
    
      Drinks({required this.name});
    
      Drinks.fromJson(Map<String, dynamic> json) {
        name = json['name'];
      }
    }
    
    List<RestaurantDetail> parseRestaurant(String? json) {
      if (json == null) {
        return [];
      }
    
      final List parsed = jsonDecode(json);
      return parsed.map((json) => RestaurantDetail.fromJson(json)).toList();
    }
    

    Below is the homepage code:

    import 'package:flutter/material.dart';
    import 'package:restaurant/data/restaurant.dart';
    import 'package:restaurant/style/theme.dart';
    
    class HomePage extends StatelessWidget {
      static const routeName = '/article_list';
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: kBackgroundColor,
          body: FutureBuilder<String>(
            future: DefaultAssetBundle.of(context)
                .loadString('assets/local_restaurant.json'),
            builder: (context, snapshot) {
              final List<RestaurantDetail> restaurants =
                  parseRestaurant(snapshot.data);
              return ListView.builder(
                itemCount: restaurants.length,
                itemBuilder: (context, index) {
                  return _buildRestaurantItem(context, restaurants[index]);
                },
              );
            },
          ),
        );
      }
    
      Widget _buildRestaurantItem(
          BuildContext context, RestaurantDetail restaurantDetail) {
        return ListTile(
          contentPadding:
              const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
          leading: Image.network(
            restaurantDetail.restaurants.pictureId,
            width: 100,
          ),
          title: Text(restaurantDetail.restaurants.name),
          subtitle: Text(restaurantDetail.restaurants.city),
          onTap: () {},
        );
      }
    }
    
    • CoderUni
      CoderUni over 2 years
      The types are different. You have to change the type into a Map<String,dynamic> using the as keyword: stackoverflow.com/questions/55789048/…
    • muhammad alam nur haris
      muhammad alam nur haris over 2 years
      can you give me an example of using it because the JSON I'm using is quite forked
    • Martin Zeitler
      Martin Zeitler over 2 years
      Why you don't just map List > Restaurant > Menu > Product instead of generic Map?