Home > Net >  Api type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>&#
Api type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>&#

Time:08-28

I'm following flutter's documentation for a api integration but I'm getting this error type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'

The sample response api gives according to its documentation is this Link to api

[
  {
    "category": "technology",
    "datetime": 1596589501,
    "headline": "Square surges after reporting 64% jump in revenue, more customers using Cash App",
    "id": 5085164,
    "image": "https://image.cnbcfm.com/api/v1/image/105569283-1542050972462rts25mct.jpg?v=1542051069",
    "related": "",
    "source": "CNBC",
    "summary": "Shares of Square soared on Tuesday evening after posting better-than-expected quarterly results and strong growth in its consumer payments app.",
    "url": "https://www.cnbc.com/2020/08/04/square-sq-earnings-q2-2020.html"
  },
  {
    "category": "business",
    "datetime": 1596588232,
    "headline": "B&G Foods CEO expects pantry demand to hold up post-pandemic",
    "id": 5085113,
    "image": "https://image.cnbcfm.com/api/v1/image/106629991-1595532157669-gettyimages-1221952946-362857076_1-5.jpeg?v=1595532242",
    "related": "",
    "source": "CNBC",
    "summary": "\"I think post-Covid, people will be working more at home, which means people will be eating more breakfast\" and other meals at home, B&G CEO Ken Romanzi said.",
    "url": "https://www.cnbc.com/2020/08/04/bg-foods-ceo-expects-pantry-demand-to-hold-up-post-pandemic.html"
  },
  {
    "category": "top news",
    "datetime": 1596584406,
    "headline": "Anthony Levandowski gets 18 months in prison for stealing Google self-driving car files",
    "id": 5084850,
    "image": "https://image.cnbcfm.com/api/v1/image/106648265-1596584130509-UBER-LEVANDOWSKI.JPG?v=1596584247",
    "related": "",
    "source": "CNBC",
    "summary": "A U.S. judge on Tuesday sentenced former Google engineer Anthony Levandowski to 18 months in prison for stealing a trade secret from Google related to self-driving cars months before becoming the head of Uber Technologies Inc's rival unit.",
    "url": "https://www.cnbc.com/2020/08/04/anthony-levandowski-gets-18-months-in-prison-for-stealing-google-self-driving-car-files.html"
  }
  }]

This is my code I followed from here

News class:

class News {
  final int id;
  final String category;
  final String datetime;
  final String headline;
  final String image;
  final String source;
  final String related;
  final String summary;
  final String url;

  News(
      {required this.id,
      required this.category,
      required this.datetime,
      required this.headline,
      required this.image,
      required this.source,
      required this.related,
      required this.summary,
      required this.url});

  factory News.fromJson(Map<String, dynamic> json) {
    return News(
      id: json['id'],
      category: json['category'],
      datetime: json['datetime'],
      headline: json['headline'],
      image: json['image'],
      related: json['realted'],
      source: json['source'],
      summary: json['summary'],
      url: json['url'],
    );
  }
}

Data fetching screen:

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

  @override
  State<MarketingNewsScreen> createState() => _MarketingNewsScreenState();
}

class _MarketingNewsScreenState extends State<MarketingNewsScreen> {
  late Future<News> futureNews;
  Future<News> fetchNews() async {
    final response = await http.get(Uri.parse(
        'https://finnhub.io/api/v1/news?category=general&token=mytokenhiddenhere'));

    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      return News.fromJson(jsonDecode(response.body));
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception('Failed to load album');
    }
  }

  @override
  void initState() {
    super.initState();
    futureNews = fetchNews();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          centerTitle: true,
          automaticallyImplyLeading: false,
          leading: IconButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              icon: const Icon(Icons.arrow_back_ios)),
          title: const Text("Marketing News")),
      body: Center(
        child: FutureBuilder<News>(
          future: futureNews,
          builder: (context, abc) {
            if (abc.hasData) {
              return Text(abc.data!.category);
            } else if (abc.hasError) {
              print("${abc.error}");
              return Text("${abc.error}");
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

Everything seems fine and well according to the documentation but it's giving the error and not working. I'm new to flutter especially to api side of it so I don't know what's wrong I'm doing here. Any help will be highly appreciated

CodePudding user response:

Your api result is list but in your model class you expect map,change your model class to this:

static List<News> fromJson(List _list) {
    List<News> result = [];

    for (var item in _list) {
      var news = News(
      id: item['id'],
      category: item['category'],
      datetime: item['datetime'],
      headline: item['headline'],
      image: item['image'],
      related: item['realted'],
      source: item['source'],
      summary: item['summary'],
      url: item['url'],
    );
      result.add(news);
    }
    return result;
  }

and also replace FutureBuilder<News> with FutureBuilder<List<News>> and all Future<News> with Future<List<News>>

  • Related