Home > OS >  Get json and show inforamtion in flutter ListView
Get json and show inforamtion in flutter ListView

Time:02-03

I`m trying to work with JSON and display data in a widget

I`m getting json from website

https://jsonplaceholder.typicode.com/posts

And I'm trying to display data from json in ListView

I`m click on button, titles are displayed in list

It's working fine


import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

class NewsWidget extends StatefulWidget {
  const NewsWidget({super.key});

  @override
  State<NewsWidget> createState() => _NewsWidgetState();
}

class _NewsWidgetState extends State<NewsWidget> {
  
  var jsonNews;

  getNewsNYT() async {
    var dio = Dio();

    final response =
        await dio.get('https://jsonplaceholder.typicode.com/posts');
    setState(() {
      jsonNews = response.data;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('JSON'),
        actions: [
          ElevatedButton(
            onPressed: getNewsNYT,
            child: const Text('NYT'),
          ),
        ],
      ),
      body: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: ListTile(
              title: Text(jsonNews[index]['title']),
            ),
          );
        },
        itemCount: jsonNews == null ? 0 : jsonNews.length,
      ),
    );
  }
}

After that I tried with a real example and took the New York Times API

There I display popular news from the main one, the request itself looks like this

final response = await dio.get('https://api.nytimes.com/svc/topstories/v2/home.json?api-key=my-key');

I add my key at the end of the request correctly


import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

class NewsWidget extends StatefulWidget {
  const NewsWidget({super.key});

  @override
  State<NewsWidget> createState() => _NewsWidgetState();
}

class _NewsWidgetState extends State<NewsWidget> {
  var jsonNews;

  getNewsNYT() async {
    var dio = Dio();

    final response = await dio.get(
        'https://api.nytimes.com/svc/topstories/v2/home.json?api-key=0SDaGP4DLAzR5OtGxVC6ObfhNljic18h');
    setState(() {
      jsonNews = response.data;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('JSON'),
        actions: [
          ElevatedButton(
            onPressed: getNewsNYT,
            child: const Text('NYT'),
          ),
        ],
      ),
      body: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: ListTile(
              title: Text(jsonNews[index]['title']),
            ),
          );
        },
        itemCount: jsonNews == null ? 0 : jsonNews.length,
      ),
    );
  }
}

I get an error there

title: Text(jsonNews[index]['title']),

The method '[]' was called on null.

I open the url to check that there really is data

I use https://jsonformatter.org/ to make it clear

As a result, I see that before Map String information is placed that I do not need. If it is removed, the Map will work correctly.

https://i.stack.imgur.com/eRG7M.jpg

How correctly to work with result of request? For example, I want to display news titles in a ListView.

Solution


getNewsNYT() async {
    var dio = Dio();
    final response = await dio.get(
        'https://api.nytimes.com/svc/topstories/v2/home.json?api-key=0SDaGP4DLAzR5OtGxVC6ObfhNljic18h');
    final jsonBody = response.data['results']; // beacause main map in section results:

    setState(() {
      jsonNews = jsonBody;
    });
  }

CodePudding user response:

I think The problem is here jsonNews = response.data, the data you need is in the ['results'] section. so try this

  getNewsNYT() async {
//var dio = Dio();

final response = await http.get(Uri.parse(
    'https://api.nytimes.com/svc/topstories/v2/home.json?api-key=0SDaGP4DLAzR5OtGxVC6ObfhNljic18h'));
setState(() {
  var jsonBody = convert.jsonDecode(response.body);
  jsonNews = jsonBody['results'];
});

}

then you will get this result results

CodePudding user response:

did you try to use the result key like that:
TextText(jsonNews[index]['results'][index]['title']);
this might not work because you have an inner list on the results key try to extract the result list and use it in listview

  • Related