2
votes

I am working with Flutter and am currently trying to create a graph. I am looking to parse this JSON Array from the link below. My issue is that the information provided in the "prices" object, the values are all inside arrays themselves. I want to get those values and split them into an X and Y list but I have no idea how to accomplish this. I posted a snippet of the JSON data below.

https://api.coingecko.com/api/v3/coins/bitcoin/market_chartvs_currency=usd&days=1

I am only familiar with parsing data by creating a class and constructor. Then create a fromJSON(Map<String, dynamic> json) class and putting the data into a list, as shown in the code snippet below that I created from another URL with object values. How could I go about parsing this array JSON data into two list data?

CODE TO PARSE JSON

List<Coins> _coins = List<Coins>();
Future<List<Coins>> fetchCoins() async {
var url = 'URL';
var response = await http.get(url);

var coins = List<Coins>();

if (response.statusCode == 200) {
  var coinsJSON = json.decode(response.body);
  for (var coinJSON in coinsJSON) {
    coins.add(Coins.fromJson(coinJSON));
  }
}
return coins;
 }

@override
void initState() {
fetchCoins().then((value) {
  setState(() {
    _coins.addAll(value);
  });
});
super.initState();
}

class Coins{
String symbol;
String name;

Coins(this.symbol, this.name);

Coins.fromJson(Map<String, dynamic> json) {
symbol = json['symbol'];
name = json['name'];

JSON DATA SNIPPET

{
"prices":[
  [
     1566344769277,
     10758.856131083012
  ],
  [
     1566345110646,
     10747.91694691537
  ],
  [
     1566345345922,
     10743.789313302059
  ],
]
}

EDIT: SOLVED WITH THE HELP OF @EJABU.

class HistoricalData {
 List prices;
 List<num> listX = [];
List<num> listY = [];

HistoricalData(this.prices,this.listX, this.listY);

HistoricalData.fromJson(Map<String, dynamic> json) {
prices = json['prices'];
for (var price in prices) {
  listX.add(price[0]);
  listY.add(price[1]);
 }
}
2

2 Answers

2
votes

You may try this...

New class Coins definition:

class Coins {
  List<num> listX = [];
  List<num> listY = [];

  Coins(this.listX, this.listY);

  Coins.fromJson(Map<String, dynamic> json) {
    List<List<num>> prices = json['prices'];
    for (var price in prices) {
      listX.add(price[0]);
      listY.add(price[1]);
    }
  }
}

Then later you can fetch it by these lines :

// Future<List<Coins>> fetchCoins() async { // Remove This
Future<Coins> fetchCoins() async {
  var url = 'URL';
  var response = await http.get(url);

  // var coins = List<Coins>(); // Remove This
  Coins coins;

  if (response.statusCode == 200) {
    var coinsJSON = json.decode(response.body);

    // Remove This
    // for (var coinJSON in coinsJSON) {
    //   coins.add(Coins.fromJson(coinJSON));
    // }
    //
    coins = Coins.fromJSON(coinsJSON);
  }
  return coins;
}

Accessing Data in Widget

In Widgets , our expected variable resides as property inside Coins class.

For example, if you use FutureBuilder, you may use these lines:

child: FutureBuilder(
  future: fetchCoins(),
  builder: (_, __) {
    return SomeChartWidget(
      listX: coins.listX,
      listY: coins.listY,
    );
  },
),
0
votes

Generating Serializers automatically

I suggest you take a look at https://pub.dev/packages/json_serializable, which is a package that does the boilerplate code generation for you. Although it might me a bit overkill to add something like this to your code or your workflow, automatically generating serializers is very convenient.

Not that in order to have custom sub-classes, they need to provide serialization as well.

If you want to extend your knowledge even further, you can also have a look at https://pub.dev/packages/built_value and https://pub.dev/packages/built_value_generator