2

Dart / Flutter JSON parsing and display

I am having trouble parsing and displaying the info. Am getting data from API

I get a response == 200 from API but am unable to display it.

The printout on screen is "Instance of medData"

Future<medData> fetchData(http.Client client) async {
  final response = await http.get(
    'xxxxxxxxxx',
    headers: {
      "host": "rapidapi.com",
      "key": "x87439756734",
    },
  );

  if (response.statusCode == 200) {
    // List json = json.decode(response.body);
    // return json.map((medData) => new medData.fromJson(medData)).toList();
    return medData.fromJson(json.decode(response.body));
  } else {
    throw Exception('Failed to load data from API');
  }
}

This Is the List View Builder

ListView _medDataListView(data) {
  return ListView.builder(
      itemCount: data.length,
      itemBuilder: (context, index) {
        return _tile(data[index].cases, data[index].number, Icons.work);
      });
}

Tile builder

ListTile _tile(String title, String subtitle, IconData icon) => ListTile(
      title: Text(title,
          style: TextStyle(
            fontWeight: FontWeight.w500,
            fontSize: 20,
          )),
      subtitle: Text(subtitle),
      leading: Icon(
        icon,
        color: Colors.blue[500],
      ),
    );

Class medData for parsing the JSON

class medData {
  String country;
  List<LatestStatByCountry> latestStatByCountry;

  medData({this.country, this.latestStatByCountry});

