5

Can anyone tell me how to parse this JSON in flutter.I'M stucked i created classes successfully but getting errors from parse method Here is The JSON

{
    "btcinr": {
        "base_unit": "btc",
        "quote_unit": "inr",
        "low": "3001337.0",
        "high": "3145000.0",
        "last": "3107312.0",
        "type": "SPOT",
        "open": "3085453",
        "volume": "243.1121",
        "sell": "3114335.0",
        "buy": "3106628.0",
        "at": 1646663606,
        "name": "BTC/INR"
    }
}

The method where i'm stuked and getting errors is

Future<List<Map<String, dynamic>>> fetchData() async {
    final response =
        await http.get(Uri.parse("https://api.wazirx.com/api/v2/tickers"));
    if (response.statusCode == 200) {
      final responseJson = json.decode(response.body);
      
    } else {
      throw Exception('Unexpected Error Occured!');
    }
  }

This method is incomplete ,any help will be appreciated Thank You!

0

4 Answers 4

5

Posting this example of a nested JSON request for better understanding. This example has a list of RejectedModel and this model has one nested model Reject in it and the code below is handling it.

Got this format of JSON Response.


[
    {
        "id": 2,
        "service": 200,
        "reject": {
            "id": 8,
            "reason": "sample",
            "order_id": 2,
        }
    },
    {
        "id": 3,
        "service": 600,
        "reject": {
            "id": 12,
            "reason": "sample",
            "order_id": 2,
        }
    }
]

The controller class looks like this

class RejectedModel{
  int id;
  int service;
  Reject reject;
  RejectedModel({required this.id, required this.service, required this.reject});

  factory RejectedModel.fromJson (Map<String,dynamic>json){
    return RejectedModel(id: json['id'],
        service: json['service'],
        reject: Reject.fromJson(json['reject'])  );
  }
}
class Reject{
//this will handel nested object
    int id;
    String reason;
    int order_id;

    Reject({required this.id, required this.reason, required this.order_id,});

    factory Reject.fromJson (Map<String,dynamic>json){
      return Reject(id: json['id'],
          reason: json['reason'],
          order_id: json['order_id']);
    }
}

making the API call in this method. Future<List<RejectedModel>> is the return type of the below method

Future getRejctedOrders() async {
    final response = await http.get(Uri.parse('your url'));

    if(response.statusCode == 200){
      List rejected = json.decode(response.body);
      return rejected.map((e) => RejectedModel.fromJson(e)).toList();
    }
    else{
      throw Exception('something wrong');
    }
}

