How to setState JSON in DropDownField? - json

// ignore_for_file: prefer_const_constructors, avoid_unnecessary_containers, prefer_const_literals_to_create_immutables, import_of_legacy_library_into_null_safe, non_constant_identifier_names, unused_field, avoid_print
import 'dart:convert';
import 'package:dropdownfield/dropdownfield.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FoodWidget extends StatefulWidget {
const FoodWidget({Key? key}) : super(key: key);
#override
_FoodWidgetState createState() => _FoodWidgetState();
}
class _FoodWidgetState extends State<FoodWidget> {
#override
void initState() {
fetchFood();
super.initState();
}
String? food_id;
List food = [];
Future<void> fetchFood() async {
final String response =
await rootBundle.loadString('assets/list_food.json');
final data = await json.decode(response);
print(data);
setState(() {
food = data["food"];
});
}
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
DropDownField(
onValueChanged: (dynamic value) {
food_id = value;
},
value: food_id,
required: false,
labelText: 'Search food',
items: food,
),
]),
);
}
}
and this is the JSON file. I want to get only names in DropDownField but I can't do it. At the setState function, I really don't know how to put it.
{
"food": [
{
"id": 1,
"name": "coca-cola",
"calories": 120
},
{
"id": 2,
"name": "egg",
"calories": 80
},
{
"id": 3,
"name": "rice",
"calories": 100
}
]
}
I tried to print(data) to test the output. It's all coming out of the domain name, but I want to use that inside. And I really don't know how to do it.
PS. I really will appreciate with answers and suggestions.

you would just need to map the data to get only its name :
Future<void> fetchFood() async {
final String response =
await rootBundle.loadString('assets/list_food.json');
final data = await json.decode(response);
print(data);
setState(() {
food = data["food"].map((e)=>e['name']).toList();
});
}
There after getting the list of foods, you map each item to get only the food name, which is what you need.
As a sidenote
I would recommend that in the future you create a model like :
class Food {
Food({
this.id,
this.name,
this.calories,
});
int id;
String name;
int calories;
factory Food.fromJson(Map<String, dynamic> json) => Food(
id: json["id"],
name: json["name"],
calories: json["calories"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"calories": calories,
};
}
So you have a strongly typed List<Food> food and you could access parameters in a type safe matter.

You need to Generate Food class
class Food {
String? id;
String? name;
String? calories;
Food({
this.id,
this.name,
this.calories,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'calories': calories,
};
}
factory Food.fromMap(Map<String, dynamic> map) {
return Food(
id: map['id'],
name: map['name'],
calories: map['calories'],
);
}
String toJson() => json.encode(toMap());
factory Food.fromJson(String source) => Food.fromMap(json.decode(source));
}
Full Code here:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FoodWidget extends StatefulWidget {
const FoodWidget({Key? key}) : super(key: key);
#override
_FoodWidgetState createState() => _FoodWidgetState();
}
class _FoodWidgetState extends State<FoodWidget> {
#override
void initState() {
fetchFood();
super.initState();
}
String? food_id;
Food? selected_food ;
List<Food> food = [];
Future<void> fetchFood() async {
final String response =
await rootBundle.loadString('assets/list_food.json');
final data = await json.decode(response) as List;
print(data);
setState(() {
food = data.map((e) => Food.fromJson(e)).toList();
});
}
#override
Widget build(BuildContext context) {
return Container(
padding:const EdgeInsets.all(15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
DropdownButton<Food>(
focusColor: Colors.white,
value: selected_food,
//elevation: 5,
style: const TextStyle(color: Colors.white),
iconEnabledColor: Colors.black,
underline: const SizedBox.shrink(),
items: food.map<DropdownMenuItem<Food>>(
(Food value) {
return DropdownMenuItem<Food>(
value: value,
child: Text(
value.name!,
style: const TextStyle(color: Colors.black),
),
);
}).toList(),
hint: const Text(
"Select Shop Category",
style: TextStyle(
color: Colors.black38,
),
),
onChanged: (Food? value) {
setState(() {
selected_food= value!;
});
},
),
]),
);
}
}
class Food {
String? id;
String? name;
String? calories;
Food({
this.id,
this.name,
this.calories,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'calories': calories,
};
}
factory Food.fromMap(Map<String, dynamic> map) {
return Food(
id: map['id'],
name: map['name'],
calories: map['calories'],
);
}
String toJson() => json.encode(toMap());
factory Food.fromJson(String source) =>
Food.fromMap(json.decode(source));
}

Related

How can i pass this complex Json MAP Data into flutter Listview

