Home > Software engineering >  type 'Null' is not a subtype of type 'List<RestaurantModel>'
type 'Null' is not a subtype of type 'List<RestaurantModel>'

Time:07-02

I'm new to programming and currently learning JSON. I got this error when using Cubit to access the JSON:

RestaurantFailed(type 'Null' is not a subtype of type 'List<RestaurantModel>')

JSON Sample: https://restaurant-api.dicoding.dev/list

I'm trying to access the API and insert it to RestaurantModel.

this is my code: restaurant_service.dart

class RestaurantService {
  Future<List<RestaurantModel>> fetchAllData() async {
    try {
      Uri url = Uri.http('restaurant-api.dicoding.dev', '/list');
      http.Response response = await http.get(url);
      Map<String, dynamic> result = jsonDecode(response.body);
      List<RestaurantModel> restaurants = result['restaurants'].forEach((json) {
        return RestaurantModel.fromJson(json: json);
      });
      return restaurants;
    } catch (e) {
      rethrow;
    }
  }
}

restaurant_cubit.dart

class RestaurantCubit extends Cubit<RestaurantState> {
  RestaurantCubit() : super(RestaurantInitial());

  void fetchData() async {
    try {
      emit(RestaurantLoading());
      List<RestaurantModel> restaurants =
          await RestaurantService().fetchAllData();
      emit(RestaurantSuccess(restaurants));
    } catch (e) {
      emit(RestaurantFailed(e.toString()));
    }
  }
}

restaurant_model.dart

class RestaurantModel {
  final String id;
  final String name;
  final String description;
  final String pictureId;
  final String city;
  final double rating;
  String? address;
  List<String>? categories;
  List<String>? menus;
  List<CustomerReviewModel>? customerReviews;

  RestaurantModel({
    required this.id,
    required this.name,
    required this.description,
    required this.pictureId,
    required this.city,
    this.rating = 0.0,
    this.address = '',
    this.categories,
    this.menus,
    this.customerReviews,
  });

  factory RestaurantModel.fromJson({required Map<String, dynamic> json}) =>
      RestaurantModel(
        id: json['id'],
        name: json['name'],
        description: json['description'],
        pictureId: json['pictureId'],
        city: json['city'],
        rating: json['rating'].toDouble(),
        address: json['address'] ?? '',
        categories: json['categories'] ?? [],
        menus: json['menus'] ?? [],
        customerReviews: json['customerReviews'] ?? [],
      );
}

any feedback or input would be very appreciated! Cheers

CodePudding user response:

The forEach should be replaced by map(...).toList() like the following code snippet:

      List<RestaurantModel> restaurants = result['restaurants'].map((json) {
        return RestaurantModel.fromJson(json: json);
      }).toList();

This is because forEach returns void and it cannot be assigned to anything. On the other hand, map returns a Iterable<RestaurantModel> and it's just a matter of converting it to list with the toList() method.

  • Related