About Flutter Firestore Rest Api Json Output - json

{
"documents": [
{
"name": "projects/xxxxx/databases/(default)/documents/blogs/Hao5IboeA6b7ySlmx0qN",
"fields": {
"imgUrl": {
"stringValue": "https://firebasestorage.googleapis.com/v0/b/xxxxxx/o/blogImages%2F72H566888.jpg?alt=media&token=75b75deb-69a3-4019-a82e-335a2d72b52e"
},
"authorName": {
"stringValue": "iki"
},
"title": {
"stringValue": "dd"
},
"desc": {
"stringValue": "ee"
}
},
"createTime": "2020-10-31T08:57:46.799862Z",
"updateTime": "2020-10-31T08:57:46.799862Z"
},
]
}
I am using Firebase Firestore Rest Api. I have the output in json format like above. I created my model using Json to dart. My model is as follows.
class Model {
List<Documents> documents;
Model({this.documents});
Model.fromJson(Map<String, dynamic> json) {
if (json['documents'] != null) {
documents = new List<Documents>();
json['documents'].forEach((v) {
documents.add(new Documents.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.documents != null) {
data['documents'] = this.documents.map((v) => v.toJson()).toList();
}
return data;
}
}
class Documents {
String name;
Fields fields;
String createTime;
String updateTime;
Documents({this.name, this.fields, this.createTime, this.updateTime});
Documents.fromJson(Map<String, dynamic> json) {
name = json['name'];
fields =
json['fields'] != null ? new Fields.fromJson(json['fields']) : null;
createTime = json['createTime'];
updateTime = json['updateTime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
if (this.fields != null) {
data['fields'] = this.fields.toJson();
}
data['createTime'] = this.createTime;
data['updateTime'] = this.updateTime;
return data;
}
}
......
return jsonModel.map((item) => model.fromJson(item)).toList(); I returned it as but in FutureBuilder it comes as snapshot.data[index].documents.
How do I access the imgUrl, authorName, title, desc fields? I am having difficulty with this kind of mixed json output. Can you help me?

You can make a nested structure listView, and you access to field models.
First way:
return FutureBuilder<List<Document>>(
future: getDocuments(),
builder: (BuildContext context, AsyncSnapshot<List<Document>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return buildListView(snapshot.data[index].documents);
},
);
} else {
return Text("error");
}
},
);
And you do sub inner method then draw.
ListView buildListView(List<Documents> documents) {
return ListView.builder(
itemCount: documents.length,
itemBuilder: (context, index) => ListTile(
title: Text(documents[index].name),
leading: Text(documents[index].fields.imgUrl.stringValue),
subtitle: Text(documents[index].fields.desc.stringValue),
),
);
2.You could be convert list to list model with list expand functions.
Future<List<Document>> getDocuments() async {
await Future.delayed(Duration(seconds: 100));
return dummyItems;
}
Future<List<Documents>> getFieldsOnly() async {
final response = await getDocuments();
return response.expand((f) => f.documents).toList();
}
Now, it's all done. You can look at this repo for more details(lib/fire-store-document)

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();
},
);
}
}

How to parse in nested json array in ListView.Builder in Flutter

I'm calling an api which returns a nested json array list and when i try to display an id of table_photos inside listview.builder then it is displaying only id:1. I want to display all three id's which is id:1,id:11,id:12 inside listview.builder. Below is the sample json along with the code and MainPage.dart i'm displaying only short code due to the long file
JSON
{
"message": "Tables returend",
"tables": [
{
"id": "7"
"table_photos": [
{
"id": "7"
}
]
},
{
"id": "6",
"table_photos": [
{
"id": "1"
},
{
"id": "11"
},
{
"id": "12"
}
]
}
]
}
Model
class TableGenerateTablesTablePhotos {
String? id;
TableGenerateTablesTablePhotos({
this.id,
});
TableGenerateTablesTablePhotos.fromJson(Map<String, dynamic> json) {
id = json["id"]?.toString();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
return data;
}
}
class TableGenerateTables {
String? id;
List<TableGenerateTablesTablePhotos?>? tablePhotos;
TableGenerateTables({
this.id,
this.tablePhotos,
});
TableGenerateTables.fromJson(Map<String, dynamic> json) {
id = json["id"]?.toString();
if (json["table_photos"] != null) {
final v = json["table_photos"];
final arr0 = <TableGenerateTablesTablePhotos>[];
v.forEach((v) {
arr0.add(TableGenerateTablesTablePhotos.fromJson(v));
});
tablePhotos = arr0;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
if (tablePhotos != null) {
final v = tablePhotos;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data["table_photos"] = arr0;
}
return data;
}
}
class TableGenerate {
String? message;
List<TableGenerateTables?>? tables;
TableGenerate({
this.message,
this.tables,
});
TableGenerate.fromJson(Map<String, dynamic> json) {
message = json["message"]?.toString();
if (json["tables"] != null) {
final v = json["tables"];
final arr0 = <TableGenerateTables>[];
v.forEach((v) {
arr0.add(TableGenerateTables.fromJson(v));
});
tables = arr0;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["message"] = message;
if (tables != null) {
final v = tables;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data["tables"] = arr0;
}
return data;
}
}
Repository
class Repository{
Future<List< TableGenerateTables >?> makeRequestTables(int id, int count) async {
var response = await http.get(
Uri.parse('API_URL'));
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
List< TableGenerateTables >? tables =
TableGenerate.fromJson(data).tables as List< TableGenerateTables >;
return tables;
} else {
throw Exception();
}
}
}
MainPage.dart
Widget showTable(List<TablesTables> data) {
return ListView.builder(
shrinkWrap: true,
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(data[index].tablePhotos![index]!.id!), //It is displaying "1"
],
),
);
});
}

