Fetch data inside factory in flutter - json

I have a json response of this type
{
"uuid": "c6514be0-cced-43b7-b1f4-e66256c1dcaf",
"title": "Harry Potter",
"author": "6637e87b-c2ce-4774-b812-4e8a09312a40",
}
this answer is associated with another one through the author key
{
"author": "6637e87b-c2ce-4774-b812-4e8a09312a40",
"name": "J.K. Rowling",
}
So i have a Book class for first response
class Book {
final String uuid;
final String title;
final Author author;
Book({
required this.uuid,
required this.title,
required this.author,
});
}
and an Author class for second response
class Author {
final String uuid;
final String name;
Book({
required this.uuid,
required this.name,
});
}
My question is if there is a method to directly fetch the author during the book factory.
I tried with this method but i can't wait for response:
factory Book.fromJson(Map<String, dynamic> json) {
return Book(
uuid: json['uuid'],
title: json['title'],
author: fetchAuthor(json['author']),
);
}
Where
Future<Author> fetchAuthor(authorUuid) async {
http.Response author = await http.get(
Uri.parse(apiURLAuthors + authorUuid),
);
if (author.statusCode == 200) {
return Author.fromJson(jsonDecode(utf8.decode(author.bodyBytes)));
} else {
throw Exception("Failed to load author $authorUuid");
}
}

I'm not sure but you can call 2 model class(book & author) in another class where you wanted to show. Then create a function to call both the data from these 2 modal class and put it in global variable. Now you can able to access the data of both modal class globally. If you want to create list then you set all values in list variable else you can also create different data type values and save data of that particular index

Related

Trying to get city name from json but getting null return