i am new to flutter, and i meet this API with complex "MAP" json. What i want is to display the list of countries with their details in flutter listview, How can i achieve that? Most of answers explain about "LIST" json.
{
"status": "Request is successful",
"message": null,
"data": {
"page": 1,
"last_page": 125,
"page_size": 2,
"countries": [
{
"id": "1",
"attributes": {
"name": "Grenada",
"code": "GD",
"subregion": "Caribbean",
"flag": "https://flagcdn.com/gd.svg",
"postalcode": "",
"latitude": "12.11666666",
"longitude": "-61.66666666",
"createdAt": "2023-01-11T22:15:40.000000Z",
"updatedAt": "2023-01-11T22:15:40.000000Z"
}
},
{
"id": "2",
"attributes": {
"name": "Malaysia",
"code": "MY",
"subregion": "South-Eastern Asia",
"flag": "https://flagcdn.com/my.svg",
"postalcode": "^(\\d{5})$",
"latitude": "2.5",
"longitude": "112.5",
"createdAt": "2023-01-11T22:15:40.000000Z",
"updatedAt": "2023-01-11T22:15:40.000000Z"
}
}
]
}
}
I found this GitHub project with these files json, modelClass Mainclass which relate with the concept but mine is has got one extra braces (map) so i do not know how to achieve the goal.
if there any suggestion or best way to code please help me.
this is how they created in model class but, but it does not work with me.
class Product {
final List<Result> results;
Product({this.results});
factory Product.fromJson(Map<String, dynamic> data) {
var list = data['data']['result'] as List;
List<Result> resultList = list.map((e) => Result.fromJson(e)).toList();
return Product(
results: resultList,
);
}
}
what i have done is
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
var data_from_link;
getData() async {
final String link = 'myurl';
data_from_link = await http.get(Uri.parse(link), headers: {"Accept": "application/json"});
final res = jsonDecode(data_from_link.body) as Map<String, dynamic>;
final List<Country> list= (res['data']['countries'] as List<dynamic>).map((e) => Country.fromJson(e))
.toList();
}
#override
void initState() {
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
final res = jsonDecode(data_from_link.body) as Map<String, dynamic>;
final List<Country> list= (res['data']['countries'] as List<dynamic>).map((e) => Country.fromJson(e))
.toList();
return ListView.builder(
itemCount: list.length,
itemBuilder: (_, i) => ListTile(
title: Text(
list![i].attributes.name,
),
subtitle: Text(list![i].attributes.code),
)
);
}
}
You can create two classes for Country and Attribute
class Country {
const Country({required this.id, required this.attributes});
/// Creates a Country from Json map
factory Country.fromJson(Map<String, dynamic> json) => Country(
id: json['id'] as String,
attribute:
Attribute.fromJson(json['attributes'] as Map<String, dynamic>),
);
/// A description for id
final String id;
final Attribute attributes;
}
class Attribute {
const Attribute({
required this.name,
required this.code,
required this.createdAt,
required this.updatedAt,
});
/// Creates a Attribute from Json map
factory Attribute.fromJson(Map<String, dynamic> json) => Attribute(
name: json['name'] as String,
code: json['code'] as String,
createdAt: DateTime.parse(json['createdAt'] as String),
updatedAt: DateTime.parse(json['updatedAt'] as String),
);
final String name;
final String code;
final DateTime createdAt;
final DateTime updatedAt;
}
when decoding:
final res = jsonDecode(json) as Map<String, dynamic>;
final List<Country> list = (res['data']['countries'] as
List<dynamic>)
.map((e) => Country.fromJson(e))
.toList();
Thank you but how can i print or call data from country attribute
after decoding because when i try something like Print
(list.country.attribute.name) . I fail. My goal is to display on
Listview
You can use it like this:
ListView.builder(
itemCount: list.length,
itemBuilder: (_, i) => ListTile(
title: Text(
list[i].attributes.name,
),
subtitle: Text(list[i].attributes.code),
)),
UPDATE
import 'package:flutter/material.dart';
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
late Future<List<Country>> futureList;
Future<List<Country>?> getData() async {
final String link = 'yoururl';
final res = await http
.get(Uri.parse(link), headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
final List<Country> list = (res['data']['countries'] as List<dynamic>)
.map((e) => Country.fromJson(e))
.toList();
return list;
} else {
throw Exception('Failed to fetch data');
}
}
#override
void initState() {
super.initState();
futureList = getData();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: futureList,
builder: (context, snapshot) {
if (snapshot.hasData) {
final list = snapshot.data;
return ListView.builder(
itemCount: list!.length,
itemBuilder: (_, i) => ListTile(
title: Text(
list![i].attributes.name,
),
subtitle: Text(list![i].attributes.code),
),
);
} else if (snapshot.hasError) {
return const Text('error fetching data');
}
return const CircularProgressIndicator();
},
);
}
}

Stuck in CircularProgressIndicator when Fetching data from json API in flutter

