Search code examples
flutterhttpgetdata-modelingflutter-futurebuilder

How to fetch data from this Nested JSON using GET method in flutter using Data Model?


I am trying to print the value of JSON in Future Builder using List Tile Builder. But I don't Know how to get the particular value from Nested JSON to the List Tile Text widget. Can someone help me?

This is the JSON File and Link for it:

    {
   "result":"success",
   "data":[
      {
         "Id":1,
         "LucasTvsPartNo":"26080177",
         "PartImage":"LFAA 5031.png",
         "FilterType":"Air Filter",
         "CustomerPartNo":"LFAA-5031",
         "Model":"Bajaj GC 1000",
         "ModelImage":"bajajgc1000.png",
         "Segment":"3W",
         "Descriptions":"Air Filter - Polyurethane Type",
         "OEMName":"BAJAJ",
         "OEMImage":"bajaj.png",
         "OEMPartNo":null,
         "ListPrice":156.87,
         "MRPPrice":189.0,
         "MasterCartonSize":32
      }
]
}

The Data Field in this JSON has many records Upto 10.

This is Data Model Using JSON to Dart:

class Temperatures {
final String result;
final List<Datum> data;

Temperatures({
    required this.result,
    required this.data,
});

}

class Datum {
    final int id;
    final String lucasTvsPartNo;
    final String partImage;
    final String filterType;
    final String customerPartNo;
    final String model;
    final String modelImage;
    final String segment;
    final String descriptions;
    final String oemName;
    final String oemImage;
    final dynamic oemPartNo;
    final double listPrice;
    final int mrpPrice;
    final int masterCartonSize;
Datum({
    required this.id,
    required this.lucasTvsPartNo,
    required this.partImage,
    required this.filterType,
    required this.customerPartNo,
    required this.model,
    required this.modelImage,
    required this.segment,
    required this.descriptions,
    required this.oemName,
    required this.oemImage,
    required this.oemPartNo,
    required this.listPrice,
    required this.mrpPrice,
    required this.masterCartonSize,
});

}

My Code for Printing the data from the class to UI using future builder:

import 'dart:convert';

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

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

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  late Future _futureData;
  @override
  void initState() {
    WidgetsFlutterBinding.ensureInitialized();
    _futureData = getData();
    super.initState();
  }

  Future getData() async {
    var url = Uri.parse(
        'http://35.154.214.176/LucasfilterAPI/api/Values/GetPricelist');
    var response = await http.get(url, headers: {
      "Accept": "application/json",
      "content-type": "application/json"
    });

    Map<String, dynamic> jsonMap = json.decode(response.body);

    print(response.statusCode);
    print(response.body);

    List<Product> Products =
        List<Product>.from(jsonMap['data'].map((x) => Data.fromJson(x)));

    return Products;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
          future: _futureData,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(
                child: CircularProgressIndicator(),
              );
            } else if (snapshot.hasError) {
              return Center(
                child: Text('Error fetching data'),
              );
            } else {
              List Data = snapshot.data;
              return ListView.builder(
                itemCount: Data.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text('Result: ${Data[index].result}'),
                    subtitle: Text('Data: ${Data[index].data.toString()}'),
                  );
                },
              );
            }
          }),
    );
  }
}

It show me the ERROR of Fetching Data .I don't know how to handle nested JSON data. This is the Problem described. If you want any further clarification. I can Provide also.


Solution

  • class Datum {
      final int id;
      final String lucasTvsPartNo;
      final String partImage;
      final String filterType;
      final String customerPartNo;
      final String model;
      final String modelImage;
      final String segment;
      final String descriptions;
      final String oemName;
      final String oemImage;
      final double listPrice;
      final double mrpPrice;
      final int masterCartonSize;
    
      Datum({
        required this.id,
        required this.lucasTvsPartNo,
        required this.partImage,
        required this.filterType,
        required this.customerPartNo,
        required this.model,
        required this.modelImage,
        required this.segment,
        required this.descriptions,
        required this.oemName,
        required this.oemImage,
        required this.listPrice,
        required this.mrpPrice,
        required this.masterCartonSize,
      });
    
      factory Datum.fromJson(Map<String, dynamic> json) {
        return Datum(
          id: json['Id'],
          lucasTvsPartNo: json['LucasTvsPartNo'],
          partImage: json['PartImage'],
          filterType: json['FilterType'],
          customerPartNo: json['CustomerPartNo'],
          model: json['Model'],
          modelImage: json['ModelImage'],
          segment: json['Segment'],
          descriptions: json['Descriptions'],
          oemName: json['OEMName'],
          oemImage: json['OEMImage'],
          listPrice: json['ListPrice'].toDouble(),
          mrpPrice: json['MRPPrice'].toDouble(),
          masterCartonSize: json['MasterCartonSize'],
        );
      }
    }
    
    class Temperatures {
      String? result;
      List<Datum?>? data;
    
      Temperatures({this.result, this.data});
    
      Temperatures.fromJson(Map<String, dynamic> json) {
        result = json['result'];
        if (json['data'] != null) {
          data = <Datum>[];
          json['data'].forEach((v) {
            data!.add(Datum.fromJson(v));
          });
        }
      }
    }
    

    But if you have null values, you must change for example String to String? and remove the required or use ?? to assign default values if it null like: model: json['Model'] ?? '-',

    And fetch the data from the internet:

    Future fetchData() async {
      try {
        var url = Uri.parse(u);
    
        var response = await http.get(url, headers: {
          "Accept": "application/json",
          "content-type": "application/json"
        });
    
        if (response.statusCode == 200) {
          return Temperatures.fromJson(
              jsonDecode(response.body) as Map<String, dynamic>);
        } else {
          throw Exception('Failed to load ');
        }
      } catch (e) {
        print(e.toString());
      }
    }
    

    And you can access data using:

    Temperatures result = await fetchData();
    List<Datum> data = result.data;