using this API call in the widget to display the data. Write this <List<RejectedModel>> before ( and after FutureBuilder

FutureBuilder <List<RejectedModel>> (
    future: getRejctedOrders,
    builder: (context,snapshot){
      if(snapshot.hasData){
        final List<RejectedModel>? data = snapshot.data;
        return ListView.builder(
          itemCount: data?.length,
          shrinkWrap: true,
          itemBuilder: (BuildContext context, int index){
            if(index.isNaN){
              return CircularProgressIndicator(color: Colors.grey,);
            }

            Reject rej = data![index].reject;
            //you can make the required widget
            return Text('data ${rej.reason}');

          },
        );
      }
      else{
        return CircularProgressIndicator(color: Colors.grey,);
      }
    },
  )
Sign up to request clarification or add additional context in comments.

Comments

3

I need to be honest, this is a bit of a generic question. But I will try to answer as I understand it. If you want to create a json parsing mechanism. You can use code generation approaches like this website. This generates a huge object for you but at least after you parse the information you can get an object to reference whatever you need.


I got the result from https://api.wazirx.com/api/v2/tickers. Put it to the website above. It generated the code here. I could not share it here because it is too big :)

What you need to do next is:

Future<Autogenerated> fetchData() async {
    final response =
        await http.get(Uri.parse("https://api.wazirx.com/api/v2/tickers"));
    if (response.statusCode == 200) {
      final responseJson = json.decode(response.body);
      final autogenerated = Autogenerated.fromJson(responseJson);
      return autogenerated;
    } else {
      throw Exception('Unexpected Error Occured!');
    }
  }

1 Comment

God bless you bro. you saved me. specially that website, the class generator
2

Following your json object structure, your fetchData method should have the return type of Map<String, Map<String, dynamic>> since it is a Map of a Map.

After updating the return type, the missing part of your code is the casting of your decoded response.body to Map<String, Map<String, dynamic>>.

See the solution below.

Solution:

Future<Map<String, Map<String, dynamic>>> fetchData() async {
    final response =
        await http.get(Uri.parse("https://api.wazirx.com/api/v2/tickers"));
    if (response.statusCode == 200) {
      final responseJson = (json.decode(response.body) as Map).map(
        (key, value) => MapEntry(key as String, value as Map<String, dynamic>));
      return responseJson;
    } else {
      throw Exception('Unexpected Error Occured!');
    }
  }

In a ListView Builder

You can use the method above to display the data in a ListView builder by using it in a FutureBuilder like below:

FutureBuilder<Map<String, Map<String, dynamic>>>(
        future: fetchData(),
        builder: (BuildContext context,
            AsyncSnapshot<Map<String, Map<String, dynamic>>> snapshot) {
          if (snapshot.data == null) {
            return const Center(child: CircularProgressIndicator());
          }

          final data = snapshot.data;

          return ListView.builder(
            itemBuilder: ((context, index) {
              final item = data!.entries.elementAt(index);
              final map = item.value;
              final String baseUnit = map['base_unit'];
              final String quoteUnit = map['quote_unit'];

              final String high = map['high'];
              final String low = map['low'];

              return ListTile(
                title: Text(baseUnit),
                subtitle: Text('High-$high$quoteUnit Low - $low$quoteUnit'),
              );
            }),
            itemCount: data!.entries.length,
          );
        },
      ),

Below is a screenshot of the UI generated from the above code:

enter image description here

2 Comments

Thank you can you also tell me how to show anything from this data in Listview builder and list tile!
@DASH, I've updated my answer with a sample code showing how to use the fetchData() method in a ListView builder.
0
Future<void> main() async {
  List<Map<String, dynamic>> fetchData2 = await fetchData();

  fetchData2.forEach((element) {
    print(element.runtimeType);
    print(element.keys);
    print(element.values);
  });
  print(fetchData2);
}

Future<List<Map<String, dynamic>>> fetchData() async {
  final response =
      await get(Uri.parse("https://api.wazirx.com/api/v2/tickers"));

  if (response.statusCode == 200) {
    Map<String, dynamic> responseJson = json.decode(response.body);
    // print(responseJson.runtimeType);
    List<Map<String, dynamic>> list = [];
    var cd = responseJson.forEach((key, value) {
      Map<String, dynamic> value2 = Map.of({key: value});
      list.add(value2);
    });

    return list;
  } else {
    throw Exception('Unexpected Error Occured!');
  }
}

Output

_InternalLinkedHashMap<String, dynamic>
1+===========>(btcinr)
({base_unit: btc, quote_unit: inr, low: 3001337.0, high: 3145000.0, last: 3102692.0, type: SPOT, open: 3090720, volume: 256.70627, sell: 3108375.0, buy: 3102776.0, at: 1646668281, name: BTC/INR})
_InternalLinkedHashMap<String, dynamic>
2+===========>(xrpinr)
({base_unit: xrp, quote_unit: inr, low: 56.4, high: 59.7997, last: 59.1699, type: SPOT, open: 58.333, volume: 688814.2, sell: 59.1663, buy: 59.0, at: 1646668281, name: XRP/INR})
_InternalLinkedHashMap<String, dynamic>
3+===========>(ethinr)
({base_unit: eth, quote_unit: inr, low: 200000.0, high: 210582.8, last: 207599.7, type: SPOT, open: 208225, volume: 528.2563, sell: 207672.0, buy: 207506.5, at: 1646668281, name: ETH/INR})
_InternalLinkedHashMap<String, dynamic>
4+===========>(trxinr)
({base_unit: trx, quote_unit: inr, low: 4.6206, high: 4.8, last: 4.782, type: SPOT, open: 4.721, volume: 12397343.0, sell: 4.782, buy: 4.7788, at: 1646668281, name: TRX/INR})
_InternalLinkedHashMap<String, dynamic>
5+===========>(eosinr)
({base_unit: eos, quote_unit: inr, low: 153.49, high: 161.97, last: 159.12, type: SPOT, open: 159, volume: 8064.39, sell: 159.86, buy: 159.02, at: 1646668281, name: EOS/INR})
_InternalLinkedHashMap<String, dynamic>
6+===========>(zilinr)
({base_unit: zil, quote_unit: inr, low: 2.95, high: 3.18, last: 3.14, type: SPOT, open: 3.04, volume: 1926347.0, sell: 3.13, buy: 3.12, at: 1646668281, name: ZIL/INR})
_InternalLinkedHashMap<String, dynamic>
7+===========>(batinr)
({base_unit: bat, quote_unit: inr, low: 49.511, high: 53.0, last: 51.782, type: SPOT, open: 51.799, volume: 42537.25, sell: 52.812, buy: 51.809, at: 1646668281, name: BAT/INR})
_InternalLinkedHashMap<String, dynamic>
8+===========>(zrxinr)
({base_unit: zrx, quote_unit: inr, low: 37.0, high: 39.43, last: 38.59, type: SPOT, open: 38.34, volume: 27340.61, sell: 39.34, buy: 38.48, at: 1646668281, name: ZRX/INR})
_InternalLinkedHashMap<String, dynamic>
9+===========>(reqinr)

enter image description here

SAmple Code

// To parse this JSON data, do
//
//     final bricklink = bricklinkFromJson(jsonString);

import 'dart:convert';

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

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyHomePage(title: 'Scanner'),
    );
  }
}

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

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

