Reputation: 95
How can fix the issue Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable' i am trying to parse data from a json Api in Android Studio flutter (dart) but i keep getting the error above, the app open fine but displays nothing and i get the error in my logcat. Any suggestion will be greatly appreciated.
//Sample Json//
{
"data": [
{
"title": "Ronix",
"year": "Year 5",
"category": "Admin"
},
{
"title": "Ultra",
"year": "Year 11",
"category": "Tutor"
},
{
"title": "Sonet",
"year": "Year 3",
"category": "Admin"
}
]
}
Here is my class .dart file
class DataClass{
String title ="";
String year="";
String category="";
DataClass(this.title, this.year, this.category);
DataClass.fromJson(Map<String, dynamic> json){
title = json["title"];
year = json["year"];
category = json["category"];
}
}
And my main .dart file
class CreateState1 extends State<JsonData1>{
List<DataClass> _dataClass = [];
Future<List<DataClass>> getMovieData() async {
var response = await http.get(Uri.parse("myjsonApiUrl"));
var datas = [];
if(response.statusCode == 200){
var datasJson = json.decode(response.body);
for(var dataJson in datasJson){
datas.add(DataClass.fromJson(dataJson));
}
}
return _dataClass;
}
@override
Widget build(BuildContext context) {
getMovieData().then((value) {
setState(() {
_dataClass.addAll(value);
});
});
return Scaffold(
backgroundColor: Colors.cyan,
body: ListView.builder(
itemBuilder: (context, index) {
return Card(
child: Column(
children: <Widget>[
Text(_dataClass[index].title),
Text( _dataClass[index].year),
Text(_dataClass[index].category),
],
),
);
},
itemCount: _dataClass.length,
),
);
}
}
Upvotes: 0
Views: 285
Reputation: 63569
as @hacker1024 said , you are missing key there.
if you are getting data from Api, try using FutureBuilder.
I’m loading from assets folder here (dont forget to add on pubspec.yaml
)
Future<List<DataClass>> getMovieData() async {
final myJson = await rootBundle.loadString("assets/j.json");
// var response = await http.get(Uri.parse(myJson));
// if (response.statusCode == 200) {
final datasJson = json.decode(myJson)["data"] as List;
return datasJson.map((js) => DataClass.fromJson(js)).toList();
// } else
// print("http error");
// return [];
}
And for implementation
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.cyan,
body: FutureBuilder<List<DataClass>>(
future: getMovieData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return CircularProgressIndicator();
if (snapshot.hasError)
return Text(snapshot.error.toString());
else if (snapshot.hasData &&
snapshot.connectionState == ConnectionState.done)
return ListView.builder(
itemBuilder: (context, index) {
return Card(
child: Column(
children: <Widget>[
Text(snapshot.data![index].title),
Text(snapshot.data![index].year),
Text(snapshot.data![index].category),
],
),
);
},
itemCount: snapshot.data!.length,
);
else
return Text("impliment more");
}),
);
}
Upvotes: 1
Reputation: 2218
instead of
for(var dataJson in datasJson){
datas.add(DataClass.fromJson(dataJson));
}
use this
for (var dataJson in datasJson['data']) {
datas.add(DataClass.fromJson(dataJson));
}
Upvotes: 0
Reputation: 3648
In your example, datasJson
is a map with a "data
" key. You want to iterate over the list assigned to the "data
" key:
var datasJson = json.decode(response.body)['data'];
Upvotes: 0