Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

type _InternalLinkedHashMap<String, dynamic> is not subtype of type List<dynamic>

Tags:

json

flutter

I am trying to implement a simple news feed app using network call wherein the screen will show the latest stories in a Listview.

With the current code, I am getting a response back from the API (as I see the entire response body in the log) but can't seem to display the data in the UI. I am getting this error :

type _InternalLinkedHashMap<String, dynamic> is not subtype of type List

This is the JSON structure

{
    "response": {
        "status": "ok",
        "userTier": "developer",
        "total": 25095,
        "startIndex": 1,
        "pageSize": 10,
        "currentPage": 1,
        "pages": 2510,
        "orderBy": "relevance",
        "results": [
          {
            "id": "australia-news/2018/aug/13/turnbulls-energy-policy-hangs-in-the-balance-as-euthanasia-debate-given-precedence",
            "type": "article",
            "sectionId": "australia-news",
            "sectionName": "Australia news",
            "webPublicationDate": "2018-08-12T18:00:08Z",
            "webTitle": "Energy policy hangs in balance, as Senate debates euthanasia",
            "webUrl": "https://www.theguardian.com/australia-news/2018/aug/13/turnbulls-energy-policy-hangs-in-the-balance-as-euthanasia-debate-given-precedence",
            "apiUrl": "https://content.guardianapis.com/australia-news/2018/aug/13/turnbulls-energy-policy-hangs-in-the-balance-as-euthanasia-debate-given-precedence",
            "isHosted": false,
            "pillarId": "pillar/news",
            "pillarName": "News"
        }, {
            "id": "media/2018/jun/13/the-rev-colin-morris-obituary-letter",
            "type": "article",
            "sectionId": "media",

For my understanding, I just want to first display webTitle in the list, and later add other fields (after I understand the network concept clearly), but getting the error mentioned above. This is my complete code :

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {

    return new MaterialApp(
      title: 'Network Example',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Scaffold(
        appBar: AppBar(
          title: new Text('Network Example'),
        ),
        body: new Container(
          child: new FutureBuilder<List<News>> (
            future: fetchNews(),
            builder: (context, snapshot) {

              if (snapshot.hasData) {
                return new ListView.builder(
                    itemCount: snapshot.data.length,
                    itemBuilder: (context, index) {
                      return new Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            new Text(snapshot.data[index].newsTitle,
                                style: new TextStyle(
                                    fontWeight: FontWeight.bold)
                            ),
                            new Divider()
                          ],
                      );
                    }
                );
              } else if (snapshot.hasError) {
                return new Text("${snapshot.error}");
              }
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }


Future<List<News>> fetchNews() async {
  final response = await http.get('https://content.guardianapis.com/search?q=debates&api-key=');
  print(response.body);
  List responseJson = json.decode(response.body.toString());
  List<News> newsTitle = createNewsList(responseJson);
  return newsTitle;

}

List<News> createNewsList(List data) {
    List<News> list = new List();
    for (int i = 0; i< data.length; i++) {
      String title = data[i]['webTitle'];

      News news = new News(
      newsTitle: title);
      list.add(news);
    }
    return list;

  }
}

class News {
 final String newsTitle;

  News({this.newsTitle});

  factory News.fromJson(Map<String, dynamic> json) {

    return new News(
      newsTitle: json['webTitle'],
    );
  }
}

I looked at similar questions before and also went through json structures articles but can't seem to figure out how to resolve this issue.

like image 724
Darshan Avatar asked Aug 20 '18 19:08

Darshan


1 Answers

The problem is, your JSON is not an array. It is an object. But you tried to use it as an array.

You may want to change your createNewsList call to the following:

List responseJson = json.decode(response.body.toString());
List<News> newsTitle = createNewsList(responseJson["response"]["results"]);
like image 78
Rémi Rousselet Avatar answered Nov 08 '22 14:11

Rémi Rousselet