I am new to dart and following a this post to get my data from json:
https://medium.com/flutter-community/converting-json-into-class-objects-in-dart-abcc3cc05478
I am getting weather data from api source which gives me to much info. I only want city name first, then onto try get current temp of that city, i pass into api.
i using https://jsonformatter.org/json-to-dart to format into classes.
I just trying to get city name first from json. but getting null return. It is due to City is a MAP???
name = city
i am getting all the data back with 200 response
jsonclass.dart
code:import 'dart:convert';
import 'package:http/http.dart' as http;
import 'apikey.dart';
import 'jasonclasscity.dart';
class WeatherApiException implements Exception {
const WeatherApiException(this.message);
final String message;
}
void main() async {
String url =
'https://api.openweathermap.org/data/2.5/forecast?q=Palm%20Springs&units=imperial';
final httpUrl = Uri.parse('$url$appid');
final response = await http.get(httpUrl);
if (response.statusCode != 200) {
print(response.statusCode);
throw WeatherApiException('Error getting city: xxxxx');
}
print(response.statusCode);
var body = response.body;
print(response.body);
City city = City.fromJson(jsonDecode(body.toString()));
print(city.toString());
}
jsonclasscity.dart
class City {
// final int id;
final String name; //need this
// final Coord coord;
// final String country;
// final int population;
// final int timezone;
// final int sunrise;
// final int sunset;
City(
{
// required this.id,
required this.name
//required this.coord,
//required this.country,
//required this.population,
//required this.timezone,
//required this.sunrise,
//required this.sunset,
});
factory City.fromJson(Map<String, dynamic> json) {
return City(
name: json ["name"],
); // City
}
}
class Coord {
final double lat;
final double lon;
Coord({
required this.lat,
required this.lon,
});
}
class MainClass {
MainClass({
required this.temp, //need this
required this.feelsLike,
required this.tempMin,
required this.tempMax,
required this.pressure,
required this.seaLevel,
required this.grndLevel,
required this.humidity,
required this.tempKf,
});
final double temp;
final double feelsLike;
final double tempMin;
final double tempMax;
final int pressure;
final int seaLevel;
final int grndLevel;
final int humidity;
final double tempKf;
}
json api data back from call:
{"cod":"200","message":0,"cnt":40,"list":[{"dt":1662498000,"main":{"temp":107.73,"feels_like":106.95,"temp_min":107.73,"temp_max":110.3,"pressure":1009,"sea_level":1009,"grnd_level":995,"humidity":18,"temp_kf":-1.43},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":8.03,"deg":123,"gust":8.99},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-06 21:00:00"},{"dt":1662508800,"main":{"temp":108.37,"feels_like":107.17,"temp_min":108.37,"temp_max":109.33,"pressure":1009,"sea_level":1009,"grnd_level":994,"humidity":17,"temp_kf":-0.53},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":1},"wind":{"speed":7.38,"deg":129,"gust":6.78},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-07 00:00:00"},{"dt":1662519600,"main":{"temp":99.99,"feels_like":99.14,"temp_min":99.99,"temp_max":99.99,"pressure":1011,"sea_level":1011,"grnd_level":995,"humidity":24,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":4},"wind":{"speed":0.94,"deg":283,"gust":4.56},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-07 03:00:00"},{"dt":1662530400,"main":{"temp":95.72,"feels_like":95.07,"temp_min":95.72,"temp_max":95.72,"pressure":1013,"sea_level":1013,"grnd_level":997,"humidity":29,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":2},"wind":{"speed":0.25,"deg":324,"gust":3.56},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-07 06:00:00"},{"dt":1662541200,"main":{"temp":91.53,"feels_like":91.89,"temp_min":91.53,"temp_max":91.53,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":37,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":2.33,"deg":90,"gust":4.29},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-07 09:00:00"},{"dt":1662552000,"main":{"temp":87.82,"feels_like":89.73,"temp_min":87.82,"temp_max":87.82,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":47,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":1.9,"deg":95,"gust":3.31},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-07 12:00:00"},{"dt":1662562800,"main":{"temp":87.26,"feels_like":94.03,"temp_min":87.26,"temp_max":87.26,"pressure":1017,"sea_level":1017,"grnd_level":1000,"humidity":61,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":4.27,"deg":94,"gust":5.46},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-07 15:00:00"},{"dt":1662573600,"main":{"temp":94.55,"feels_like":100.96,"temp_min":94.55,"temp_max":94.55,"pressure":1016,"sea_level":1016,"grnd_level":1000,"humidity":45,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":5.3,"deg":103,"gust":6.13},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-07 18:00:00"},{"dt":1662584400,"main":{"temp":101.66,"feels_like":102.16,"temp_min":101.66,"temp_max":101.66,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":25,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":5.75,"deg":98,"gust":8.25},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-07 21:00:00"},{"dt":1662595200,"main":{"temp":102.78,"feels_like":101.17,"temp_min":102.78,"temp_max":102.78,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":20,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":6.42,"deg":117,"gust":7.74},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-08 00:00:00"},{"dt":1662606000,"main":{"temp":96.26,"feels_like":96.26,"temp_min":96.26,"temp_max":96.26,"pressure":1013,"sea_level":1013,"grnd_level":997,"humidity":30,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":5.26,"deg":117,"gust":6.46},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-08 03:00:00"},{"dt":1662616800,"main":{"temp":93.09,"feels_like":92.77,"temp_min":93.09,"temp_max":93.09,"pressure":1013,"sea_level":1013,"grnd_level":997,"humidity":33,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":2.75,"deg":280,"gust":3.29},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-08 06:00:00"},{"dt":1662627600,"main":{"temp":91.8,"feels_like":90.66,"temp_min":91.8,"temp_max":91.8,"pressure":1011,"sea_level":1011,"grnd_level":995,"humidity":32,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":4.63,"deg":296,"gust":5.26},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-08 09:00:00"},{"dt":1662638400,"main":{"temp":82.94,"feels_like":86.76,"temp_min":82.94,"temp_max":82.94,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":64,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":2.04,"deg":31,"gust":3.67},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-08 12:00:00"},{"dt":1662649200,"main":{"temp":86.65,"feels_like":91.22,"temp_min":86.65,"temp_max":86.65,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":57,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":4.79,"deg":111,"gust":5.73},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-08 15:00:00"},{"dt":1662660000,"main":{"temp":91.9,"feels_like":97.29,"temp_min":91.9,"temp_max":91.9,"pressure":1010,"sea_level":1010,"grnd_level":994,"humidity":48,"temp_kf":0},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03d"}],"clouds":{"all":38},"wind":{"speed":5.3,"deg":97,"gust":4.43},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-08 18:00:00"},{"dt":1662670800,"main":{"temp":99.64,"feels_like":102.29,"temp_min":99.64,"temp_max":99.64,"pressure":1007,"sea_level":1007,"grnd_level":991,"humidity":31,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"clouds":{"all":82},"wind":{"speed":6.49,"deg":103,"gust":7.18},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-08 21:00:00"},{"dt":1662681600,"main":{"temp":98.38,"feels_like":100.67,"temp_min":98.38,"temp_max":98.38,"pressure":1004,"sea_level":1004,"grnd_level":989,"humidity":32,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":91},"wind":{"speed":4.27,"deg":115,"gust":5.57},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-09 00:00:00"},{"dt":1662692400,"main":{"temp":94.01,"feels_like":96.22,"temp_min":94.01,"temp_max":94.01,"pressure":1005,"sea_level":1005,"grnd_level":989,"humidity":38,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":98},"wind":{"speed":0.43,"deg":302,"gust":2.59},"visibility":10000,"pop":0.08,"sys":{"pod":"n"},"dt_txt":"2022-09-09 03:00:00"},{"dt":1662703200,"main":{"temp":91.24,"feels_like":92.17,"temp_min":91.24,"temp_max":91.24,"pressure":1004,"sea_level":1004,"grnd_level":988,"humidity":39,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":98},"wind":{"speed":3.06,"deg":286,"gust":3.47},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-09 06:00:00"},{"dt":1662714000,"main":{"temp":81.39,"feels_like":83.91,"temp_min":81.39,"temp_max":81.39,"pressure":1006,"sea_level":1006,"grnd_level":990,"humidity":62,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":100},"wind":{"speed":4.63,"deg":62,"gust":6.29},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-09 09:00:00"},{"dt":1662724800,"main":{"temp":79,"feels_like":79,"temp_min":79,"temp_max":79,"pressure":1005,"sea_level":1005,"grnd_level":989,"humidity":71,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":100},"wind":{"speed":2.51,"deg":60,"gust":4.79},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-09 12:00:00"},{"dt":1662735600,"main":{"temp":80.55,"feels_like":83.55,"temp_min":80.55,"temp_max":80.55,"pressure":1006,"sea_level":1006,"grnd_level":990,"humidity":68,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":100},"wind":{"speed":3.8,"deg":64,"gust":5.48},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-09 15:00:00"},{"dt":1662746400,"main":{"temp":87.75,"feels_like":90.99,"temp_min":87.75,"temp_max":87.75,"pressure":1006,"sea_level":1006,"grnd_level":990,"humidity":51,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":100},"wind":{"speed":8.95,"deg":91,"gust":17.07},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-09 18:00:00"},{"dt":1662757200,"main":{"temp":83.46,"feels_like":87.93,"temp_min":83.46,"temp_max":83.46,"pressure":1005,"sea_level":1005,"grnd_level":989,"humidity":65,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":100},"wind":{"speed":9.75,"deg":102,"gust":15.77},"visibility":10000,"pop":0.16,"sys":{"pod":"d"},"dt_txt":"2022-09-09 21:00:00"},{"dt":1662768000,"main":{"temp":80.98,"feels_like":84.6,"temp_min":80.98,"temp_max":80.98,"pressure":1004,"sea_level":1004,"grnd_level":988,"humidity":70,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":9.42,"deg":79,"gust":24.18},"visibility":10000,"pop":0.37,"rain":{"3h":1.03},"sys":{"pod":"d"},"dt_txt":"2022-09-10 00:00:00"},{"dt":1662778800,"main":{"temp":76.71,"feels_like":78.13,"temp_min":76.71,"temp_max":76.71,"pressure":1004,"sea_level":1004,"grnd_level":988,"humidity":86,"temp_kf":0},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":10.13,"deg":16,"gust":15.84},"visibility":3866,"pop":0.88,"rain":{"3h":8.03},"sys":{"pod":"n"},"dt_txt":"2022-09-10 03:00:00"},{"dt":1662789600,"main":{"temp":77.85,"feels_like":79.41,"temp_min":77.85,"temp_max":77.85,"pressure":1005,"sea_level":1005,"grnd_level":989,"humidity":87,"temp_kf":0},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":8.9,"deg":67,"gust":15.05},"visibility":2520,"pop":1,"rain":{"3h":13.28},"sys":{"pod":"n"},"dt_txt":"2022-09-10 06:00:00"},{"dt":1662800400,"main":{"temp":76.24,"feels_like":78.08,"temp_min":76.24,"temp_max":76.24,"pressure":1005,"sea_level":1005,"grnd_level":988,"humidity":96,"temp_kf":0},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":8.21,"deg":85,"gust":12.82},"visibility":284,"pop":0.99,"rain":{"3h":14.58},"sys":{"pod":"n"},"dt_txt":"2022-09-10 09:00:00"},{"dt":1662811200,"main":{"temp":73.42,"feels_like":74.88,"temp_min":73.42,"temp_max":73.42,"pressure":1007,"sea_level":1007,"grnd_level":991,"humidity":94,"temp_kf":0},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":6.73,"deg":89,"gust":12.12},"visibility":519,"pop":1,"rain":{"3h":18.39},"sys":{"pod":"n"},"dt_txt":"2022-09-10 12:00:00"},{"dt":1662822000,"main":{"temp":74.17,"feels_like":75.52,"temp_min":74.17,"temp_max":74.17,"pressure":1010,"sea_level":1010,"grnd_level":993,"humidity":90,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":4.45,"deg":82,"gust":7.65},"visibility":853,"pop":1,"rain":{"3h":2.28},"sys":{"pod":"d"},"dt_txt":"2022-09-10 15:00:00"},{"dt":1662832800,"main":{"temp":76.66,"feels_like":77.92,"temp_min":76.66,"temp_max":76.66,"pressure":1011,"sea_level":1011,"grnd_level":994,"humidity":83,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":99},"wind":{"speed":5.95,"deg":98,"gust":10.58},"visibility":4886,"pop":1,"rain":{"3h":1.15},"sys":{"pod":"d"},"dt_txt":"2022-09-10 18:00:00"},{"dt":1662843600,"main":{"temp":79.83,"feels_like":79.83,"temp_min":79.83,"temp_max":79.83,"pressure":1010,"sea_level":1010,"grnd_level":994,"humidity":73,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":99},"wind":{"speed":4.59,"deg":98,"gust":9.37},"visibility":10000,"pop":0.75,"rain":{"3h":1.11},"sys":{"pod":"d"},"dt_txt":"2022-09-10 21:00:00"},{"dt":1662854400,"main":{"temp":80.85,"feels_like":84.36,"temp_min":80.85,"temp_max":80.85,"pressure":1009,"sea_level":1009,"grnd_level":993,"humidity":70,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":99},"wind":{"speed":5.14,"deg":108,"gust":7.31},"visibility":10000,"pop":0.84,"rain":{"3h":1.43},"sys":{"pod":"d"},"dt_txt":"2022-09-11 00:00:00"},{"dt":1662865200,"main":{"temp":79.84,"feels_like":79.84,"temp_min":79.84,"temp_max":79.84,"pressure":1011,"sea_level":1011,"grnd_level":994,"humidity":72,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":3.36,"deg":117,"gust":5.55},"visibility":10000,"pop":0.83,"rain":{"3h":0.84},"sys":{"pod":"n"},"dt_txt":"2022-09-11 03:00:00"},{"dt":1662876000,"main":{"temp":79.72,"feels_like":79.72,"temp_min":79.72,"temp_max":79.72,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":73,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"clouds":{"all":98},"wind":{"speed":1.03,"deg":40,"gust":3.29},"visibility":10000,"pop":0.75,"rain":{"3h":0.16},"sys":{"pod":"n"},"dt_txt":"2022-09-11 06:00:00"},{"dt":1662886800,"main":{"temp":79.48,"feels_like":79.48,"temp_min":79.48,"temp_max":79.48,"pressure":1012,"sea_level":1012,"grnd_level":995,"humidity":72,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":95},"wind":{"speed":2.1,"deg":84,"gust":4.72},"visibility":10000,"pop":0.05,"sys":{"pod":"n"},"dt_txt":"2022-09-11 09:00:00"},{"dt":1662897600,"main":{"temp":79.5,"feels_like":79.5,"temp_min":79.5,"temp_max":79.5,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":73,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":96},"wind":{"speed":3.47,"deg":104,"gust":4.63},"visibility":10000,"pop":0.08,"sys":{"pod":"n"},"dt_txt":"2022-09-11 12:00:00"},{"dt":1662908400,"main":{"temp":79.7,"feels_like":79.7,"temp_min":79.7,"temp_max":79.7,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":73,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":99},"wind":{"speed":3.13,"deg":96,"gust":4.18},"visibility":10000,"pop":0.05,"sys":{"pod":"d"},"dt_txt":"2022-09-11 15:00:00"},{"dt":1662919200,"main":{"temp":84.87,"feels_like":88.41,"temp_min":84.87,"temp_max":84.87,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":58,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"clouds":{"all":84},"wind":{"speed":4.52,"deg":94,"gust":5.99},"visibility":10000,"pop":0.03,"sys":{"pod":"d"},"dt_txt":"2022-09-11 18:00:00"}],"city":{"id":5380668,"name":"Palm Springs","coord":{"lat":33.8303,"lon":-116.5453},"country":"US","population":44552,"timezone":-25200,"sunrise":1662470615,"sunset":1662516349}}
I've not dug into your code, but I can pretty much guarantee that your issue will be down to you not querying the correct nested level of the JSON Object. Looking at the JSON data you get back from the API call, within the main Object, there is then a 'City' Object, which has the key 'name' against it. Make sure you're querying the correct level.
The structure you need to get the data you need is essentially the following pseudo code: JsonObjectFromAPIResponse.get("city").get("name")
Just translate this into what you're doing. Debug it step by step. You're over complicating it in your code example before you've got the basics working. Forget about the City Objects and Factories you've been creating, just get it working in a single file, then refactor it after.
thanks for response. i was able to figure out the correct way to walk down the json tree. i was just coding the format incorrect.
this worked
print('justcity name:');
// printout Palm SPrings ok.
print(data['city']['name']);
//print(justList[0]);
final justTemp = data['list'][0]['main']['temp'];
print('justTemp:');
this json tool help me understand the json tree better for my very long and complex json response from host api.
https://jsonpathfinder.com/

How to get value from Json List - flutter

I have this code where i get json data into a list in flutter but i don't really know how to get the particular data i want like the value
main.dart
Future<String> loadDataFromJson() async {
return await rootBundle.loadString("assets/categories.json");
}
Future loadData() async {
String jString = await loadDataFromJson();
final jRes = json.decode(jString) as List;
List<Category> datas = jRes.map((e) => Category.fromJson(e)).toList();
print(datas);
}
#override
void initState() {
super.initState();
loadData();
}
Here I printed the data and it gave me this I/flutter ( 6111): [Instance of 'Category', Instance of 'Category', Instance of 'Category', Instance of 'Category']
Models
class Category {
final String catId;
final String catName;
Category({this.catId, this.catName});
factory Category.fromJson(Map<String, dynamic> json) {
return Category(catId: json['cat_id'], catName: json['category']);
}
}
my json is something like this but there are multiple
{
"category": "Design & Creativity",
"cat_id": "1",
"cat_suncategory": [
{
"sub_name": "Ads",
"sub_image": "https://images.unsplash.com/photo-1589838017489-9198a27bd040?ixid=MXwxMjA3fDB8MHxzZWFyY2h8Mnx8YWR2ZXJ0aXNlbWVudHxlbnwwfHwwfA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"
}
]
}
So please how do i get the value i want
I cannot understand your problem but this may help you;
If your json values in 'jRes', you can do
String myCategory = jRes["category"];
String subName = jRes["cat_suncategory"][0]["sub_name"];
String subImage = jRes["cat_suncategory"][0]["sub_image"];
Because of using '[0]' is; the 'cat_suncategory' is an array and you should take first element of it, it means [0].

Angular4 - why does custom toJSON() only get called on new objects?

I have this code. Notice that the serialization is simply renaming the template_items property to template_items_attributes:
export class Template {
constructor(
) {}
public id: string
public account_id: string
public name: string
public title: string
public info: string
public template_items: Array<TemplateItem>
toJSON(): ITemplateSerialized {
return {
id: this.id,
account_id: this.account_id,
name: this.name,
title: this.title,
info: this.info,
template_items_attributes: this.template_items
}
}
}
export interface ITemplateSerialized {
id: string,
account_id: string,
name: string,
title: string,
info: string,
template_items_attributes: Array<TemplateItem>
}
Creating an object locally works fine and stringify calls the toJSON() method.
However, once I send that object to the API:
private newTemplate(name: string): Template {
let template = new Template();
template.name = name;
template.account_id = this._userService.user.account_id;
// next 5 lines are for testing that toJSON() is called on new obj
let item = new TemplateItem();
item.content = "Test"
template.template_items.push(item);
let result = JSON.stringify(template);
console.log('ready', result); // SHOWS the property changes
return template;
}
postTemplate(name: string): Observable<any> {
return this._authService.post('templates', JSON.stringify(this.newTemplate(name)))
.map((response) => {
return response.json();
});
}
It is saved and returned, but from that point on when I stringify and save again it does NOT call toJSON().
patchTemplate(template: Template): Observable<any> {
console.log('patching', JSON.stringify(template)); // DOES NOT CHANGE!
return this._authService.patch('templates' + `/${template.id}`, JSON.stringify(template))
.map((response) => {
return response.json();
});
}
Why does toJSON() only work on new objects?
In fact, your question has nothing to do with Angular or Typescript, it's just some JavaScript and the logic of how serialization work and why do we serialize objects.
I send that object to the API, save and return it
When you return an "object" from an API, you're returning a string which you parse as a JSON serialized object. Then you get a plain JavaScript object, not an instance of your class.
Object prototype in JavaScript does not have toJSON method, and even if it had, it's not the method you've written inside the Template class, so it won't be called.
You don't even need a server call to replicate this, just do
const obj = JSON.parse(JSON.stringify(new Template()))
obj.toJSON // undefined
And you'll see that obj is not an instance of Template. It's simply an object which simply happens to have all the fields as your original object made as a Template instance, but it's not an instance of that class.

Mapping JSON into Class Objects

I am trying to map my JSON file into a class object, and then update the cards based on the newly received JSON.
My JSON structure is like this
{
"$class": "FirstCard",
"id": "1",
"description": "I am card number one",
"Role": "attack",
"score": 0,
"tag": [
"string"
],................}
my Class looks like this:
class CardInfo {
//Constructor
String id;
String description;
String role;
int score;
}
How can I map the values in my JSON file into the fields of objects created from CardInfo class?
Update
the following trial prints null at ci.description, does this mean the object was never created ?
const jsonCodec = const JsonCodec
_loadData() async {
var url = 'myJsonURL';
var httpClient = createHttpClient();
var response =await httpClient.get(url);
print ("response" + response.body);
Map cardInfo = jsonCodec.decode(response.body);
var ci = new CardInfo.fromJson(cardInfo);
print (ci.description); //prints null
}
Update2
Printing cardInfo gives the following:
{$class: FirstCard, id: 1, description: I am card number one,........}
Note that it resembles the original JSON but without the double quotes on string values.
class CardInfo {
//Constructor
String id;
String description;
String role;
int score;
CardInfo.fromJson(Map json) {
id = json['id'];
description = json['description'];
role = json['Role'];
score = json['score'];
}
}
var ci = new CardInfo.fromJson(myJson);
You can use source generation tools like https://github.com/dart-lang/source_gen https://pub.dartlang.org/packages/json_serializable to generate the serialization and deserialization code for you.
If you prefer using immutable classes https://pub.dartlang.org/packages/built_value is a good bet.
If you want to get your JSON from a url do as follows:
import 'dart:convert';
_toObject() async {
var url = 'YourJSONurl';
var httpClient = createHttpClient();
var response =await httpClient.get(url);
Map cardInfo = JSON.decode(response.body);
var ci = new CardInfo.fromJson(cardInfo);
}
Please refer to the main answer if you want to know how to setup your class so that your JSON fields can be mapped to it. It is very helpful.
I created some useful library for this using reflection called json_parser which is available at pub.
https://github.com/gi097/json_parser
You can add the following to your dependencies.yaml:
dependencies:
json_parser: 0.1.1
build_runner: 0.8.3
Then the json can be parsed using:
DataClass instance = JsonParser.parseJson<DataClass>(json);
Follow the README.md for more instructions.
The best solution I've found is this medium post
Which converts the Json to dart very easily
import 'package:json_annotation/json_annotation.dart';
part 'post_model.g.dart';
#JsonSerializable()
class PostModel {
int userId;
int id;
String title;
String body;
PostModel(this.userId, this.id, this.title, this.body);
factory PostModel.fromJson(Map<String, dynamic> json) => _$PostModelFromJson(json);
Map<String, dynamic> toJson() => _$PostModelToJson(this);
}
You can generate them if you don't want to create them manually.
Add dependecies to pubspec.yaml:
dependencies:
json_annotation: ^4.0.0
dev_dependencies:
build_it: ^0.2.5
json_serializable: ^4.0.2
Create configurtion file my_classes.yaml:
---
format:
name: build_it
generator:
name: build_it:json
---
checkNullSafety: true
classes:
- name: CardInfo
fields:
- { name: id, type: String? }
- { name: description, type: String? }
- { name: role, type: String?, jsonKey: { name: Role } }
- { name: score, type: int? }
- { name: tag, type: List<String>, jsonKey: { defaultValue: [] } }
Run build process:
dart run build_runner build
Generated code my_classes.g.dart:
// GENERATED CODE - DO NOT MODIFY BY HAND
import 'package:json_annotation/json_annotation.dart';
part 'my_classes.g.g.dart';
// **************************************************************************
// build_it: build_it:json
// **************************************************************************
#JsonSerializable()
class CardInfo {
CardInfo(
{this.id, this.description, this.role, this.score, required this.tag});
/// Creates an instance of 'CardInfo' from a JSON representation
factory CardInfo.fromJson(Map<String, dynamic> json) =>
_$CardInfoFromJson(json);
String? id;
String? description;
#JsonKey(name: 'Role')
String? role;
int? score;
#JsonKey(defaultValue: [])
List<String> tag;
/// Returns a JSON representation of the 'CardInfo' instance.
Map<String, dynamic> toJson() => _$CardInfoToJson(this);
}
Now you can use them.
this pkg can help you convert JSON to a class instance. https://www.npmjs.com/package/class-converter
import { property, toClass } from 'class-convert';
class UserModel {
#property('i')
id: number;
#property()
name: string;
}
const userRaw = {
i: 1234,
name: 'name',
};
// use toClass to convert plain object to class
const userModel = toClass(userRaw, UserModel);
// you will get a class, just like below one
{
id: 1234,
name: 'name',
}

JSON serialization and deserialization to objects in Flutter

Since Flutter took out dart: mirrors off of its SDK, it's no longer possible to use libraries like dartson for JSON to object serialization/deserialization. However I've read that built_value is another way of achieving a similar purpose. I couldn't find any good examples on how to implement it as it contains a significant amount of boilerplate code. Can someone give me an example? For instance, this is the JSON I'm trying to serialize to objects:
{
"name":"John",
"age":30,
"cars": [
{ "name":"Ford", "models":[ "Fiesta", "Focus", "Mustang" ] },
{ "name":"BMW", "models":[ "320", "X3", "X5" ] },
{ "name":"Fiat", "models":[ "500", "Panda" ] }
]
}
I was hoping for more details from the answers provided. Even though they were good suggestions, they were too general for me to understand. So after doing my own research, I'll share my implementation to the above JSON example I provided in hope that it would save someone's else's time. So here are the steps I followed:
In my Flutter project, first I imported the following libraries:
dependencies:
built_value: ^1.0.1
built_collection: ^1.0.0
dev_dependencies:
build_runner: ^0.3.0
built_value_generator:^1.0.1
I created a folder called tool. In it, I put 2 files: build.dart and watch.dart. There implementations of those files are show below
build.dart
// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
import 'dart:async';
import 'package:build_runner/build_runner.dart';
import 'package:built_value_generator/built_value_generator.dart';
import 'package:source_gen/source_gen.dart';
/// Example of how to use source_gen with [BuiltValueGenerator].
///
/// Import the generators you want and pass them to [build] as shown,
/// specifying which files in which packages you want to run against.
Future main(List<String> args) async {
await build(
new PhaseGroup.singleAction(
new GeneratorBuilder([new BuiltValueGenerator()]),
new InputSet('built_value_example', const [
'lib/model/*.dart',
'lib/*.dart',
])),
deleteFilesByDefault: true);
}
watch.dart
// Copyright (c) 2016, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
import 'dart:async';
import 'package:build_runner/build_runner.dart';
import 'package:built_value_generator/built_value_generator.dart';
import 'package:source_gen/source_gen.dart';
/// Example of how to use source_gen with [BuiltValueGenerator].
///
/// This script runs a watcher that continuously rebuilds generated source.
///
/// Import the generators you want and pass them to [watch] as shown,
/// specifying which files in which packages you want to run against.
Future main(List<String> args) async {
watch(
new PhaseGroup.singleAction(
new GeneratorBuilder([new BuiltValueGenerator()]),
new InputSet('built_value_example', const [
'lib/model/*.dart',
'lib/*.dart'])),
deleteFilesByDefault: true);
}
I created a serializers.dart file that would serialize my json string to my custom dart object, and my model object person.dart
serializers.dart
library serializers;
import 'package:built_collection/built_collection.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'model/person.dart';
part 'serializers.g.dart';
Serializers serializers = (
_$serializers.toBuilder()..addPlugin(new StandardJsonPlugin())
).build();
person.dart
library person;
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
part 'person.g.dart';
abstract class Person implements Built<Person, PersonBuilder> {
String get name;
int get age;
BuiltList<Car> get cars;
Person._();
factory Person([updates(PersonBuilder b)]) = _$Person;
static Serializer<Person> get serializer => _$personSerializer;
}
abstract class Car implements Built<Car, CarBuilder> {
String get name;
BuiltList<String> get models;
Car._();
factory Car([updates(CarBuilder b)]) = _$Car;
static Serializer<Car> get serializer => _$carSerializer;
}
After creating the 4 files above, it will show some compiler errors. Don't mind them yet. This is because the build.dart file hasn't been run yet. So in this step, run build.dart. If you're using Webstorm, simply right click on build.dart and hit "Run build.dart". This will create 2 files: "person.g.dart" and "serializers.g.dart". If you notice carefully, in our build.dart file, we put 'lib/model/.dart' and 'lib/.dart'. The build knows where to look for those files by going through the paths specified and looks for files which have part "something" included. So it's important to keep that line in those files before running the build.dart file
Finally, now I can use the serializer in my main.dart file to serialize the json string to my custom dart object class Person. In my main.dart, I added the following code in initState()
main.dart
Person _person;
#override
void initState() {
super.initState();
String json = "{"
"\"name\":\"John\",\"age\":30,\"cars\": "
"["
"{ \"name\":\"Ford\", \"models\":[ \"Fiesta\", \"Focus\", \"Mustang\" ] },"
"{ \"name\":\"BMW\", \"models\":[ \"320\", \"X3\", \"X5\" ] },"
"{ \"name\":\"Fiat\", \"models\":[ \"500\", \"Panda\" ] }"
"]}";
setState(() {
_person = serializers.deserializeWith(
Person.serializer, JSON.decode(json));
});
}
My sample project is also available on Github Built value sample project
json_serialization
This package by the Dart Team generates everything needed for the fromJson constructor and toJson method in a seprate file.
Dependencies
Add the following dependencies:
dependencies:
json_annotation: ^2.0.0
dev_dependencies:
build_runner: ^1.0.0
json_serializable: ^2.0.0
Model class
Adapt your model class to have the following parts:
import 'package:json_annotation/json_annotation.dart';
// will be generated later
part 'person.g.dart';
#JsonSerializable()
class Person {
Person(this.name, this.age);
final String name;
final int age;
factory Person.fromJson(Map<String, dynamic> json) =>
_$PersonFromJson(json);
Map<String, dynamic> toJson() => _$PersonToJson(this);
}
Generate code
Generate the person.g.dart file from the terminal:
flutter packages pub run build_runner build
Use it
Then use it like this:
JSON → object
String rawJson = '{"name":"Mary","age":30}';
Map<String, dynamic> map = jsonDecode(rawJson);
Person person = Person.fromJson(map);
Object → JSON
Person person = Person('Mary', 30);
Map<String, dynamic> map = person.toJson();
String rawJson = jsonEncode(map);
Notes
In a Dart project use pub run build_runner build.
See this answer for more ways to serialize JSON.
From the Dart web site:
The dart:convert library provides a JsonCodec class, which you can use to convert simple types (map, list, int, num, string) automatically from a and to a JSON string. The two key static methods are JSON.encode(object) and JSON.decode(string).
Decoding example:
import 'dart:convert';
...
Map<String, dynamic> parsedMap = JSON.decode(json);
print(parsedMap['name']); // John
print(parsedMap['age']); // 30
Encoding example:
Map<String, dynamic> mapData = <String, dynamic>{ 'hello': 'world!' };
String jsonData = JSON.encode(mapData); // convert map to String
If you want to have your JSON inflate into custom Dart classes instead of a tree of primitive objects, Hadrien's answer should point you in the right direction, but I just wanted to leave this here in case anyone else is trying to get basic JSON serialization/deserialization working.
You can use Jaguar Serializer, it is easy to start and work perfectly for Flutter, or Server and Web dev.
https://github.com/Jaguar-dart/jaguar_serializer
You should prepare a configuration file for Built_value that will parse you dart source and generate the .g.dart. Once there are ready json serialisation is automatic. You can generate those files once or using a watch command.
Those file will be added at the same level than the source and the dart command
part of data;
to be seen as the same Class.
Here's the config I'm using with my Flutter project :
import 'dart:async';
import 'package:build_runner/build_runner.dart';
import 'package:built_value_generator/built_value_generator.dart';
import 'package:source_gen/source_gen.dart';
Future main(List<String> args) async {
await build(
new PhaseGroup.singleAction(
new GeneratorBuilder([
new BuiltValueGenerator(),
]),
new InputSet('flutter_project', const ['lib/data/*.dart'])),
deleteFilesByDefault: true);
}
You may find useful to read all the posts by David Morgan to understand the benefits. It need some time to turn your mind around but it's a very good pattern.
https://medium.com/dartlang/darts-built-value-for-immutable-object-models-83e2497922d4
https://medium.com/dartlang/darts-built-value-for-serialization-f5db9d0f4159
The trick is to understand how sourcegen parse and then enrich your classes by adding a lot of behaviors like Builders and Serializers.
1) first put json code to any convert website ex:
[JSON to Darthttps://javiercbk.github.io ›][1]
it will give like this output
class Autogenerated {
int? code;
List<Result>? result;
String? status;
Autogenerated({this.code, this.result, this.status});
Autogenerated.fromJson(Map<String, dynamic> json) {
code = json['code'];
if (json['result'] != null) {
result = <Result>[];
json['result'].forEach((v) {
result!.add(new Result.fromJson(v));
});
}
status = json['status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['code'] = this.code;
if (this.result != null) {
data['result'] = this.result!.map((v) => v.toJson()).toList();
}
data['status'] = this.status;
return data;
}
}
class Result {
int? id;
int? projectId;
String? projectName;
int? userId;
String? userName;
Result(
{this.id, this.projectId, this.projectName, this.userId, this.userName});
Result.fromJson(Map<String, dynamic> json) {
id = json['id'];
projectId = json['project_id'];
projectName = json['project_name'];
userId = json['user_id'];
userName = json['user_name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['project_id'] = this.projectId;
data['project_name'] = this.projectName;
data['user_id'] = this.userId;
data['user_name'] = this.userName;
return data;
}
}
--------------------------------------------------------------------------------------
and change that code like this format for easy use
***get_client.dart***
import 'package:json_annotation/json_annotation.dart';
part 'get_client.g.dart';
#JsonSerializable(
explicitToJson: true,
)
class ClientModel {
#JsonKey(name: "address1")
String? address1;
#JsonKey(name: "city")
int? city;
#JsonKey(name: "city_name")
String? cityName;
#JsonKey(name: "country")
int? country;
#JsonKey(name: "country_name")
String? countryName;
#JsonKey(name: "email")
String? email;
#JsonKey(name: "first_name")
String? firstName;
#JsonKey(name: "gender")
String? gender;
#JsonKey(name: "id")
int? id;
#JsonKey(name: "last_name")
String? lastName;
#JsonKey(name: "mobile_no")
String? mobileNo;
#JsonKey(name: "password")
String? password;
#JsonKey(name: "pincode")
String? pincode;
#JsonKey(name: "role")
int? role;
#JsonKey(name: "role_name")
String? roleName;
#JsonKey(name: "state")
int? state;
#JsonKey(name: "state_name")
String? stateName;
ClientModel(
{this.address1,
this.city,
this.cityName,
this.country,
this.countryName,
this.email,
this.firstName,
this.gender,
this.id,
this.lastName,
this.mobileNo,
this.password,
this.pincode,
this.role,
this.roleName,
this.state,
this.stateName});
factory ClientModel.fromJson(Map<String, dynamic> map) =>
_$ClientModelFromJson(map);
Map<String, dynamic> toJson() => _$ClientModelToJson(this);
}
-------------------------------------------------------------------
[1]: https://%20JSON%20to%20Darthttps://javiercbk.github.io%20%E2%80%BA
after run build runner cmd in terminal
***flutter pub run build_runner build***
then it will create the following output file
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'get_client.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ClientModel _$ClientModelFromJson(Map<String, dynamic> json) => ClientModel(
address1: json['address1'] as String?,
city: json['city'] as int?,
cityName: json['city_name'] as String?,
country: json['country'] as int?,
countryName: json['country_name'] as String?,
email: json['email'] as String?,
firstName: json['first_name'] as String?,
gender: json['gender'] as String?,
id: json['id'] as int?,
lastName: json['last_name'] as String?,
mobileNo: json['mobile_no'] as String?,
password: json['password'] as String?,
pincode: json['pincode'] as String?,
role: json['role'] as int?,
roleName: json['role_name'] as String?,
state: json['state'] as int?,
stateName: json['state_name'] as String?,
);
Map<String, dynamic> _$ClientModelToJson(ClientModel instance) =>
<String, dynamic>{
'address1': instance.address1,
'city': instance.city,
'city_name': instance.cityName,
'country': instance.country,
'country_name': instance.countryName,
'email': instance.email,
'first_name': instance.firstName,
'gender': instance.gender,
'id': instance.id,
'last_name': instance.lastName,
'mobile_no': instance.mobileNo,
'password': instance.password,
'pincode': instance.pincode,
'role': instance.role,
'role_name': instance.roleName,
'state': instance.state,
'state_name': instance.stateName,
};
after we can use like this in repository file
static Future<dynamic> getAllClients(int id) async {
String url = "${HttpUrls.clientList}/${0}";
Response response = await dio.get(url);
if (response.statusCode == 200) {
List<ClientModel> clientLists = (response.data['result'] as List)
.map((eachItem) => ClientModel.fromJson(eachItem))
.toList();
print(clientLists.toString());
if (clientLists.isNotEmpty) {
return clientLists;
}
} else {
BaseResponse baseResponse =
BaseResponse.fromJson(response.data as Map<String, dynamic>);
return baseResponse;
}
}