Ava Juan
Ava Juan

Reputation: 113

Flutter _TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>')

I'm getting the below JSON as response from my URL. Not sure what's wrong I'm getting the below mentioned error.

Here is my json. I have attached the code from main.dart file too.

{
   "data": [
      {
         "id": 1,
         "attributes": {
            "Title": "Name One",
            "Story": "Body Text of One",
            "createdAt": "2022-01-03T17:04:32.919Z",
            "updatedAt": "2022-01-03T18:22:02.016Z",
            "publishedAt": "2022-01-03T18:22:02.014Z"
         }
      },
      {
         "id": 2,
         "attributes": {
            "Title": "Name Two",
            "Story": "Body Text of two",
            "createdAt": "2022-01-03T17:04:32.919Z",
            "updatedAt": "2022-01-03T18:22:02.016Z",
            "publishedAt": "2022-01-03T18:22:02.014Z"
         }
      },
      {
         "id": 3,
         "attributes": {
            "Title": "Name Three",
            "Story": "Body Text of three",
            "createdAt": "2022-01-03T17:04:32.919Z",
            "updatedAt": "2022-01-03T18:22:02.016Z",
            "publishedAt": "2022-01-03T18:22:02.014Z"
         }
      }
   ],
   "meta": {
      "pagination": {
         "page": 1,
         "pageSize": 25,
         "pageCount": 1,
         "total": 3
      }
   }
}

This is my main.dart file. I'm trying to get the data and create a ListView.

// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';

void main() => runApp(App());

class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const Homepage(),
    );
  }
}

class Homepage extends StatefulWidget {
  const Homepage({Key? key}) : super(key: key);

  @override
  _HomepageState createState() => _HomepageState();
}

class _HomepageState extends State<Homepage> {
  Future<List<Story>> _getStories() async {
    var response = await http
        .get(Uri.parse('https://my.api.com/stories'));
    if (response.statusCode == 200) {
      List StoriesList = jsonDecode(response.body);
      List<Story> stories = [];
      for (var storyMap in StoriesList) {
        stories.add(Story.fromJson(storyMap));
      }
      return stories;
    } else {
      throw Exception('Failed to load stories');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('News Stories'),
      ),
      body: Container(
        child: FutureBuilder(
          future: _getStories(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.data == null) {
              return Container(
                child: Center(
                  child: CircularProgressIndicator(),
                ),
              );
            } else {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    title: Text(snapshot.data[index].title),
                  );
                },
              );
            }
          },
        ),
      ),
    );
  }
}

class Story {
  final String title;
  final String body;

  Story({required this.title, required this.body});

  factory Story.fromJson(Map<String, dynamic> json) {
    return Story(
      title: json['Title'],
      body: json['Story'],
    );
  }
}

I'm not sure what is wrong here. I'm getting this error.

_TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>')

Upvotes: 0

Views: 56

Answers (1)

Sam Chan
Sam Chan

Reputation: 1772

There are some change in data decode

 if (response.statusCode == 200) {
      Map responseData = jsonDecode(response.body)/// the json should be Map not List, it is reason causing error
      List StoriesList = responseData["data"];
      List<Story> stories = [];
      for (var storyMap in StoriesList) {
        stories.add(Story.fromJson(storyMap["attributes"]));/// Another thing need to be changed according to the json you provided 
      }
      return stories;
    } else {
      throw Exception('Failed to load stories');
    }

Upvotes: 1

Related Questions