  medData.fromJson(Map<String, dynamic> json) {
    country = json['country'];
    if (json['latest_stat_by_country'] != null) {
      latestStatByCountry = new List<LatestStatByCountry>();
      json['latest_stat_by_country'].forEach((v) {
        latestStatByCountry.add(new LatestStatByCountry.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['country'] = this.country;
    if (this.latestStatByCountry != null) {
      data['latest_stat_by_country'] =
          this.latestStatByCountry.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class LatestStatByCountry {
  String id;
  String countryName;
  String totalCases;
  String newCases;
  String activeCases;
  String totalDeaths;
  String newDeaths;
  String totalRecovered;
  String seriousCritical;
  Null region;
  String totalCasesPer1m;
  String recordDate;

  LatestStatByCountry(
      {this.id,
      this.countryName,
      this.totalCases,
      this.newCases,
      this.activeCases,
      this.totalDeaths,
      this.newDeaths,
      this.totalRecovered,
      this.seriousCritical,
      this.region,
      this.totalCasesPer1m,
      this.recordDate});

  LatestStatByCountry.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    countryName = json['country_name'];
    totalCases = json['total_cases'];
    newCases = json['new_cases'];
    activeCases = json['active_cases'];
    totalDeaths = json['total_deaths'];
    newDeaths = json['new_deaths'];
    totalRecovered = json['total_recovered'];
    seriousCritical = json['serious_critical'];
    region = json['region'];
    totalCasesPer1m = json['total_cases_per1m'];
    recordDate = json['record_date'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['country_name'] = this.countryName;
    data['total_cases'] = this.totalCases;
    data['new_cases'] = this.newCases;
    data['active_cases'] = this.activeCases;
    data['total_deaths'] = this.totalDeaths;
    data['new_deaths'] = this.newDeaths;
    data['total_recovered'] = this.totalRecovered;
    data['serious_critical'] = this.seriousCritical;
    data['region'] = this.region;
    data['total_cases_per1m'] = this.totalCasesPer1m;
    data['record_date'] = this.recordDate;
    return data;
  }
}

Building the widget

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<medData>(
          future: fetchData(http.Client()),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Text("${snapshot.data}");
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
} 

I don't really know what i'm doing wrong when trying to display the data.

2
  • Can you show me an example of your json data that you fetched? Commented Mar 26, 2020 at 7:22
  • Thank you for the reply :) { "country": "South Africa", "latest_stat_by_country": [ { "id": "216413", "country_name": "South Africa", "total_cases": "709", "new_cases": "", "active_cases": "697", "total_deaths": "", "new_deaths": "", "total_recovered": "12", "serious_critical": "2", "region": null, "total_cases_per1m": "12", "record_date": "2020-03-26 05:50:02.171" } ] } Commented Mar 26, 2020 at 7:57

1 Answer 1

1

You can copy paste run full code below
Step 1 : parse json string with medDataFromJson(response.body);

factory MedData.fromJson(Map<String, dynamic> json) => MedData(
        country: json["country"],
        latestStatByCountry: List<LatestStatByCountry>.from(
            json["latest_stat_by_country"]
                .map((x) => LatestStatByCountry.fromJson(x))),
      );

Step 2 : In FutureBuilder do return _medDataListView(snapshot.data.latestStatByCountry);

Step 3: ListView _medDataListView(List<LatestStatByCountry> data) data is List<LatestStatByCountry>

working demo

enter image description here

full code

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

// To parse this JSON data, do
//
//     final medData = medDataFromJson(jsonString);

import 'dart:convert';

MedData medDataFromJson(String str) => MedData.fromJson(json.decode(str));

String medDataToJson(MedData data) => json.encode(data.toJson());

class MedData {
  String country;
  List<LatestStatByCountry> latestStatByCountry;

  MedData({
    this.country,
    this.latestStatByCountry,
  });

  factory MedData.fromJson(Map<String, dynamic> json) => MedData(
        country: json["country"],
        latestStatByCountry: List<LatestStatByCountry>.from(
            json["latest_stat_by_country"]
                .map((x) => LatestStatByCountry.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "country": country,
        "latest_stat_by_country":
            List<dynamic>.from(latestStatByCountry.map((x) => x.toJson())),
      };
}

class LatestStatByCountry {
  String id;
  String countryName;
  String totalCases;
  String newCases;
  String activeCases;
  String totalDeaths;
  String newDeaths;
  String totalRecovered;
  String seriousCritical;
  dynamic region;
  String totalCasesPer1M;
  DateTime recordDate;

  LatestStatByCountry({
    this.id,
    this.countryName,
    this.totalCases,
    this.newCases,
    this.activeCases,
    this.totalDeaths,
    this.newDeaths,
    this.totalRecovered,
    this.seriousCritical,
    this.region,
    this.totalCasesPer1M,
    this.recordDate,
  });

  factory LatestStatByCountry.fromJson(Map<String, dynamic> json) =>
      LatestStatByCountry(
        id: json["id"],
        countryName: json["country_name"],
        totalCases: json["total_cases"],
        newCases: json["new_cases"],
        activeCases: json["active_cases"],
        totalDeaths: json["total_deaths"],
        newDeaths: json["new_deaths"],
        totalRecovered: json["total_recovered"],
        seriousCritical: json["serious_critical"],
        region: json["region"],
        totalCasesPer1M: json["total_cases_per1m"],
        recordDate: DateTime.parse(json["record_date"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "country_name": countryName,
        "total_cases": totalCases,
        "new_cases": newCases,
        "active_cases": activeCases,
        "total_deaths": totalDeaths,
        "new_deaths": newDeaths,
        "total_recovered": totalRecovered,
        "serious_critical": seriousCritical,
        "region": region,
        "total_cases_per1m": totalCasesPer1M,
        "record_date": recordDate.toIso8601String(),
      };
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

MedData medData;

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  ListView _medDataListView(List<LatestStatByCountry> data) {
    return ListView.builder(
        itemCount: data.length,
        itemBuilder: (context, index) {
          return _tile(
              data[index].countryName, data[index].totalCases, Icons.work);
        });
  }

  ListTile _tile(String title, String subtitle, IconData icon) => ListTile(
        title: Text(title,
            style: TextStyle(
              fontWeight: FontWeight.w500,
              fontSize: 20,
            )),
        subtitle: Text(subtitle),
        leading: Icon(
          icon,
          color: Colors.blue[500],
        ),
      );

  Future<MedData> fetchData(http.Client client) async {
    final response = await http.get(
      'https://coronavirus-monitor.p.rapidapi.com/coronavirus/latest_stat_by_country.php?country=South%20Africa',
      headers: {
        "x-rapidapi-host": "coronavirus-monitor.p.rapidapi.com",
        "x-rapidapi-key": "23bdb74dbfmsh865510b645e32f6p1f7b7bjsn2e800c1ac844",
      },
    );
    /*String jsonString = '''
    { "country": "South Africa", "latest_stat_by_country": [ { "id": "216413", "country_name": "South Africa", "total_cases": "709", "new_cases": "", "active_cases": "697", "total_deaths": "", "new_deaths": "", "total_recovered": "12", "serious_critical": "2", "region": null, "total_cases_per1m": "12", "record_date": "2020-03-26 05:50:02.171" } ] }
    ''';

    http.Response response = http.Response(jsonString, 200);*/
    if (response.statusCode == 200) {
      // List json = json.decode(response.body);
      // return json.map((medData) => new medData.fromJson(medData)).toList();
      //return medData.fromJson(json.decode(response.body));
      medData = medDataFromJson(response.body);
      return medData;
    } else {
      throw Exception('Failed to load data from API');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<MedData>(
          future: fetchData(http.Client()),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              //return Text("${snapshot.data}");
              return _medDataListView(snapshot.data.latestStatByCountry);
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much for the response. I am trying to display the records individually in a list. How do i get the json from the api to parse? final response = await http.get( 'coronavirus-monitor.p.rapidapi.com/coronavirus/…', headers: { "x-rapidapi-host": "coronavirus-monitor.p.rapidapi.com", "x-rapidapi-key": "23bdb74dbfmsh865510b645e32f6p1f7b7bjsn2e800c1ac844", }, );
Glad to help. please mark this as answer if it help you. thanks.
I have update full code to include your url. please check it.
Yo are an absolute champ! I have one final question. How do get set variables to each one of the subfield ie. id, totalcases so as to use them elsewhere? Also how do i display all the submenus in the list simultaneously?
I have update full code. just declare MedData medData outside of class. then you can access everywhere. and ListView will show List<LatestStatByCountry> , you do not need extra codeing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.