How to parse a complex JSON file in Flutter - json

I'm having a really complex JSON file to parse:
{
"adult": false,
"backdrop_url": "https://image.tmdb.org/t/p/w500/gLbBRyS7MBrmVUNce91Hmx9vzqI.jpg",
"belongs_to_collection": {
"id": 230,
"name": "The Godfather Collection",
"poster_url": "https://image.tmdb.org/t/p/w200/sSbkKCHtIEakht5rnEjrWeR2LLG.jpg",
"backdrop_url": "https://image.tmdb.org/t/p/w500/3WZTxpgscsmoUk81TuECXdFOD0R.jpg"
},
"budget": 13000000,
"genres": [
"Drama",
"Crime"
],
"homepage": null,
"id": 240,
"imdb_id": "tt0071562",
"original_language": "en",
"original_title": "The Godfather: Part II",
"overview": "In the continuing saga of the Corleone crime family, a young Vito Corleone grows up in Sicily and in 1910s New York. In the 1950s, Michael Corleone attempts to expand the family business into Las Vegas, Hollywood and Cuba.",
"popularity": 17.578,
"poster_url": "https://image.tmdb.org/t/p/w200/bVq65huQ8vHDd1a4Z37QtuyEvpA.jpg",
"production_companies": [
{
"id": 4,
"logo_url": "https://image.tmdb.org/t/p/w200/fycMZt242LVjagMByZOLUGbCvv3.png",
"name": "Paramount",
"origin_country": "US"
},
{
"id": 536,
"logo_url": null,
"name": "The Coppola Company",
"origin_country": ""
}
],
"production_countries": [
{
"iso_3166_1": "US",
"name": "United States of America"
}
],
"release_date": "1974-12-20",
"revenue": 102600000,
"runtime": 200,
"spoken_languages": [
{
"iso_639_1": "en",
"name": "English"
},
{
"iso_639_1": "it",
"name": "Italiano"
},
{
"iso_639_1": "la",
"name": "Latin"
},
{
"iso_639_1": "es",
"name": "EspaƱol"
}
],
"status": "Released",
"tagline": "I don't feel I have to wipe everybody out, Tom. Just my enemies.",
"title": "The Godfather: Part II",
"video": false,
"vote_average": 8.5,
"vote_count": 4794
}
And this is my class for parsing:
class movieDetails {
bool? adult;
String? backdropUrl;
Null? belongsToCollection;
int? budget;
List<String>? genres;
Null? homepage;
int? id;
String? imdbId;
String? originalLanguage;
String? originalTitle;
String? overview;
double? popularity;
String? posterUrl;
List<ProductionCompanies>? productionCompanies;
List<ProductionCountries>? productionCountries;
String? releaseDate;
int? revenue;
int? runtime;
List<SpokenLanguages>? spokenLanguages;
String? status;
String? tagline;
String? title;
bool? video;
double? voteAverage;
int? voteCount;
movieDetails(
{this.adult,
this.backdropUrl,
this.belongsToCollection,
this.budget,
this.genres,
this.homepage,
this.id,
this.imdbId,
this.originalLanguage,
this.originalTitle,
this.overview,
this.popularity,
this.posterUrl,
this.productionCompanies,
this.productionCountries,
this.releaseDate,
this.revenue,
this.runtime,
this.spokenLanguages,
this.status,
this.tagline,
this.title,
this.video,
this.voteAverage,
this.voteCount});
movieDetails.fromJson(Map<String, dynamic> json) {
adult = json['adult'];
backdropUrl = json['backdrop_url'];
belongsToCollection = json['belongs_to_collection'];
budget = json['budget'];
genres = json['genres'].cast<String>();
homepage = json['homepage'];
id = json['id'];
imdbId = json['imdb_id'];
originalLanguage = json['original_language'];
originalTitle = json['original_title'];
overview = json['overview'];
popularity = json['popularity'];
posterUrl = json['poster_url'];
if (json['production_companies'] != null) {
productionCompanies = <ProductionCompanies>[];
json['production_companies'].forEach((v) {
productionCompanies!.add(new ProductionCompanies.fromJson(v));
});
}
if (json['production_countries'] != null) {
productionCountries = <ProductionCountries>[];
json['production_countries'].forEach((v) {
productionCountries!.add(new ProductionCountries.fromJson(v));
});
}
releaseDate = json['release_date'];
revenue = json['revenue'];
runtime = json['runtime'];
if (json['spoken_languages'] != null) {
spokenLanguages = <SpokenLanguages>[];
json['spoken_languages'].forEach((v) {
spokenLanguages!.add(new SpokenLanguages.fromJson(v));
});
}
status = json['status'];
tagline = json['tagline'];
title = json['title'];
video = json['video'];
voteAverage = json['vote_average'];
voteCount = json['vote_count'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['adult'] = this.adult;
data['backdrop_url'] = this.backdropUrl;
data['belongs_to_collection'] = this.belongsToCollection;
data['budget'] = this.budget;
data['genres'] = this.genres;
data['homepage'] = this.homepage;
data['id'] = this.id;
data['imdb_id'] = this.imdbId;
data['original_language'] = this.originalLanguage;
data['original_title'] = this.originalTitle;
data['overview'] = this.overview;
data['popularity'] = this.popularity;
data['poster_url'] = this.posterUrl;
if (this.productionCompanies != null) {
data['production_companies'] =
this.productionCompanies!.map((v) => v.toJson()).toList();
}
if (this.productionCountries != null) {
data['production_countries'] =
this.productionCountries!.map((v) => v.toJson()).toList();
}
data['release_date'] = this.releaseDate;
data['revenue'] = this.revenue;
data['runtime'] = this.runtime;
if (this.spokenLanguages != null) {
data['spoken_languages'] =
this.spokenLanguages!.map((v) => v.toJson()).toList();
}
data['status'] = this.status;
data['tagline'] = this.tagline;
data['title'] = this.title;
data['video'] = this.video;
data['vote_average'] = this.voteAverage;
data['vote_count'] = this.voteCount;
return data;
}
}
class ProductionCompanies {
int? id;
String? logoUrl;
String? name;
String? originCountry;
ProductionCompanies({this.id, this.logoUrl, this.name, this.originCountry});
ProductionCompanies.fromJson(Map<String, dynamic> json) {
id = json['id'];
logoUrl = json['logo_url'];
name = json['name'];
originCountry = json['origin_country'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['logo_url'] = this.logoUrl;
data['name'] = this.name;
data['origin_country'] = this.originCountry;
return data;
}
}
class ProductionCountries {
String? iso31661;
String? name;
ProductionCountries({this.iso31661, this.name});
ProductionCountries.fromJson(Map<String, dynamic> json) {
iso31661 = json['iso_3166_1'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['iso_3166_1'] = this.iso31661;
data['name'] = this.name;
return data;
}
}
class SpokenLanguages {
String? iso6391;
String? name;
SpokenLanguages({this.iso6391, this.name});
SpokenLanguages.fromJson(Map<String, dynamic> json) {
iso6391 = json['iso_639_1'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['iso_639_1'] = this.iso6391;
data['name'] = this.name;
return data;
}
}
Since I'm getting this JSON from the internet, here's the fetching method:
Future<movieDetails> fetchDetails() async {
final response = await http.get(Uri.parse(url)); //url: just a string containing the website's URL
if (response.statusCode == 200){
return compute(parseDetails, response.body);
}
else{
throw Exception('Failed!');
}
}
Everything seems okay from here, but then I have literally no idea how to do the parseDetails function. How should I do it? This JSON file is too complex for me to handle.

Is there any reason you're using compute to parse the JSON file? The file you provided seems to have reasonable length and won't block the main isolate (unless the file is much bigger than what you provided, where compute might be appropriate)
Your code will be something like this (will parse the JSON response in the main isolate). For more details see the official documentation about JSON. Also a tip, follow the dart naming convention PascalCase for classes (MovieDetails instead of movieDetails)
Future<movieDetails> fetchDetails() async {
final response = await http.get(Uri.parse(url)); //url: just a string containing the website's URL
if (response.statusCode == 200){
Map<String, dynamic> movieDetailsMap = jsonDecode(response.body);
return movieDetails.fromJson(movieDetailsMap);
}
else{
throw Exception('Failed!');
}
}

movieDetails parseDetails(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return movieDetails.fromJson(parsed);
}

Related

Trying to convert Json to Dart but its giving me 3 errors

I am trying to convert JSON response to dart but over 3 error. I convert the Json from online website https://javiercbk.github.io/json_to_dart/
the errors says : The method 'toJson' isn't defined for the type 'List'.
Try correcting the name to the name of an existing method, or defining a method named 'toJson'.
the code :
class RedZoneModel {
bool? status;
List<Data>? data;
RedZoneModel({this.status, this.data});
RedZoneModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
if (json['data'] != null) {
data = <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;
if (this.data != null) {
data['data'] = this.data!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
int? id;
String? areaName;
Geojson? geojson;
String? createdAt;
String? updatedAt;
Data({this.id, this.areaName, this.geojson, this.createdAt, this.updatedAt});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
areaName = json['area_name'];
geojson = json['geojson'] != null ? new Geojson.fromJson(json['geojson']) : null;
createdAt = json['created_at'];
updatedAt = json['updated_at'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['area_name'] = this.areaName;
if (this.geojson != null) {
data['geojson'] = this.geojson!.toJson();
}
data['created_at'] = this.createdAt;
data['updated_at'] = this.updatedAt;
return data;
}
}
class Geojson {
String? type;
List<List>? coordinates;
Geojson({this.type, this.coordinates});
Geojson.fromJson(Map<String, dynamic> json) {
type = json['type'];
if (json['coordinates'] != null) {
coordinates = <List>[];
json['coordinates'].forEach((v) { coordinates!.add(new List.fromJson(v)); }); // ! Error at List.fromJson(v)
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['type'] = this.type;
if (this.coordinates != null) {
data['coordinates'] = this.coordinates!.map((v) => v.toJson()).toList(); // ! Error at v.toJson()
}
return data;
}
}
class Coordinates {
Coordinates({ }); // ! Error at Coordinates({ });
Coordinates.fromJson(Map<String, dynamic> json) {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
return data;
}
}
and this is the response :
{
"status": true,
"data": [
{
"id": 8,
"area_name": "Surian",
"geojson": {
"type": "Polygon",
"coordinates": [
[
[
-1.2453052,
460.8429751
],
[
-1.2200768,
460.9066456
],
[
-1.2564606,
460.9423423
],
[
-1.2940451,
460.8711205
],
[
-1.2453052,
460.8429751
],
[
-1.2940451,
460.8711205
],
[
-1.2453052,
460.8429751
]
]
]
},
"created_at": "2022-08-29T14:30:10.000000Z",
"updated_at": "2022-12-19T18:30:10.000000Z"
},
{
"id": 13,
"area_name": "test edit",
"geojson": {
"type": "Polygon",
"coordinates": [
[
[
123,
123
],
[
123,
123
],
[
123,
123
],
[
123,
123
],
[
123,
123
]
]
]
},
"created_at": "2022-08-29T15:43:35.000000Z",
"updated_at": "2022-12-20T08:28:00.000000Z"
}
]
}
Anyone have any suggestion?
You shouldn't really use online generators that convert JSON to Dart objects.
Instead, learn about json and serialization. You can use dart packages such as freezed and json_serializable to generate the encoding boilerplate for your JSON response.
Here is sample json to Dart object converter for your json response above:
class Data {
const Data({
required this.id,
required this.area_name,
required this.geojson,
required this.created_at,
required this.updated_at,
});
factory Data.fromJson(Map<String, dynamic> json) => Data(
id: json['id'] as int,
area_name: json['area_name'] as String,
geojson: GeoJson.fromJson(json['geojson'] as Map<String, dynamic>),
created_at: DateTime.parse(json['created_at'] as String),
updated_at: DateTime.parse(json['updated_at'] as String),
);
final int id;
final String area_name;
final GeoJson geojson;
final DateTime created_at;
final DateTime updated_at;
}
class GeoJson {
const GeoJson({
required this.type,
required this.coordinates,
});
factory GeoJson.fromJson(Map<String, dynamic> json) => GeoJson(
type: json['type'] as String,
coordinates: (json['coordinates'] as List<dynamic>)
.map((e) => Polygon.fromJson(e as Map<String, dynamic>))
.toList(),
);
final String type;
final List<Polygon> coordinates;
}
class Polygon {
const Polygon({
required this.lat,
required this.lang,
});
/// Creates a Polygon from Json map
factory Polygon.fromJson(Map<String, dynamic> json) => Polygon(
lat: json['lat'] as num,
lang: json['lang'] as num,
);
final num lat;
final num lang;
}

How can i handle multiple data type for a same key from API in Flutter?

Let's explain my problem..
suppose have a json object like
from this picture i want to handle offer_price key
enter image description here
{
"product": [
{
"id": 1,
"price": 100.0,
"offer_price": 40
},
{
"id": 2,
"price": 80.0,
"offer_price": 10.50
},
{
"id": 3,
"price": 200.0,
"offer_price": "40.5"
},
{
"id": 4,
"price": 100.0,
"offer_price": null,
}
]
}
class Product {
int? id;
int? price;
// if you need the value as String
String? offerPriceAsString;
// Value as a double
double? offerPrice;
Product({this.id, this.price, this.offerPrice});
Product.fromJson(Map<String, dynamic> json) {
id = json['id'];
price = json['price'];
double.parse("1.0");
// Any value to String
offerPriceAsString = json['offer_price'].toString();
// String to Double
offerPrice = double.parse(json['offer_price'].toString());
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['price'] = price;
data['offer_price'] = offerPrice;
return data;
}
}
In the dart data model for offer_price field make its datatype as dynamic via which you'll be able to have a dynamic data in it as run type. And while consuming this in any place just check the runtimeType of the variable and use it by type casting or just using it with .toString().
eg class:
class Products {
Products({this.product});
Products.fromJson(Map<String, dynamic> json) {
if (json['product'] != null) {
product = <Product>[];
json['product'].forEach((v) {
product!.add(Product.fromJson(v));
});
}
}
List<Product>? product;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (this.product != null) {
data['product'] = this.product!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Product {
Product({this.id, this.price, this.offerPrice});
Product.fromJson(Map<String, dynamic> json) {
id = json['id'];
price = json['price'];
offerPrice = json['offer_price'];
}
int? id;
int? price;
dynamic? offerPrice;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = this.id;
data['price'] = this.price;
data['offer_price'] = this.offerPrice;
return data;
}
}
For consuming it just try:
Products products = List<Products>[];
//assign products = Products.fromJson(jsonData);
//using
products[i].offerPrice == null
? "null"
: products[i].offerPrice.runtimeType == String
? products[i].offerPrice.toString()
: products[i].offerPrice.runtimeType == Int
? int.parse(products[i].offerPrice)
: products[i].offerPrice.runtimeType == Double
? double.parse(products[i].offerPrice)
: ""

nested array list length returning all the list length

i have a complex json list in my flutter and i want to return the length of array object's nested list. but it is returning all the lists length.
my json list
{
"clients": [
{
"id": 58,
"name": "mmkmkmk",
"address": "mmakaka",
"tin_no": "9887665",
"status": "0",
"created_at": "2022-10-04T18:32:52.000000Z",
"updated_at": "2022-10-04T18:32:52.000000Z",
"phones": [
{
"id": 43,
"client_id": "58",
"supplier_id": null,
"company_id": null,
"phone_number": "987098709",
"email": "mmk#asd.fv",
"model": "Client",
"category": "Sales",
"created_at": "2022-10-04T18:32:52.000000Z",
"updated_at": "2022-10-04T18:32:52.000000Z"
}
]
},
{
"id": 59,
"name": "Konka33",
"address": "bole33",
"tin_no": "41231343",
"status": "1",
"created_at": "2022-10-04T18:33:54.000000Z",
"updated_at": "2022-10-04T18:33:54.000000Z",
"phones": [
{
"id": 44,
"client_id": "59",
"supplier_id": null,
"company_id": null,
"phone_number": "412313421",
"email": "i34#mail.com",
"model": "Client",
"category": "Manager",
"created_at": "2022-10-04T18:33:54.000000Z",
"updated_at": "2022-10-04T18:33:54.000000Z"
},
{
"id": 45,
"client_id": "59",
"supplier_id": null,
"company_id": null,
"phone_number": "-1780132721",
"email": "b34#bmail.com",
"model": "Client",
"category": "Sales",
"created_at": "2022-10-04T18:33:54.000000Z",
"updated_at": "2022-10-04T18:33:54.000000Z"
}
]
}
}
]
I want to display the selected index phones length.
I'm trying to do that by doing datasList[index].phones!.length but it's returning all of the length of the phones object from all clients phones object. not the index i wanted. how can i display the selected phones length?
client model
class Client {
List<Clients>? clients;
Client({required this.clients});
Client.fromJson(Map<String, dynamic> json) {
if (json['clients'] != null) {
clients = <Clients>[];
json['clients'].forEach((v) {
clients?.add(new Clients.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.clients != null) {
data['clients'] = this.clients!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Clients {
int? id;
String? name;
String? address;
int? tinNo;
int? status;
String? createdAt;
String? updatedAt;
List<Phones>? phones;
Clients(
{this.id,
this.name,
this.address,
this.tinNo,
this.status,
this.createdAt,
this.updatedAt,
this.phones});
Clients.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
address = json['address'];
tinNo = json['tin_no'];
status = json['status'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
if (json['phones'] != null) {
phones = <Phones>[];
json['phones'].forEach((v) {
phones!.add(new Phones.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['address'] = this.address;
data['tin_no'] = this.tinNo;
data['status'] = this.status;
data['created_at'] = this.createdAt;
data['updated_at'] = this.updatedAt;
if (this.phones != null) {
data['phones'] = this.phones!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Phones {
int? id;
int? clientId;
Null? supplierId;
Null? companyId;
int? phoneNumber;
String? email;
String? model;
String? category;
String? createdAt;
String? updatedAt;
Phones(
{this.id,
this.clientId,
this.supplierId,
this.companyId,
this.phoneNumber,
this.email,
this.model,
this.category,
this.createdAt,
this.updatedAt});
Phones.fromJson(Map<String, dynamic> json) {
id = json['id'];
clientId = json['client_id'];
supplierId = json['supplier_id'];
companyId = json['company_id'];
phoneNumber = json['phone_number'];
email = json['email'];
model = json['model'];
category = json['category'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['client_id'] = this.clientId;
data['supplier_id'] = this.supplierId;
data['company_id'] = this.companyId;
data['phone_number'] = this.phoneNumber;
data['email'] = this.email;
data['model'] = this.model;
data['category'] = this.category;
data['created_at'] = this.createdAt;
data['updated_at'] = this.updatedAt;
return data;
}
}

Advanced json parse in dart

I want to parse this Json. Now i am parsing Load as a class with 2 fields: id, and value. But what i want to is to parse it like Map<int, String>. When i am trying to cast the object, flutter gives me an error. for example:
Map<int, String> map = {
38 : "#1038 Fort Dodge, IA - Algona, IA",
39 : "#1039 Louisville, KY - Louisville, KY"
}
it is not the same as this question
{
"loads": {
"data": [
{
"id": 38,
"value": "#1038 Fort Dodge, IA - Algona, IA"
},
{
"id": 39,
"value": "#1039 Louisville, KY - Louisville, KY"
}
]
},
"date_ranges": {
"data": [
{
"id": "all_time",
"value": "All"
},
{
"id": "this_year",
"value": "This year"
}
]
}
}
You can create pojo class to parse your JSON
TestModel testModel = TestModel.fromJson(yourResponse);
class TestModel {
Loads loads;
Loads dateRanges;
TestModel({this.loads, this.dateRanges});
TestModel.fromJson(Map<String, dynamic> json) {
loads = json['loads'] != null ? new Loads.fromJson(json['loads']) : null;
dateRanges = json['date_ranges'] != null
? new Loads.fromJson(json['date_ranges'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.loads != null) {
data['loads'] = this.loads.toJson();
}
if (this.dateRanges != null) {
data['date_ranges'] = this.dateRanges.toJson();
}
return data;
}
}
class Loads {
List<Data> data;
Loads({this.data});
Loads.fromJson(Map<String, dynamic> json) {
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>();
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
int id;
String value;
Data({this.id, this.value});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['value'] = this.value;
return data;
}
}
class Data {
String id;
String value;
Data({this.id, this.value});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['value'] = this.value;
return data;
}
}
There was a issue you found because loads and date_ranges contain same child name data but there properties are different that's why your model class return error
Here I write a code for loads, please have a look
void main() {
Map<int, String> map = {
};
var mapdata = {
"loads": {
"data": [
{
"id": 50,
"value": "#1038 Fort Dodge, IA - Algona, IA"
},
{
"id": 39,
"value": "#1039 Louisville, KY - Louisville, KY"
}
]
},
"date_ranges": {
"data": [
{
"id": "all_time",
"value": "All"
},
{
"id": "this_year",
"value": "This year"
}
]
}
};
TestModel test = TestModel.fromJson(mapdata);
test.loads.data.forEach((e)=>map[e.id]=e.value);
print(map);
}
class TestModel {
Loads loads;
Loads dateRanges;
TestModel({this.loads, this.dateRanges});
TestModel.fromJson(Map<String, dynamic> json) {
loads = json['loads'] != null ? new Loads.fromJson(json['loads']) : null;
dateRanges = json['date_ranges'] != null
? new Loads.fromJson(json['date_ranges'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.loads != null) {
data['loads'] = this.loads.toJson();
}
if (this.dateRanges != null) {
data['date_ranges'] = this.dateRanges.toJson();
}
return data;
}
}
class Loads {
List<Data> data;
Loads({this.data});
Loads.fromJson(Map<String, dynamic> json) {
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>();
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
var id; // here changes the type
String value;
Data({this.id, this.value});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
value = json['value'];
}
Map<String, String> toJson() {
final Map<String, String> data = new Map<String, String>();
data['id'] = this.id;
data['value'] = this.value;
return data;
}
}
map result:
{50: #1038 Fort Dodge, IA - Algona, IA, 39: #1039 Louisville, KY - Louisville, KY}
N.B: Make your id dynamic with var type

Parsing Nested JSON Object Flutter

I'm trying to parse an object in JSON and I am able to do so successfully without the nested JSON object Opening Hours. I don't know why. Here is the json data:
{
"location": [
{
"id": 4,
"location_name": "PastryMan",
"cbd_products": "",
"phone": "1231231234",
"street_address": "535 7th Ave",
"location_logo": "https://.s3.amazonaws.com/location_logo/water.png",
"location_photo": "https://dispensaries.s3.amazonaws.com/location_photo/delta9.jpg",
"sponsored_location": "Yes",
"city": "New York",
"state": "New York",
"zip_Code": 10018,
"lat": 40.7538935555556,
"lng": -73.9883851111111,
"latlng": "(40.7770112244898, -74.2110798163265)",
"opening_hours": [
{
"day_of_week": "Tuesday",
"opening_time": "08:00:00",
"closing_time": "22:00:00"
},
{
"day_of_week": "Wednesday",
"opening_time": "08:00:00",
"closing_time": "22:00:00"
},
{
"day_of_week": "Thursday",
"opening_time": "08:00:00",
"closing_time": "22:00:00"
},
{
"day_of_week": "Friday",
"opening_time": "08:00:00",
"closing_time": "22:00:00"
},
{
"day_of_week": "Saturday",
"opening_time": "08:00:00",
"closing_time": "22:00:00"
},
{
"day_of_week": "Sunday",
"opening_time": "08:00:00",
"closing_time": "22:00:00"
},
{
"day_of_week": 7,
"opening_time": "08:00:00",
"closing_time": "22:00:00"
}
],
"ratings": 0.0
},}
I have setup my class like this:
class Location {
int id;
String name;
String phone;
String address;
String city;
String locationPhoto;
String locationLogo;
String state;
num lat;
num long;
List<OpeningHours> openingHours;
String cbdProducts;
num rating;
String zipCode;
String latlng;
String sponsored;
location(
{this.id,
this.name,
this.cbdProducts,
this.phone,
this.address,
this.locationLogo,
this.locationPhoto,
this.sponsored,
this.city,
this.state,
this.zipCode,
this.lat,
this.long,
this.latlng,
this.openingHours,
this.rating});
location.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['location_name'];
cbdProducts = json['cbd_products'];
phone = json['phone'];
address = json['street_address'];
locationLogo = json['location_logo'];
locationPhoto = json['location_photo'];
address = json['sponsored_location'];
city = json['city'];
state = json['state'];
zipCode = json['zip_Code'];
lat = json['lat'];
long = json['long'];
latlng = json['latlng'];
if (json['opening_hours'] != null) {
openingHours = new List<OpeningHours>();
json['opening_hours'].forEach((v) {
openingHours.add(new OpeningHours.fromJson(v));
});
}
rating = json['ratings'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['location_name'] = this.name;
data['cbd_products'] = this.cbdProducts;
data['phone'] = this.phone;
data['street_address'] = this.address;
data['location_logo'] = this.locationLogo;
data['location_photo'] = this.locationPhoto;
data['sponsored_location'] = this.address;
data['city'] = this.city;
data['state'] = this.state;
data['zip_Code'] = this.zipCode;
data['lat'] = this.lat;
data['lng'] = this.long;
data['latlng'] = this.latlng;
if (this.openingHours != null) {
data['opening_hours'] = this.openingHours.map((v) => v.toJson()).toList();
}
data['ratings'] = this.rating;
return data;
}
}
class OpeningHours {
String dayOfWeek;
String openingTime;
String closingTime;
OpeningHours({this.dayOfWeek, this.openingTime, this.closingTime});
OpeningHours.fromJson(Map<String, dynamic> json) {
dayOfWeek = json['day_of_week'];
openingTime = json['opening_time'];
closingTime = json['closing_time'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['day_of_week'] = this.dayOfWeek;
data['opening_time'] = this.openingTime;
data['closing_time'] = this.closingTime;
return data;
}
}
Then I call my api in a future to get the details. Here is the api:
Future getLocations() async {
var url = '$_server/api/customer/location/';
HttpClient client = new HttpClient();
HttpClientRequest request = await client.getUrl(Uri.parse(url));
HttpClientResponse response = await request.close();
String reply = await response.transform(utf8.decoder).join();
var responseData = json.decode(reply);
Locations _location = Locations.fromJson(responseData);
currentLocations = _location.location;
print(currentLocations);
return _location.location;
}
When I call the api currentLocations = null. What have I done wrong here?
One of the easiest ways is to use quicktype.io to generate PODO (Plain Old Dart Objects). Just Select the dart language to create PODO and copy-paste your JSON over there and provide the class Name as "Location". I have done that for you now your location class will look like this:
class Location {
Location({
this.location,
});
List<LocationElement> location;
factory Location.fromJson(Map<String, dynamic> json) => Location(
location: List<LocationElement>.from(json["location"].map((x) => LocationElement.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"location": List<dynamic>.from(location.map((x) => x.toJson())),
};
}
class LocationElement {
LocationElement({
this.id,
this.locationName,
this.cbdProducts,
this.phone,
this.streetAddress,
this.locationLogo,
this.locationPhoto,
this.sponsoredLocation,
this.city,
this.state,
this.zipCode,
this.lat,
this.lng,
this.latlng,
this.openingHours,
this.ratings,
});
int id;
String locationName;
String cbdProducts;
String phone;
String streetAddress;
String locationLogo;
String locationPhoto;
String sponsoredLocation;
String city;
String state;
int zipCode;
double lat;
double lng;
String latlng;
List<OpeningHour> openingHours;
int ratings;
factory LocationElement.fromJson(Map<String, dynamic> json) => LocationElement(
id: json["id"],
locationName: json["location_name"],
cbdProducts: json["cbd_products"],
phone: json["phone"],
streetAddress: json["street_address"],
locationLogo: json["location_logo"],
locationPhoto: json["location_photo"],
sponsoredLocation: json["sponsored_location"],
city: json["city"],
state: json["state"],
zipCode: json["zip_Code"],
lat: json["lat"].toDouble(),
lng: json["lng"].toDouble(),
latlng: json["latlng"],
openingHours: List<OpeningHour>.from(json["opening_hours"].map((x) => OpeningHour.fromJson(x))),
ratings: json["ratings"],
);
Map<String, dynamic> toJson() => {
"id": id,
"location_name": locationName,
"cbd_products": cbdProducts,
"phone": phone,
"street_address": streetAddress,
"location_logo": locationLogo,
"location_photo": locationPhoto,
"sponsored_location": sponsoredLocation,
"city": city,
"state": state,
"zip_Code": zipCode,
"lat": lat,
"lng": lng,
"latlng": latlng,
"opening_hours": List<dynamic>.from(openingHours.map((x) => x.toJson())),
"ratings": ratings,
};
}
class OpeningHour {
OpeningHour({
this.dayOfWeek,
this.openingTime,
this.closingTime,
});
dynamic dayOfWeek;
String openingTime;
String closingTime;
factory OpeningHour.fromJson(Map<String, dynamic> json) => OpeningHour(
dayOfWeek: json["day_of_week"],
openingTime: json["opening_time"],
closingTime: json["closing_time"],
);
Map<String, dynamic> toJson() => {
"day_of_week": dayOfWeek,
"opening_time": openingTime,
"closing_time": closingTime,
};
}
This may work now and if still there is issue then you may be getting null value from backend.