How to call nested json data using API in flutter?

My JSON looks like this:
{
Info: [
{
c_type_id: "1",
cleaning type: "A Cleaning"
},
{
c_type_id: "2",
cleaning type: "B Cleaning"
},
{
c_type_id: "3",
cleaning type: "C Cleaning"
},
{
c_type_id: "4",
cleaning type: "D Cleaning"
},
{
c_type_id: "5",
cleaning type: "E Cleaning"
},
]
}
and here is the code:
The following code is created by this
Class 1:
class Album {
List<Info> info;
Album({this.info})
Album.fromJson(Map<String, dynamic> json) {
if (json['Info'] != null) {
info = List<Info>.empty();
json['Info'].forEach((v) {
info.add(new Info.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.info != null) {
data['Info'] = this.info.map((v) => v.toJson()).toList();
}
return data;
}
}
class 2:
class Info {
String cTypeId;
String cleaningType;
Info({this.cTypeId, this.cleaningType});
Info.fromJson(Map<String, dynamic> json) {
cTypeId = json['c_type_id'];
cleaningType = json['cleaning type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['c_type_id'] = this.cTypeId;
data['cleaning type'] = this.cleaningType;
return data;
}
}
This is the error I get when I execute the code:
error: The argument type 'List' can't be assigned to the parameter type 'String'.
Hoping for help!
You should Try below code your problem has been solved ->
Declare your API Call funtion
Future<List<dynamic>> getInfoData() async {
String url = 'https://fillmmaka.com/gigocleanapi/cleanintypes.php';
var response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
return json.decode(response.body)['Info'];
}
Declare your Widget
Center(
child: FutureBuilder<List<dynamic>>(
future: getInfoData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
var id = snapshot.data[index]['c_type_id'];
var type = snapshot.data[index]['cleaning type'];
return Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.green.shade300,
),
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: Text(id),
title: Text(type),
),
);
},
),
);
}
return CircularProgressIndicator();
},
),
),
Your Screen look like this ->
What is your goal? What do you want to show on the screen?
For example, do you want to show a list with all the cleaning types?
You are getting this error because the attribute info in your Album class is a List:
class Album {
List<Info> info;
If you want to show the cleaningType of the first info on the list, you may do something like this:
return Text(snapshot.data.info[0].cleaningType);
Just keep in mind this will crash if the info list is empty.
you are trying to access the whole list there just use snapshot.data.info[index].variableName you want to access
and you will be good to go

How to store complex json data in model class in flutter

Here is my code"
I've tried printing values.
I got value in token.
I'm able to iterate through the each value present in API using for each loop but data isn't storing into my model class.
SharedPreferences prefs = await SharedPreferences.getInstance();
final token = prefs.getString("token") ?? null;
final userId = prefs.getInt("id") ?? null;
List<GroupListData> grpDataList = [];
if (token != null) {
String url = "${NetworkRequest.baseUrl}/api/group_list";
var groupRes = await http.post(Uri.parse(url), body: {
"user_id": '$userId'
}, headers: {
//'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
//print(groupRes.body);
if (groupRes.statusCode == 200) {
final rowJsonData = jsonDecode(groupRes.body);
GroupListData groupListData;
List<dynamic> groupLists = rowJsonData['data'];
groupLists.forEach((d) {
print(d['id']);
groupListData = GroupListData(
id: d['id'],
groupName: d["groupName"],
status: d["status"],
createdAt: d["createdAt"],
updatedAt: d["updatedAt"],
);
grpDataList.add(groupListData);
});
for (var d in rowJsonData['data']) {
print(d);
}
} else {
print('grpResp ${groupRes.statusCode}');
}
//print('Token : $token');
} else {
print('token is empty');
}
print(grpDataList);
return grpDataList;
}
here this is my JSON Data
{
"data": [
{
"id": 1,
"group_name": "payroll",
"status": 1,
"created_at": "2021-07-20 08:27:31",
"updated_at": "2021-07-20 10:09:11"
},
{
"id": 2,
"group_name": "New Recuritment",
"status": 1,
"created_at": "2021-07-20 11:21:40",
"updated_at": "2021-07-20 11:21:40"
}
],
"message": "Data Found",
"status": 200
}
here is my model class
i think that there is issue in my model class
i am not able to understand
class GroupListData {
GroupListData({
this.id,
this.groupName,
this.status,
this.createdAt,
this.updatedAt,
});
int? id;
String? groupName;
int? status;
DateTime? createdAt;
DateTime? updatedAt;
factory GroupListData.fromJson(Map<String, dynamic> json) => GroupListData(
id: json["id"],
groupName: json["group_name"],
status: json["status"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"group_name": groupName,
"status": status,
"created_at": createdAt!.toIso8601String(),
"updated_at": updatedAt!.toIso8601String(),
};
}
here is my ui code
FutureBuilder<List<GroupListData>>(
future: getGroupListData(),
builder: (BuildContext context,
AsyncSnapshot<List<GroupListData>> snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text('Loading...'),
),
);
}
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data!.length,
itemBuilder: (BuildContext context, int index) {
return RoundedCard(
str: '${snapshot.data![index].groupName}', ///.groupName always return null value
onTap: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: FeedPage(feedTitle: 'Marketing Team'),
inheritTheme: true,
ctx: context),
);
print('Marketing card');
});
});
},
),
thanks in advance
You dont need to convert your json to modal by yourself.
if the Flutter SDK < 2.0 (Null safety) then please use this online json converter https://javiercbk.github.io/json_to_dart/
otherwise use this online json Converter for Flutter > 2.0 https://app.quicktype.io/

