Sudhakar
Sudhakar

Reputation: 57

How to Parse Nested JSON

I'm able to parse the JSON using following code,

Map<String, dynamic> map = jsonDecode(response.body); // import 'dart:convert';

List<dynamic> datalist  = map['data'];

I got List dynamic but i need data list

My problem is if I get product items in data list then how should i parse the JSON. I got stuck here.

When it comes to nested array of JSON, how to parse it.

**

{
    "status": 0,
    "message": "Product Not Found",
    "data": [{
            "id": "1",
            "product_name": "Pet 0.5",
            "qty": "500",
            "unit": "ml",
            "product_img": "SRC.jpg",
            "description": "sgsdgdfhdfhh",
            "sale_price": "100",
            "donation_amt": "10"
        },
        {
            "id": "7",
            "product_name": "Pet 1l",
            "qty": "1",
            "unit": "l",
            "product_img": "SRC1.jpg",
            "description": "dgdg",
            "sale_price": "20",
            "donation_amt": "1"
        }
    ]
}

**

My dart code for the JSON

    class ProductList {
      int status;
      String message;
      List<Data> data;

      ProductList({this.status, this.message, this.data});

      ProductList.fromJson(Map<String, dynamic> json) {
        status = json['status'];
        message = json['message'];
        if (json['data'] != null) {
          data = new List<Data>();
          json['data'].forEach((v) {
            data.add(new Data.fromJson(v));
          });
        }
      }

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

class Data {
  String id;
  String productName;
  String qty;
  String unit;
  String productImg;
  String description;
  String salePrice;
  String donationAmt;

  Data(
      {this.id,
      this.productName,
      this.qty,
      this.unit,
      this.productImg,
      this.description,
      this.salePrice,
      this.donationAmt});

  Data.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    productName = json['product_name'];
    qty = json['qty'];
    unit = json['unit'];
    productImg = json['product_img'];
    description = json['description'];
    salePrice = json['sale_price'];
    donationAmt = json['donation_amt'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['product_name'] = this.productName;
    data['qty'] = this.qty;
    data['unit'] = this.unit;
    data['product_img'] = this.productImg;
    data['description'] = this.description;
    data['sale_price'] = this.salePrice;
    data['donation_amt'] = this.donationAmt;
    return data;
  }
}

This is the code below for the drop down list. We need to populate the drop down with the product name and id. The product name and id fields are there in the data part of the JSON

                       Padding(
                      padding: const EdgeInsets.fromLTRB(25.0, 20.0, 0, 0),
                    child: Container(
                        width: 160,
                        height: 40,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(5.0),
                          border: Border.all(
                              color: Colors.red,
                              style: BorderStyle.solid,
                              width: 0.80),
                        ),
                        child: DropdownButton<Product>(
                            value: selectedUser,
                            icon: Padding(
                              padding: const EdgeInsets.only(left:15.0),
                              child: Icon(Icons.arrow_drop_down),
                            ),
                            iconSize: 25,
                            underline: SizedBox(),
                            onChanged: (Product newValue) {
                              setState(() {
                                selectedUser = newValue;
                              });
                            },

                            items: users.map((Product user) {
                              return DropdownMenuItem<Product>(
                                value: user,
                                child: Padding(
                                  padding:
                                      const EdgeInsets.only(left: 10.0),
                                  child: Text(
                                    user.name,
                                    style: TextStyle(
                                      fontSize: 18,
                                      color: Colors.black,
                                    ),
                                  ),
                                ),
                              );
                            }).toList()),
                      ),
                       ),

Upvotes: 1

Views: 480

Answers (2)

Mike Robinson
Mike Robinson

Reputation: 8945

Remember: "JSON is not 'nested.'" When you're given a JSON string, you decode it and this gives you a data-structure ... which very well might be "nested." How to handle that correctly is up to you.

Always treat JSON (or YAML, or XML) as a "black box." Use the utilities provided in the language to encode, decode and parse them.

Upvotes: 0

Sagar Acharya
Sagar Acharya

Reputation: 3767

