Reputation: 516
I'm getting data from an API and i'm trying to push that data into two variables. I can access part of the data being returned but not all of it, I can print all of the data but when I try to access a specific part of it, it doesn't work.
E.G: res = response from API
print(res.data); // This works
print(res.feeds); // This doesn't work
print(res.feeds.id); // This doesn't work
The error I am getting is:
'Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<FeedItem>'
This is how i'm converting and reading the data:
class FeedData {
String data;
List<FeedItem> feeds;
FeedData({this.data, this.feeds});
factory FeedData.fromJson(Map<String, dynamic> json) {
return FeedData(
data: json['data'],
feeds: json['feeds'],
);
}
}
I can read and access the 'data' but not the 'feeds' which is my problem, I need to be able to access the data in the 'feeds' The 'FeedItem' class is built in the same way as the 'FeedData' class so I'm sure that it is built properly
This is how I'm calling the data:
getUserFeed() async {
FeedData res = FeedData.fromJson(
await requests.get(url: 'feeds/u?u=jxchumber&PageNumber=1'));
print(res.data);
// res.data works
print(res.feeds);
// res.feeds doesn't work
}
This is the data being returned from the API:
{
"data": "default",
"feeds": [
{
"id": 2,
"photoUrl": "https://cartalkio-image-storage-dev.s3.eu-west-2.amazonaws.com/o85DvOaTXXE.jpg",
"description": "Magna duis consectetur sit ut commodo non eiusmod.",
"dateAdded": "0001-01-01T00:00:00",
"isMain": false,
"publicId": null,
"isImage": true,
"mainImage": "https://randomuser.me/api/portraits/men/76.jpg",
"userId": 9,
"likers": null,
"username": "Larsen",
"thumbnail": null,
"likes": 0
},
{
"id": 4,
"photoUrl": "https://cartalkio-image-storage-dev.s3.eu-west-2.amazonaws.com/lXR833PRh3g.jpg",
"description": "Magna duis consectetur sit ut commodo non eiusmod.",
"dateAdded": "0001-01-01T00:00:00",
"isMain": false,
"publicId": null,
"isImage": true,
"mainImage": "https://randomuser.me/api/portraits/men/4.jpg",
"userId": 8,
"likers": null,
"username": "Lloyd",
"thumbnail": null,
"likes": 0
},
}
Upvotes: 2
Views: 3506
Reputation: 6029
The error is because you are not passing json['feeds'] as a List. Your FeedData class will have to be changed to the following, this is assuming that your FeedItem class also has a fromJson method :
class FeedData {
String data;
List<FeedItem> feeds;
FeedData({this.data, this.feeds});
factory FeedData.fromJson(Map<String, dynamic> json) {
return FeedData(
data: json['data'],
feeds: List.from(json['feeds']).map((item)=>FeedItem.fromJson(item)).toList(),
);
}
}
Please see the working code based on your data. You can also load the following code on DartPad https://dartpad.dev/24694a911ddd0619277f5780573086f1
void main() {
Map<String, dynamic> json = {
"data": "default",
"feeds": [
{
"id": 2,
"photoUrl": "https://cartalkio-image-storage-dev.s3.eu-west-2.amazonaws.com/o85DvOaTXXE.jpg",
"description": "Magna duis consectetur sit ut commodo non eiusmod.",
"dateAdded": "0001-01-01T00:00:00",
"isMain": false,
"publicId": null,
"isImage": true,
"mainImage": "https://randomuser.me/api/portraits/men/76.jpg",
"userId": 9,
"likers": null,
"username": "Larsen",
"thumbnail": null,
"likes": 0
},
{
"id": 4,
"photoUrl": "https://cartalkio-image-storage-dev.s3.eu-west-2.amazonaws.com/lXR833PRh3g.jpg",
"description": "Magna duis consectetur sit ut commodo non eiusmod.",
"dateAdded": "0001-01-01T00:00:00",
"isMain": false,
"publicId": null,
"isImage": true,
"mainImage": "https://randomuser.me/api/portraits/men/4.jpg",
"userId": 8,
"likers": null,
"username": "Lloyd",
"thumbnail": null,
"likes": 0
},
]
};
FeedData feedData = FeedData.fromJson(json);
print(feedData.feeds.length);
}
class FeedData {
String data;
List<FeedItem> feeds;
FeedData({this.data, this.feeds});
factory FeedData.fromJson(Map<String, dynamic> json) {
return FeedData(
data: json['data'],
feeds: List.from(json['feeds']).map((item)=>FeedItem.fromJson(item)).toList(),
);
}
}
class FeedItem {
int id;
String photoUrl;
String description;
String dateAdded;
bool isMain;
Null publicId;
bool isImage;
String mainImage;
int userId;
Null likers;
String username;
Null thumbnail;
int likes;
FeedItem(
{this.id,
this.photoUrl,
this.description,
this.dateAdded,
this.isMain,
this.publicId,
this.isImage,
this.mainImage,
this.userId,
this.likers,
this.username,
this.thumbnail,
this.likes});
FeedItem.fromJson(Map<String, dynamic> json) {
id = json['id'];
photoUrl = json['photoUrl'];
description = json['description'];
dateAdded = json['dateAdded'];
isMain = json['isMain'];
publicId = json['publicId'];
isImage = json['isImage'];
mainImage = json['mainImage'];
userId = json['userId'];
likers = json['likers'];
username = json['username'];
thumbnail = json['thumbnail'];
likes = json['likes'];
}
}
Upvotes: 3
Reputation: 250
When you are doing feeds: json['feeds']
, You are basically trying to assign a Map<String,dynamic>
to a class FeedItem
, Moreover you want to assign a complete list as List<Map<String,dynamic>>
to List<FeedItem
, The problem is that flutter just can't parse the data automatically and assign like this , You need to go deep level by level and assign Map<String,dynamic>
to FeedItem
and then finally convert it to a List
I will share a piece of code based on my knowledge, how I tackle this type of problem and I believe that will give you better insight about your problem ( if not solve it )
Future<void> getData() async {
http.Response response =
await http.get('Example address');
if (response.statusCode == HttpStatus.ok) {
//if the status code is 200 or 'OK' parse the data and convert Outer layer as List
//after that , Map each element as a FeedItem and finally convert the result to List
feeds = (json.decode(response.body) as List)
.map<FeedItem>(
(_feed) => FeedItem.fromJSON(_feed))
.toList();
} else {
throw response;
}
}
Upvotes: 3
Reputation: 11881
You are not converting feedItems to objects
factory FeedData.fromJson(Map<String, dynamic> json) {
return FeedData(
data: json['data'],
feeds: json['feeds'], # <- here is the problem
);
Should be something like this:
feeds: (json['feeds'] as List)
?.map((e) =>
e == null ? null : FeedItem.fromJson(e as Map<String, dynamic>))
?.toList(),
Upvotes: 1
Reputation: 4575
Please change this code
print(res.feeds); --> print(res.feeds[0]);
print(res.feeds.id); --> print(res.feeds[0].id);
Upvotes: 0