jsonflutterandroid-studiodartlistview

Dart Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>


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,
       ),
    );
  }
}

Solution

  • As @hacker1024 said, you are missing key there.

    If you are getting data from an API, try using FutureBuilder.

    I'm loading from assets folder here (don't 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("implement more");
              }),
        );
      }