So as you Described i have made some changes and loaded you json locally, you can make a api call and then everything is the same:

{
    "status": 0,
    "message": "Product Not Found",
    "data": [
        {
            "id": "1",
            "product_name": "Pet 0.5",
            "qty": "500",
            "unit": "ml",
            "product_img": "SRC.jpg",
            "description": "sgsdgdfhdfhh",
            "sale_price": "100",
            "donation_amt": "10"
        },
        {
            "id": "7",
            "product_name": "Pet 1l",
            "qty": "1",
            "unit": "l",
            "product_img": "SRC1.jpg",
            "description": "dgdg",
            "sale_price": "20",
            "donation_amt": "1"
        }
    ]
}

json you provided

// To parse this JSON data, do
//
//     final productList = productListFromJson(jsonString);

import 'dart:convert';

ProductList productListFromJson(String str) =>
    ProductList.fromJson(json.decode(str));

String productListToJson(ProductList data) => json.encode(data.toJson());

class ProductList {
  int status;
  String message;
  List<Datum> data;

  ProductList({
    this.status,
    this.message,
    this.data,
  });

  factory ProductList.fromJson(Map<String, dynamic> json) => ProductList(
        status: json["status"],
        message: json["message"],
        data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "status": status,
        "message": message,
        "data": List<dynamic>.from(data.map((x) => x.toJson())),
      };
}

class Datum {
  String id;
  String productName;
  String qty;
  String unit;
  String productImg;
  String description;
  String salePrice;
  String donationAmt;

  Datum({
    this.id,
    this.productName,
    this.qty,
    this.unit,
    this.productImg,
    this.description,
    this.salePrice,
    this.donationAmt,
  });

  factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        id: json["id"],
        productName: json["product_name"],
        qty: json["qty"],
        unit: json["unit"],
        productImg: json["product_img"],
        description: json["description"],
        salePrice: json["sale_price"],
        donationAmt: json["donation_amt"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "product_name": productName,
        "qty": qty,
        "unit": unit,
        "product_img": productImg,
        "description": description,
        "sale_price": salePrice,
        "donation_amt": donationAmt,
      };
}

creating the model class for the json

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sample_testing_project/models.dart';

main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _currentSelectedValue;
  List<Datum> data = List();
  bool _isLoading = false;
  String selectedUser;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    loadYourData();
  }

  Future<String> loadFromAssets() async {
    return await rootBundle.loadString('json/parse.json');
  }

  loadYourData() async {
    setState(() {
      _isLoading = true;
    });
    // Loading your json locally you can make an api call, when you get the response just pass it to the productListFromJson method
    String jsonString = await loadFromAssets();
    final productList = productListFromJson(jsonString);
    data = productList.data;
    setState(() {
      _isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: _isLoading
            ? Text('Loading')
            : Container(
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(25.0, 20.0, 0, 0),
                  child: Container(
                    width: 160,
                    height: 40,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(5.0),
                      border: Border.all(
                          color: Colors.red,
                          style: BorderStyle.solid,
                          width: 0.80),
                    ),
                    child: DropdownButton(
                        value: selectedUser,
                        isExpanded: true,
                        icon: Padding(
                          padding: const EdgeInsets.only(left: 15.0),
                          child: Icon(Icons.arrow_drop_down),
                        ),
                        iconSize: 25,
                        underline: SizedBox(),
                        onChanged: (newValue) {
                          setState(() {
                            selectedUser = newValue;
                          });
                        },
                        hint: Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Text('Select'),
                        ),
                        items: data.map((data) {
                          return DropdownMenuItem(
                            value: data.id,
                            child: Padding(
                              padding: const EdgeInsets.only(left: 10.0),
                              child: Text(
                                data.id + ':' + data.productName,
                                style: TextStyle(
                                  fontSize: 18,
                                  color: Colors.black,
                                ),
                              ),
                            ),
                          );
                        }).toList()),
                  ),
                ),
              ),
      ),
    );
  }
}

check out the changes that i have made using your same ui. Let me know if its working. Thanks.

Upvotes: 2

Related Questions