int myvalue = 0;

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

  @override
  void initState() {}

  Future<int> functions() async {
    // do something here
    return Future.value();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Scanner"),
        backgroundColor: Colors.green,
      ),
      body: FutureBuilder(
          future: fetchData(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              List<Map<String, dynamic>> data =
                  snapshot.data as List<Map<String, dynamic>>;
              return Container(
                color: Colors.white,
                child: ListView.builder(
                  itemCount: data.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text((data[index] as Map<String, dynamic>)
                          .keys
                          .single
                          .toString()),
                      subtitle: Text((data[index] as Map<String, dynamic>)
                          .values
                          .single
                          .toString()),
                      leading: CircleAvatar(
                          child: Text((data[index] as Map<String, dynamic>)
                              .keys
                              .single[0]
                              .toString())),
                    );
                  },
                ),
              );
            } else {
              return Center(
                child: Container(
                  height: 50,
                  width: 50,
                  child: CircularProgressIndicator(),
                ),
              );
            }
          }),
    );
  }
}

class Page1 extends StatelessWidget {
  var _controller = TextEditingController();

  Page1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Center(
          child: Container(
            height: 55,
            child: ElevatedButton(
                style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(Colors.green)),
                onPressed: () {},
                child: Text(
                  "Choose the Date",
                  style: TextStyle(fontSize: 25),
                )),
          ),
        ),
        Center(
          child: Text(
            "No date Choosen",
            style: TextStyle(fontSize: 16),
          ),
        ),
        Center(
          child: Wrap(
            // direction: Axis.vertical,
            children: [
              RadioListTile(
                  title: Text("home"),
                  value: "Home",
                  groupValue: "Home",
                  onChanged: (v) {}),
              RadioListTile(
                  title: Text("Company"),
                  value: "Company",
                  groupValue: "Home",
                  onChanged: (v) {}),
              RadioListTile(
                  title: Text("Other"),
                  value: "Other",
                  groupValue: "Home",
                  onChanged: (v) {}),
            ],
          ),
        ),
        Center(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextFormField(
              controller: _controller,
              decoration: InputDecoration(
                hintText: "Enter the number of bottels",
                border: OutlineInputBorder(),
              ),
            ),
          ),
        ),
        Container(
          // height: 75,
          padding: EdgeInsets.symmetric(horizontal: 50),
          child: Row(
            children: [
              Expanded(
                child: Container(
                  height: 55,
                  child: ElevatedButton(
                      style: ButtonStyle(
                          backgroundColor:
                              MaterialStateProperty.all(Colors.green)),
                      onPressed: () {},
                      child: Text(
                        "Start",
                        style: TextStyle(fontSize: 25),
                      )),
                ),
              ),
            ],
          ),
        )
      ],
    );
  }
}

Future<List<Map<String, dynamic>>> fetchData() async {
  final response =
      await get(Uri.parse("https://api.wazirx.com/api/v2/tickers"));

  if (response.statusCode == 200) {
    Map<String, dynamic> responseJson = json.decode(response.body);
    // print(responseJson.runtimeType);
    List<Map<String, dynamic>> list = [];
    var cd = responseJson.forEach((key, value) {
      Map<String, dynamic> value2 = Map.of({key: value});
      list.add(value2);
    });

    return list;
  } else {
    throw Exception('Unexpected Error Occured!');
  }
}

Comments

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.