I'm debugging an app on my physical device to fetch data from a json API but it keeps showing the CircularProgressIndicator as you see . Still a beginner and I've been trying to solve this for 3 days countinously . Thanks in advance, the code is below
here
main.dart code
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:json/pages/homePage.dart';
void main() {
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.dumpErrorToConsole(details);
if (kReleaseMode) exit(1);
};
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
);
}
}
homePage.dart file
import 'package:json/models/bcNewsModel.dart';
import 'package:json/services/api_manager.dart';
class HomePage extends StatefulWidget {
#override
MyHomePage createState() => MyHomePage();
// TODO: implement createState
}
class MyHomePage extends State<HomePage> {
Future<Bitcoin> _bcNews;
#override
void initeState() {
_bcNews = API_Manager().BCNews();
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('BitCoin App'),
),
body: Container(
child: FutureBuilder<Bitcoin>(
future: _bcNews,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.articles.length,
// ignore: missing_return
itemBuilder: (context, index) {
var article = snapshot.data.articles[index];
Container(
height: 100,
child: Row(
children: <Widget>[
Image.network(article.urlToImage),
],
),
);
});
} else
return Center(child: CircularProgressIndicator());
},
),
));
}
}
api_manager.dart file
Bitcoin bitcoinFromJson(String str) => Bitcoin.fromJson(json.decode(str));
String bitcoinToJson(Bitcoin data) => json.encode(data.toJson());
class Bitcoin {
Bitcoin({
this.status,
this.totalResults,
this.articles,
});
String status;
int totalResults;
List<Article> articles;
factory Bitcoin.fromJson(Map<String, dynamic> json) => Bitcoin(
status: json["status"],
totalResults: json["totalResults"],
articles: List<Article>.from(
json["articles"].map((x) => Article.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"totalResults": totalResults,
"articles": List<dynamic>.from(articles.map((x) => x.toJson())),
};
}
class Article {
Article({
this.source,
this.author,
this.title,
this.description,
this.url,
this.urlToImage,
this.publishedAt,
this.content,
});
Source source;
String author;
String title;
String description;
String url;
String urlToImage;
DateTime publishedAt;
String content;
factory Article.fromJson(Map<String, dynamic> json) => Article(
source: Source.fromJson(json["source"]),
author: json["author"],
title: json["title"],
description: json["description"],
url: json["url"],
urlToImage: json["urlToImage"],
publishedAt: DateTime.parse(json["publishedAt"]),
content: json["content"],
);
Map<String, dynamic> toJson() => {
"source": source.toJson(),
"author": author,
"title": title,
"description": description,
"url": url,
"urlToImage": urlToImage,
"publishedAt": publishedAt.toIso8601String(),
"content": content,
};
}
class Source {
Source({
this.id,
this.name,
});
String id;
String name;
factory Source.fromJson(Map<String, dynamic> json) => Source(
id: json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
};
}
Could the problem be with my physical device ?
Since you are trying to request this information, check in your manifest if you have enabled access to the internet. Otherwise, it will keep on blocking the requests.

How to display in widget the complex JSON using flutter?

My problem is i don't know how to display the Object inside the Object of JSON.
But i already display the Outer Object like name, usermae etc. And i want to display the object inside the Address and Geo. Im new to JSON and flutter please guide me
i read this but i dont know what i need here
the code is from here
JSON OUTPUT json is from here
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere#april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
]
MODEL
i generate my model in here
import 'dart:convert';
List<UserModel> userModelFromJson(String str) =>
List<UserModel>.from(json.decode(str).map((x) => UserModel.fromJson(x)));
String userModelToJson(List<UserModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class UserModel {
int id;
String name;
String username;
String email;
Address address;
String phone;
String website;
Company company;
UserModel({
this.id,
this.name,
this.username,
this.email,
this.address,
this.phone,
this.website,
this.company,
});
factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
id: json["id"],
name: json["name"],
username: json["username"],
email: json["email"],
address: Address.fromJson(json["address"]),
phone: json["phone"],
website: json["website"],
company: Company.fromJson(json["company"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"username": username,
"email": email,
"address": address.toJson(),
"phone": phone,
"website": website,
"company": company.toJson(),
};
}
class Address {
String street;
String suite;
String city;
String zipcode;
Geo geo;
Address({
this.street,
this.suite,
this.city,
this.zipcode,
this.geo,
});
factory Address.fromJson(Map<String, dynamic> json) => Address(
street: json["street"],
suite: json["suite"],
city: json["city"],
zipcode: json["zipcode"],
geo: Geo.fromJson(json["geo"]),
);
Map<String, dynamic> toJson() => {
"street": street,
"suite": suite,
"city": city,
"zipcode": zipcode,
"geo": geo.toJson(),
};
}
class Geo {
String lat;
String lng;
Geo({
this.lat,
this.lng,
});
factory Geo.fromJson(Map<String, dynamic> json) => Geo(
lat: json["lat"],
lng: json["lng"],
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lng": lng,
};
}
class Company {
String name;
String catchPhrase;
String bs;
Company({
this.name,
this.catchPhrase,
this.bs,
});
factory Company.fromJson(Map<String, dynamic> json) => Company(
name: json["name"],
catchPhrase: json["catchPhrase"],
bs: json["bs"],
);
Map<String, dynamic> toJson() => {
"name": name,
"catchPhrase": catchPhrase,
"bs": bs,
};
}
Services.dart
class Services {
static const String url = 'https://jsonplaceholder.typicode.com/users';
static Future<List<UserModel>> getUsers() async {
try {
final response = await http.get(url);
if (200 == response.statusCode) {
final List<UserModel> users = userModelFromJson(response.body);
return users;
} else {
return List<UserModel>();
}
} catch (e) {
return List<UserModel>();
}
}
}
HomeView.dart
class _HomeViewState extends State<HomeView> {
List<UserModel> _users;
bool _loading;
#override
void initState() {
super.initState();
_loading = true;
Services.getUsers().then((users) {
setState(() {
_users = users;
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_loading ? 'Loading...' : 'Users'),
),
body: Container(
color: Colors.white,
child: ListView.builder(
itemCount: _users == null ? 0 : _users.length,
itemBuilder: (context, index) {
UserModel user = _users[index];
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
ListTile(
title: Text(user.name),
subtitle: Text(user.email),
trailing: Text(user.phone),
),
],
);
},
),
),
);
}
}
Thank you for your kindness
The model that you create is correct, you have (Good habit) only to check the objects inside your model before you parse them
UserModel.fromJson(Map<String, dynamic> json) {
// ...
address =
json['address'] != null ? new Address.fromJson(json['address']) : null;
company =
json['company'] != null ? new Company.fromJson(json['company']) : null;
// ...
}
On your service class use the fetch way that is set on flutter documentation to simplify your code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<UserModel>> fetchUsers(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/users');
return parseUsers(response.body);
}
List<UserModel> parseUsers(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<UserModel>((json) => UserModel.fromJson(json)).toList();
}
and once you get the data from json you can access to every object based on the hierarchy inside the json, in your case the stateful widget would look like, where i replace the name and the phone with latitude inside the geo and city inside the address
class _HomeViewState extends State<HomeView> {
List<UserModel> _users;
bool _loading;
#override
void initState() {
super.initState();
_loading = true;
fetchUsers(http.Client()).then((users) {
setState(() {
_users = users;
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_loading ? 'Loading...' : 'Users'),
),
body: Container(
color: Colors.white,
child: ListView.builder(
itemCount: _users == null ? 0 : _users.length,
itemBuilder: (context, index) {
UserModel user = _users[index];
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
ListTile(
title: Text(user.name),
subtitle: Text(user.address.geo.lat),
trailing: Text(user.address.city),
),
],
);
},
),
),
);
}
}
I hope this help
You can copy paste run full code below
You can directly assign attribute
code snippet
title: Text('${user.name} ${user.address.city} ${user.address.geo.lat}'),
working demo
full code
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
List<UserModel> userModelFromJson(String str) =>
List<UserModel>.from(json.decode(str).map((x) => UserModel.fromJson(x)));
String userModelToJson(List<UserModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class UserModel {
int id;
String name;
String username;
String email;
Address address;
String phone;
String website;
Company company;
UserModel({
this.id,
this.name,
this.username,
this.email,
this.address,
this.phone,
this.website,
this.company,
});
factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
id: json["id"],
name: json["name"],
username: json["username"],
email: json["email"],
address: Address.fromJson(json["address"]),
phone: json["phone"],
website: json["website"],
company: Company.fromJson(json["company"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"username": username,
"email": email,
"address": address.toJson(),
"phone": phone,
"website": website,
"company": company.toJson(),
};
}
class Address {
String street;
String suite;
String city;
String zipcode;
Geo geo;
Address({
this.street,
this.suite,
this.city,
this.zipcode,
this.geo,
});
factory Address.fromJson(Map<String, dynamic> json) => Address(
street: json["street"],
suite: json["suite"],
city: json["city"],
zipcode: json["zipcode"],
geo: Geo.fromJson(json["geo"]),
);
Map<String, dynamic> toJson() => {
"street": street,
"suite": suite,
"city": city,
"zipcode": zipcode,
"geo": geo.toJson(),
};
}
class Geo {
String lat;
String lng;
Geo({
this.lat,
this.lng,
});
factory Geo.fromJson(Map<String, dynamic> json) => Geo(
lat: json["lat"],
lng: json["lng"],
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lng": lng,
};
}
class Company {
String name;
String catchPhrase;
String bs;
Company({
this.name,
this.catchPhrase,
this.bs,
});
factory Company.fromJson(Map<String, dynamic> json) => Company(
name: json["name"],
catchPhrase: json["catchPhrase"],
bs: json["bs"],
);
Map<String, dynamic> toJson() => {
"name": name,
"catchPhrase": catchPhrase,
"bs": bs,
};
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeView(title: 'Flutter Demo Home Page'),
);
}
}
class Services {
static const String url = 'https://jsonplaceholder.typicode.com/users';
static Future<List<UserModel>> getUsers() async {
try {
final response = await http.get(url);
if (200 == response.statusCode) {
final List<UserModel> users = userModelFromJson(response.body);
return users;
} else {
return List<UserModel>();
}
} catch (e) {
return List<UserModel>();
}
}
}
class HomeView extends StatefulWidget {
HomeView({Key key, this.title}) : super(key: key);
final String title;
#override
_HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
List<UserModel> _users;
bool _loading;
#override
void initState() {
super.initState();
_loading = true;
Services.getUsers().then((users) {
setState(() {
_users = users;
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_loading ? 'Loading...' : 'Users'),
),
body: Container(
color: Colors.white,
child: ListView.builder(
itemCount: _users == null ? 0 : _users.length,
itemBuilder: (context, index) {
UserModel user = _users[index];
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
ListTile(
title: Text('${user.name} ${user.address.city} ${user.address.geo.lat}'),
subtitle: Text(user.email),
trailing: Text(user.phone),
),
],
);
},
),
),
);
}
}