flutter rest api get json

I just started using flutter. I have a rest api service that I wrote with nodejs. below is producing the output "result.json". I am trying to access this with flutter.
Connecting to the server.
Getting json data from server.
But I cannot take this into card. can you help me ?
Customers.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:hasta_takip/models/customers_model.dart';
import 'package:http/http.dart' as http;
class Customers extends StatefulWidget {
#override
_CustomersState createState() => _CustomersState();
}
class _CustomersState extends State<Customers> {
Future<List<CustomersModel>> _fetchCustomers() async {
var response = await http.get("http://localhost:3000/customers");
if (response.statusCode == 200) {
return (json.decode(response.body))
.map((e) => CustomersModel.fromJson(e))
.toList();
} else {
throw Exception("not connected ${response.statusCode}");
}
}
#override
void initState() {
super.initState();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Customer list"),
),
body: FutureBuilder(
future: _fetchCustomers(),
builder: (BuildContext context,
AsyncSnapshot<List<CustomersModel>> snapshot) {
print(snapshot.data);
if (snapshot.hasData) {
print(snapshot);
return ListView.builder(
//itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile();
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
CustomersModel.dart
import 'dart:convert';
CustomersModel customersModelFromJson(String str) => CustomersModel.fromJson(json.decode(str));
String customersModelToJson(CustomersModel data) => json.encode(data.toJson());
class CustomersModel {
CustomersModel({
this.result,
});
List<Result> result;
factory CustomersModel.fromJson(Map<String, dynamic> json) => CustomersModel(
result: List<Result>.from(json["result"].map((x) => Result.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"result": List<dynamic>.from(result.map((x) => x.toJson())),
};
}
class Result {
Result({
this.id,
this.customerName,
this.customerLastname,
});
int id;
String customerName;
String customerLastname;
factory Result.fromJson(Map<String, dynamic> json) => Result(
id: json["id"],
customerName: json["customer_name"],
customerLastname: json["customer_lastname"],
);
Map<String, dynamic> toJson() => {
"id": id,
"customer_name": customerName,
"customer_lastname": customerLastname,
};
}
Result.json
{
"result": [
{
"id": 1,
"customer_name": "John",
"customer_lastname": "simon"
},
{
"id": 2,
"customer_name": "peter",
"customer_lastname": "bratt"
}
]
}
Change the _fetchCustomer() with below
Future<CustomersModel> _fetchCustomers() async { // this line
var response = await http.get("http://localhost:3000/customers");
if (response.statusCode == 200) {
return customersModelFromJson(response.body); // this line
} else {
throw Exception("not connected ${response.statusCode}");
}
}
And change your FutureBuilder with below
FutureBuilder(
future: _fetchCustomers(),
builder: (BuildContext context,
AsyncSnapshot<CustomersModel> snapshot) { // this line
print(snapshot.data);
if (snapshot.hasData) {
print(snapshot);
return ListView.builder(
itemCount: snapshot.data.result.length, // this line
itemBuilder: (context, index) {
return ListTile();
});
} else {
return Center(child: CircularProgressIndicator());
}
},
)