Reputation: 35
Here is the json file that i want to parse:
{
"Meta Data": {
"1. Information": "Weekly Adjusted Prices and Volumes",
"2. Symbol": "MSFT",
"3. Last Refreshed": "2020-03-25",
"4. Time Zone": "US/Eastern"
},
"Weekly Adjusted Time Series": {
"2020-03-25": {
"1. open": "137.0100",
"2. high": "154.3300",
"3. low": "132.5200",
"4. close": "146.9200",
"5. adjusted close": "146.9200",
"6. volume": "235583286",
"7. dividend amount": "0.0000"
},
"2020-03-20": {
"1. open": "140.0000",
"2. high": "150.1500",
"3. low": "135.0000",
"4. close": "137.3500",
"5. adjusted close": "137.3500",
"6. volume": "421347734",
"7. dividend amount": "0.0000"
},
}
I just wanted to get the date, open, and close. I tried finding stuff online but still was unable to do so.
Here is my TimeSeries class:
class TimeSeries {
final String date;
final double open;
final double close;
TimeSeries({this.date, this.open, this.close});
factory TimeSeries.fromJson(Map<String, dynamic> json) {
return TimeSeries(
date: json[''],
open: double.parse(json['1. open']),
close: double.parse(json['4. close']),
);
}
}
And these are my function for now:
Future getTimeSeries(String stock) async {
print("Starting get request");
http.get("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo").then((res){
print("received response.");
var resObj = json.decode(res.body);
}).catchError((e) {
print("Failed to get response.");
});
}
Upvotes: 2
Views: 1644
Reputation: 31
I'd suggest to use this library https://github.com/k-paxian/dart-json-mapper
Of course if you don't like to hardcode .fromJson
methods for all your model classes manually and having fun with debugging & supporting them later.
Upvotes: 0
Reputation: 7182
You may want to do some mapping here. Your TimeSeries
class is enough, but you need to tweak your getTimeSeries
function. Firstly, you may want to change its return type to return a Future
with a List<TimeSeries>
, because you'll be getting a list of those.
Inside the then
callback of your HTTP call you want to firstly get inside the JSON map you have data in, so in that case it's resObj['Weekly Adjusted Time Series']
. Then, run map
on this and here is the place where you want to instantiate TimeSeries
(I also used final
instead of var
- it's just a good practise to use it where you don't need var
):
final resObj = json.decode(res.body);
return resObj.map((date, fields) {
return TimeSeries(DateTime.parse(date), fields['1. open'], fields['4. close']);
});
IMO TimeSeries.fromJson
won't help here, because you don't get the date
field from this inside map in your JSON.
Your whole new code would look like this:
class TimeSeries {
final String date;
final double open;
final double close;
TimeSeries({this.date, this.open, this.close});
}
Future<List<TimeSeries>> getTimeSeries(String stock) async {
print("Starting get request");
return http.get("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo").then((res){
print("received response.");
final resObj = json.decode(res.body);
return resObj.map((date, fields) {
return TimeSeries(date, fields['1. open'], fields['4. close']);
});
}).catchError((e) {
print("Failed to get response.");
});
}
Upvotes: 2
Reputation: 2340
Try this.
class TimeSeries {
final String date;
final double open;
final double close;
TimeSeries({this.date, this.open, this.close});
factory TimeSeries.fromJson(Map<String, dynamic> json, String indexDate) {
return TimeSeries(
date: indexDate,
open: double.parse(json["Weekly Adjusted Time Series"][indexDate]['1. open']),
close: double.parse(json["Weekly Adjusted Time Series"][indexDate]['4. close']),
);
}
}
And you can call the constructor as follows
List<TimeSeries> datesList(json) {
List<TimeSeries> dates;
for (date in json["Weekly Adjusted Time Series"]) {
dates.add(TimeSeries.fromJson(json, date));
}
return dates;
}
Upvotes: 2