How to Parse Nested JSON

I'm able to parse the JSON using following code,
Map<String, dynamic> map = jsonDecode(response.body); // import 'dart:convert';
List<dynamic> datalist = map['data'];
I got List dynamic but i need data list
My problem is if I get product items in data list then how should i parse the JSON. I got stuck here.
When it comes to nested array of JSON, how to parse it.
**
{
"status": 0,
"message": "Product Not Found",
"data": [{
"id": "1",
"product_name": "Pet 0.5",
"qty": "500",
"unit": "ml",
"product_img": "SRC.jpg",
"description": "sgsdgdfhdfhh",
"sale_price": "100",
"donation_amt": "10"
},
{
"id": "7",
"product_name": "Pet 1l",
"qty": "1",
"unit": "l",
"product_img": "SRC1.jpg",
"description": "dgdg",
"sale_price": "20",
"donation_amt": "1"
}
]
}
**
My dart code for the JSON
class ProductList {
int status;
String message;
List<Data> data;
ProductList({this.status, this.message, this.data});
ProductList.fromJson(Map<String, dynamic> json) {
status = json['status'];
message = json['message'];
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>();
data['status'] = this.status;
data['message'] = this.message;
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
String id;
String productName;
String qty;
String unit;
String productImg;
String description;
String salePrice;
String donationAmt;
Data(
{this.id,
this.productName,
this.qty,
this.unit,
this.productImg,
this.description,
this.salePrice,
this.donationAmt});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
productName = json['product_name'];
qty = json['qty'];
unit = json['unit'];
productImg = json['product_img'];
description = json['description'];
salePrice = json['sale_price'];
donationAmt = json['donation_amt'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['product_name'] = this.productName;
data['qty'] = this.qty;
data['unit'] = this.unit;
data['product_img'] = this.productImg;
data['description'] = this.description;
data['sale_price'] = this.salePrice;
data['donation_amt'] = this.donationAmt;
return data;
}
}
This is the code below for the drop down list. We need to populate the drop down with the product name and id. The product name and id fields are there in the data part of the JSON
Padding(
padding: const EdgeInsets.fromLTRB(25.0, 20.0, 0, 0),
child: Container(
width: 160,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
border: Border.all(
color: Colors.red,
style: BorderStyle.solid,
width: 0.80),
),
child: DropdownButton<Product>(
value: selectedUser,
icon: Padding(
padding: const EdgeInsets.only(left:15.0),
child: Icon(Icons.arrow_drop_down),
),
iconSize: 25,
underline: SizedBox(),
onChanged: (Product newValue) {
setState(() {
selectedUser = newValue;
});
},
items: users.map((Product user) {
return DropdownMenuItem<Product>(
value: user,
child: Padding(
padding:
const EdgeInsets.only(left: 10.0),
child: Text(
user.name,
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
),
);
}).toList()),
),
),
So as you Described i have made some changes and loaded you json locally, you can make a api call and then everything is the same:
{
"status": 0,
"message": "Product Not Found",
"data": [
{
"id": "1",
"product_name": "Pet 0.5",
"qty": "500",
"unit": "ml",
"product_img": "SRC.jpg",
"description": "sgsdgdfhdfhh",
"sale_price": "100",
"donation_amt": "10"
},
{
"id": "7",
"product_name": "Pet 1l",
"qty": "1",
"unit": "l",
"product_img": "SRC1.jpg",
"description": "dgdg",
"sale_price": "20",
"donation_amt": "1"
}
]
}
json you provided
// To parse this JSON data, do
//
// final productList = productListFromJson(jsonString);
import 'dart:convert';
ProductList productListFromJson(String str) =>
ProductList.fromJson(json.decode(str));
String productListToJson(ProductList data) => json.encode(data.toJson());
class ProductList {
int status;
String message;
List<Datum> data;
ProductList({
this.status,
this.message,
this.data,
});
factory ProductList.fromJson(Map<String, dynamic> json) => ProductList(
status: json["status"],
message: json["message"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
String id;
String productName;
String qty;
String unit;
String productImg;
String description;
String salePrice;
String donationAmt;
Datum({
this.id,
this.productName,
this.qty,
this.unit,
this.productImg,
this.description,
this.salePrice,
this.donationAmt,
});
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
productName: json["product_name"],
qty: json["qty"],
unit: json["unit"],
productImg: json["product_img"],
description: json["description"],
salePrice: json["sale_price"],
donationAmt: json["donation_amt"],
);
Map<String, dynamic> toJson() => {
"id": id,
"product_name": productName,
"qty": qty,
"unit": unit,
"product_img": productImg,
"description": description,
"sale_price": salePrice,
"donation_amt": donationAmt,
};
}
creating the model class for the json
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sample_testing_project/models.dart';
main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _currentSelectedValue;
List<Datum> data = List();
bool _isLoading = false;
String selectedUser;
#override
void initState() {
// TODO: implement initState
super.initState();
loadYourData();
}
Future<String> loadFromAssets() async {
return await rootBundle.loadString('json/parse.json');
}
loadYourData() async {
setState(() {
_isLoading = true;
});
// Loading your json locally you can make an api call, when you get the response just pass it to the productListFromJson method
String jsonString = await loadFromAssets();
final productList = productListFromJson(jsonString);
data = productList.data;
setState(() {
_isLoading = false;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: _isLoading
? Text('Loading')
: Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(25.0, 20.0, 0, 0),
child: Container(
width: 160,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
border: Border.all(
color: Colors.red,
style: BorderStyle.solid,
width: 0.80),
),
child: DropdownButton(
value: selectedUser,
isExpanded: true,
icon: Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Icon(Icons.arrow_drop_down),
),
iconSize: 25,
underline: SizedBox(),
onChanged: (newValue) {
setState(() {
selectedUser = newValue;
});
},
hint: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Select'),
),
items: data.map((data) {
return DropdownMenuItem(
value: data.id,
child: Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Text(
data.id + ':' + data.productName,
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
),
);
}).toList()),
),
),
),
),
);
}
}
check out the changes that i have made using your same ui.
Let me know if its working.
Thanks.
Remember: "JSON is not 'nested.'" When you're given a JSON string, you decode it and this gives you a data-structure ... which very well might be "nested." How to handle that correctly is up to you.
Always treat JSON (or YAML, or XML) as a "black box." Use the utilities provided in the language to encode, decode and parse them.

