I just want to fetch the whole list of my model and in my response>
I cannot assign the result of the HTTP request to the list. Could anybody provide me what I'm missing in my code?
I want to fetch the whole list of 20 items as count param says but I'm getting a single response.body and it is not possible to assign it to a list which I expect. How to convert it to a list?
My error: Cannot assinge Future to Future<List>
Base response:
class ApiService {
String baseUrl = astronomyApiUrl;
Future<http.Response> fetchData(Map<String, String> urlParams) async {
http.Response response;
var combinedUrl = combineUrl(urlParams: urlParams);
final url = Uri.parse(combinedUrl);
try {
response = await http.get(url);
} on Exception catch (e) {
throw e;
}
return response;
}
String combineUrl({Map<String, String>? urlParams}) {
final buffer = StringBuffer();
urlParams!.forEach((name, value) {
buffer.write("$name=$value&");
});
return "$baseUrl/api/?${buffer.toString()}";
}
}
List response:
class AstronomyService {
Future<List<AstronomyModel>?> getAstronomy() async {
try {
final response = await ApiService().fetchData({
"thumbs": true.toString(),
"count": "20",
});
if (response.statusCode == 200) {
final result = astronomyModelFromJson(response.body);
return result; //Cannot assinge Future<AstronomyModel> to Future<List<AstronomyModel>>
} else {
return null;
}
} on SocketException catch (e) {
throw e;
} on HttpException catch (e) {
throw e;
} on FormatException catch (e) {
throw e;
}
}
}
Model:
AstronomyModel astronomyModelFromJson(String str) =>
AstronomyModel.fromJson(json.decode(str));
class AstronomyModel {
AstronomyPicModel({
this.date,
this.hdurl,
this.description,
this.mediaType,
this.thumbnailUrl,
this.title,
this.url,
});
DateTime? date;
String? hdurl;
String? description;
String? mediaType;
String? thumbnailUrl;
String? title;
String? url;
factory AstronomyModel.fromJson(Map<String, dynamic> json) =>
AstronomyModel(
date: DateTime.parse(json["date"]),
hdurl: json["hdurl"],
description: json["description"],
mediaType: json["media_type"],
thumbnailUrl: json["thumbnail_url"],
title: json["title"],
url: json["url"],
);
}
CodePudding user response:
Your AstronomyModel.fromJson
just creates a single AstronomyModel
.
So your astronomyModelFromJson(response.body)
will just create a single one too.
As you provide no indication as to what the API is, or what the response.body is, this is just a guess:
Assuming that API call does return a list (why don't you look at it, and print it out? print(response.body);
), then perhaps what you want to do is something like:
final result = response.body.map((a)=> astronomyModelFromJson(a));
CodePudding user response:
I messed up in model part. I was decoding just single response instead of list.
Solution was just to replace this:
AstronomyModel astronomyModelFromJson(String str) =>
AstronomyModel.fromJson(json.decode(str));
To this:
List<AstronomyModel> astronomyModelFromJson(String str) => List<AstronomyModel>.from(json.decode(str).map((x) => AstronomyModel.fromJson(x)));
CodePudding user response:
Actually you are having this issue because astronomyModelFromJson method will return you AstronomyModel while the Future is waiting to return List. You should try doing something like this
class AstronomyService {
Future<List<AstronomyModel>?> getAstronomy() async {
try {
final response = await ApiService().fetchData({
"thumbs": true.toString(),
"count": "20",
});
if (response.statusCode == 200) {
final items = json.decode(response.body).cast<Map<String, dynamic>>();
List<AstronomyModel> result = items.map<AstronomyModel>((json) {
return AstronomyModel.fromJson(json);
}).toList();
return result;
} else {
return null;
}
} on SocketException catch (e) {
throw e;
} on HttpException catch (e) {
throw e;
} on FormatException catch (e) {
throw e;
}
}
}
CodePudding user response:
try {
final response = await ApiService().fetchData({
ListView.builder(
itemCount:20
});
.try list view builder instead may be it works and try to initialize
List<AstronomyModel>
.on your screen may be it works. thanks