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.