Flutter how to JSON serialize data form api

I am tryin to use model in my flutter app to get this concept up and running in my app. I am quite new to OOP so i want to learn as much as i can. My problem is that i have API response from OpenWeather API my method is calling api getting data. That works fine and the i make manual decode and accessing propetires by hand weather["main"] aa usually with JSON. But what i want is to factor/pre-procesds my JSON by model. Below code is working good but i want to apply concept of using JSON serialization and i have no idea how to start. All my attempts failed...:/
I have generated models with https://app.quicktype.io/ with help of guy form my previous answer.
Model:
import 'dart:convert';
Forcast forcastFromJson(String str) => Forcast.fromJson(json.decode(str));
String forcastToJson(Forcast data) => json.encode(data.toJson());
class Forcast {
String cod;
double message;
int cnt;
List<ListElement> list;
City city;
Forcast({
this.cod,
this.message,
this.cnt,
this.list,
this.city,
});
factory Forcast.fromJson(Map<String, dynamic> json) => new Forcast(
cod: json["cod"],
message: json["message"].toDouble(),
cnt: json["cnt"],
list: new List<ListElement>.from(
json["list"].map((x) => ListElement.fromJson(x))),
city: City.fromJson(json["city"]),
);
Map<String, dynamic> toJson() => {
"cod": cod,
"message": message,
"cnt": cnt,
"list": new List<dynamic>.from(list.map((x) => x.toJson())),
"city": city.toJson(),
};
}
class City {
int id;
String name;
Coord coord;
String country;
City({
this.id,
this.name,
this.coord,
this.country,
});
factory City.fromJson(Map<String, dynamic> json) => new City(
id: json["id"],
name: json["name"],
coord: Coord.fromJson(json["coord"]),
country: json["country"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"coord": coord.toJson(),
"country": country,
};
}
class Coord {
double lat;
double lon;
Coord({
this.lat,
this.lon,
});
factory Coord.fromJson(Map<String, dynamic> json) => new Coord(
lat: json["lat"].toDouble(),
lon: json["lon"].toDouble(),
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lon": lon,
};
}
class ListElement {
int dt;
MainClass main;
List<Weather> weather;
Clouds clouds;
Wind wind;
Sys sys;
DateTime dtTxt;
Rain rain;
Rain snow;
ListElement({
this.dt,
this.main,
this.weather,
this.clouds,
this.wind,
this.sys,
this.dtTxt,
this.rain,
this.snow,
});
factory ListElement.fromJson(Map<String, dynamic> json) => new ListElement(
dt: json["dt"],
main: MainClass.fromJson(json["main"]),
weather: new List<Weather>.from(
json["weather"].map((x) => Weather.fromJson(x))),
clouds: Clouds.fromJson(json["clouds"]),
wind: Wind.fromJson(json["wind"]),
sys: Sys.fromJson(json["sys"]),
dtTxt: DateTime.parse(json["dt_txt"]),
rain: json["rain"] == null ? null : Rain.fromJson(json["rain"]),
snow: json["snow"] == null ? null : Rain.fromJson(json["snow"]),
);
Map<String, dynamic> toJson() => {
"dt": dt,
"main": main.toJson(),
"weather": new List<dynamic>.from(weather.map((x) => x.toJson())),
"clouds": clouds.toJson(),
"wind": wind.toJson(),
"sys": sys.toJson(),
"dt_txt": dtTxt.toIso8601String(),
"rain": rain == null ? null : rain.toJson(),
"snow": snow == null ? null : snow.toJson(),
};
}
class Clouds {
int all;
Clouds({
this.all,
});
factory Clouds.fromJson(Map<String, dynamic> json) => new Clouds(
all: json["all"],
);
Map<String, dynamic> toJson() => {
"all": all,
};
}
class MainClass {
double temp;
double tempMin;
double tempMax;
double pressure;
double seaLevel;
double grndLevel;
int humidity;
double tempKf;
MainClass({
this.temp,
this.tempMin,
this.tempMax,
this.pressure,
this.seaLevel,
this.grndLevel,
this.humidity,
this.tempKf,
});
factory MainClass.fromJson(Map<String, dynamic> json) => new MainClass(
temp: json["temp"].toDouble(),
tempMin: json["temp_min"].toDouble(),
tempMax: json["temp_max"].toDouble(),
pressure: json["pressure"].toDouble(),
seaLevel: json["sea_level"].toDouble(),
grndLevel: json["grnd_level"].toDouble(),
humidity: json["humidity"],
tempKf: json["temp_kf"].toDouble(),
);
Map<String, dynamic> toJson() => {
"temp": temp,
"temp_min": tempMin,
"temp_max": tempMax,
"pressure": pressure,
"sea_level": seaLevel,
"grnd_level": grndLevel,
"humidity": humidity,
"temp_kf": tempKf,
};
}
class Rain {
double the3H;
Rain({
this.the3H,
});
factory Rain.fromJson(Map<String, dynamic> json) => new Rain(
the3H: json["3h"] == null ? null : json["3h"].toDouble(),
);
Map<String, dynamic> toJson() => {
"3h": the3H == null ? null : the3H,
};
}
class Sys {
Pod pod;
Sys({
this.pod,
});
factory Sys.fromJson(Map<String, dynamic> json) => new Sys(
pod: podValues.map[json["pod"]],
);
Map<String, dynamic> toJson() => {
"pod": podValues.reverse[pod],
};
}
enum Pod { D, N }
final podValues = new EnumValues({"d": Pod.D, "n": Pod.N});
class Weather {
int id;
MainEnum main;
Description description;
String icon;
Weather({
this.id,
this.main,
this.description,
this.icon,
});
factory Weather.fromJson(Map<String, dynamic> json) => new Weather(
id: json["id"],
main: mainEnumValues.map[json["main"]],
description: descriptionValues.map[json["description"]],
icon: json["icon"],
);
Map<String, dynamic> toJson() => {
"id": id,
"main": mainEnumValues.reverse[main],
"description": descriptionValues.reverse[description],
"icon": icon,
};
}
enum Description {
CLEAR_SKY,
BROKEN_CLOUDS,
LIGHT_RAIN,
MODERATE_RAIN,
FEW_CLOUDS
}
final descriptionValues = new EnumValues({
"broken clouds": Description.BROKEN_CLOUDS,
"clear sky": Description.CLEAR_SKY,
"few clouds": Description.FEW_CLOUDS,
"light rain": Description.LIGHT_RAIN,
"moderate rain": Description.MODERATE_RAIN
});
enum MainEnum { CLEAR, CLOUDS, RAIN }
final mainEnumValues = new EnumValues({
"Clear": MainEnum.CLEAR,
"Clouds": MainEnum.CLOUDS,
"Rain": MainEnum.RAIN
});
class Wind {
double speed;
double deg;
Wind({
this.speed,
this.deg,
});
factory Wind.fromJson(Map<String, dynamic> json) => new Wind(
speed: json["speed"].toDouble(),
deg: json["deg"].toDouble(),
);
Map<String, dynamic> toJson() => {
"speed": speed,
"deg": deg,
};
}
class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
Network to make API call:
import 'package:http/http.dart' as http;
import 'dart:convert';
class NetworkHelper {
NetworkHelper({this.text});
String text;
String apiKey = '';
Future<dynamic> getData(text) async {
http.Response response = await http.get(
'https://api.openweathermap.org/data/2.5/weather?q=$text&appid=$apiKey&units=metric');
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);
return decodedData;
} else {
print(response.statusCode);
}
}
Future<dynamic> getForcast(text) async {
http.Response response = await http.get(
'http://api.openweathermap.org/data/2.5/forecast?q=${text}&units=metric&appid=$apiKey');
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);
return decodedData;
} else {
print(response.statusCode);
}
}
Future<dynamic> getDataLocation(lat, lon) async {
http.Response response = await http.get(
'https://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=$apiKey&units=metric');
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);
return decodedData;
} else {
print(response.statusCode);
}
}
Future<dynamic> getForcastLocation(lat, lon) async {
http.Response response = await http.get(
'http://api.openweathermap.org/data/2.5/forecast?lat=$lat&lon=$lon&units=metric&appid=$apiKey');
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);
return decodedData;
} else {
print(response.statusCode);
}
}
}
Weather where i display data:
import 'package:flutter/material.dart';
import 'package:weather/common/format.dart';
import 'package:weather/service/Network.dart';
import 'package:weather/service/location.dart';
class Weather extends StatefulWidget {
Weather({this.text});
final String text;
_WeatherState createState() => _WeatherState();
}
class _WeatherState extends State<Weather> {
NetworkHelper networkHelper = NetworkHelper();
Location location = Location();
Formats formats = Formats();
int temperature;
String cityName;
String description;
bool isLoading = true;
dynamic newData;
String city;
#override
void initState() {
super.initState();
city = widget.text;
buildUI(city);
}
buildUI(String text) async {
var weatherData = await networkHelper.getData(text);
var forecastData = await networkHelper.getForcast(text);
double temp = weatherData['main']['temp'];
temperature = temp.toInt();
cityName = weatherData['name'];
description = weatherData['weather'][0]['description'];
newData = forecastData['list'].toList();
setState(() {
isLoading = false;
});
}
buildUIByLocation() async {
await location.getCurrentLocation();
var weatherLocation = await networkHelper.getDataLocation(
location.latitude, location.longitude);
var forcastLocation = await networkHelper.getForcastLocation(
location.latitude, location.longitude);
double temp = weatherLocation['main']['temp'];
temperature = temp.toInt();
cityName = weatherLocation['name'];
description = weatherLocation['weather'][0]['description'];
newData = forcastLocation['list'].toList();
setState(() {
isLoading = false;
});
}
Widget get _pageToDisplay {
if (isLoading == true) {
return _loadingView;
} else {
return _weatherView;
}
}
Widget get _loadingView {
return Center(child: CircularProgressIndicator());
}
Widget get _weatherView {
return SafeArea(
child: Column(
children: <Widget>[
Flexible(
flex: 1,
child: Container(
margin: EdgeInsets.fromLTRB(12, 1, 30, 0),
decoration: new BoxDecoration(
color: Color(0xff4556FE),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Color(0xFFD4DAF6),
offset: Offset(20, 20),
),
BoxShadow(
color: Color(0xFFadb6ff),
offset: Offset(10, 10),
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'$cityName',
style: TextStyle(fontSize: 25, color: Colors.white),
),
SizedBox(
height: 5,
),
Text(
'$temperature°C',
style: TextStyle(fontSize: 50, color: Colors.white),
),
],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'$description',
style: TextStyle(fontSize: 25, color: Colors.white),
),
],
),
)
],
),
),
),
SizedBox(
height: 30,
),
Flexible(
flex: 2,
child: Container(
margin: EdgeInsets.fromLTRB(12, 10, 12, 0),
decoration: new BoxDecoration(
color: Color(0xff4556FE),
borderRadius: BorderRadius.vertical(top: Radius.circular(10.0)),
),
child: ListView.builder(
padding: const EdgeInsets.all(8.0),
itemCount: newData.length,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: const EdgeInsets.all(4.0),
height: 50,
child: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
formats.readTimeStamp(newData[index]['dt']),
style: TextStyle(
color: Colors.white, fontSize: 14),
),
Text(
newData[index]['weather'][0]['main'].toString(),
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600),
),
Text(
formats.floatin(newData[index]['main']['temp']),
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600),
),
],
),
));
}),
),
),
],
),
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(
padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
icon: Icon(Icons.autorenew, color: Colors.black, size: 30),
onPressed: () {
if (city == "") {
setState(() {
isLoading = true;
buildUIByLocation();
});
} else {
setState(() {
isLoading = true;
buildUI(city);
});
}
},
),
IconButton(
padding: EdgeInsets.fromLTRB(0, 0, 15, 0),
icon: Icon(
Icons.location_on,
color: Colors.black,
size: 30,
),
onPressed: () async {
setState(() {
city = '';
isLoading = true;
});
await buildUIByLocation();
},
)
],
leading: IconButton(
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
onPressed: () {
Navigator.pop(context);
},
),
elevation: 0,
backgroundColor: Colors.transparent,
title: const Text(
'Change location',
style: TextStyle(color: Colors.black),
),
),
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(color: Color(0xFFfafafa)),
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 20, 5, 0),
child: Center(child: _pageToDisplay),
),
)
],
),
);
}
}
This is a really basic example. Here you see the Car model class and his basic attributes. Data would be fetching by CarRepository class, this class do network stuff and map data from json to model.
The CarScreen class is an Stateful widget and call CarRepository after initState. If data fetched from network, cars would be displayed in an list.
While fetching an loading indicator would displayed.
import 'dart:convert';
import 'package:http/http.dart' as http;
class Car {
//
// Attributes
//
int id;
String name;
String color;
int speed;
//
// Constructor
//
Car({
#required this.id,
#required this.name,
#required this.color,
#required this.speed,
});
// convert Json to an car object object
factory Car.fromJson(Map<String, dynamic> json) {
return Car(
id: json['id'] as int,
name: json['name'] as String,
color: json['color'] as String,
speed: json['speed'] as int,
);
}
}
class CarRepository {
/// Load all cars form api and will convert it
/// to an list of cars.
///
/// {
/// "results": [
/// {
/// "id": 1,
/// "name": "Tesla Model 3",
/// "color": "red",
/// "speed": 225
/// },
/// {
/// "id": 3,
/// "name": "Tesla Model S",
/// "color": "black",
/// "speed": 255
/// }
/// ]
/// }
///
///
static Future<List<Car>> fetchAll() async {
String query = '';
String url = Uri.encodeFull("https://xxx.de/api/cars" + query);
final response = await http.get(url);
if (response.statusCode == 200) {
Map data = json.decode(response.body);
final cars = (data['results'] as List).map((i) => new Car.fromJson(i));
return cars.toList();
} else {
return [];
}
}
}
class CarsScreen extends StatefulWidget {
_CarsScreenState createState() => _CarsScreenState();
}
class _CarsScreenState extends State<CarsScreen> {
bool _isLoading = true;
List<Car> _cars = [];
#override
void initState() {
super.initState();
fetchCars();
}
Future fetchCars() async {
_cars = await CarRepository.fetchAll();
setState(() {
_isLoading = false;
});
}
#override
Widget build(BuildContext context) {
if (_isLoading) {
return Scaffold(
appBar: AppBar(
title: Text('Cars'),
),
body: Container(
child: Center(
child: CircularProgressIndicator(),
),
),
);
} else {
return Scaffold(
appBar: AppBar(
title: Text('Cars'),
),
body: ListView.builder(
itemCount: _cars.length,
itemBuilder: (context, index) {
Car car = _cars[index];
return ListTile(
title: Text(car.name),
subtitle: Text(car.color),
);
},
),
);
}
}
}
This example include nested array with car objects. I hope it will help.
There is an relationship between producer and car.
import 'dart:convert';
import 'package:http/http.dart' as http;
class CarRepository {
/// Load all producers form api and will convert it
/// to an list of producers.
/// [
/// {
/// "id": 1,
/// "name": "Tesla"
/// "cars": [
/// {
/// "id": 1,
/// "name": "Tesla Model 3",
/// "color": "red",
/// "speed": 225
/// },
/// {
/// "id": 3,
/// "name": "Tesla Model S",
/// "color": "black",
/// "speed": 255
/// }
/// ]
/// },
/// {
/// "id": 2,
/// "name": "Volkswagen"
/// "cars": [
/// {
/// "id": 1,
/// "name": "Golf",
/// "color": "red",
/// "speed": 225
/// },
/// {
/// "id": 3,
/// "name": "Passat",
/// "color": "black",
/// "speed": 255
/// }
/// ]
/// }
/// ]
///
///
static Future<List<Car>> fetchAll() async {
String query = '';
String url = Uri.encodeFull("https://xxx.de/api/producers" + query);
final response = await http.get(url);
if (response.statusCode == 200) {
Map data = json.decode(response.body);
final cars = (data as List).map((i) => new Car.fromJson(i));
return cars.toList();
} else {
return [];
}
}
}
class Producer {
//
// Attributes
//
int id;
String name;
List<Car> cars;
//
// Constructor
//
Producer({
#required this.id,
#required this.name,
#required this.cars,
});
// convert Json to an producer object object
factory Producer.fromJson(Map<String, dynamic> json) {
return Producer(
id: json['id'] as int,
name: json['name'] as String,
cars: (json['cars'] as List ?? []).map((c) {
return Car.fromJson(c);
}).toList(),
);
}
}
class Car {
//
// Attributes
//
int id;
String name;
String color;
int speed;
//
// Constructor
//
Car({
#required this.id,
#required this.name,
#required this.color,
#required this.speed,
});
// convert Json to an car object object
factory Car.fromJson(Map<String, dynamic> json) {
return Car(
id: json['id'] as int,
name: json['name'] as String,
color: json['color'] as String,
speed: json['speed'] as int,
);
}
}