Adding data to a json file in dart - json

I have a Json file having some user data as an array , I am able to read those data in my flutter project , But what I wanna do is to add some other user from the data I receive from the textfield in my flutter app.
Can anyone tell me how to do that ? Thanks in advance.
My Json file looks something like this.
{
"users": [
{
"id": 1,
"username": "steve",
"password": "captainamerica"
}
]
}
and I have to add another user with id - 2, username - tony, and password - ironman.

I have tried showing you how to map the JSON to OBJECT and then add a new user to the users object and then to JSON again.
Here's the complete code:
If you have any doubts, please ask:
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
UsersPodo _usersPodo; // Users object to store users from json
// A function that converts a response body into a UsersPodo
UsersPodo parseJson(String responseBody) {
final parsed = json.decode(responseBody);
return UsersPodo.fromJson(parsed);
}
class Demo extends StatefulWidget {
#override
_Demo createState() => _Demo();
}
class _Demo extends State<Demo> {
final String localJson = '''
{
"users": [
{
"id": 1,
"username": "steve",
"password": "captainamerica"
}
]
}'''; // local json string
Future<UsersPodo> fetchJSON() async {
return compute(parseJson, localJson);
}
Widget body() {
return FutureBuilder<UsersPodo>(
future: fetchJSON(),
builder: (context, snapshot) {
return snapshot.hasError
? Center(child: Text(snapshot.error.toString()))
: snapshot.hasData
? _buildBody(usersList: snapshot.data)
: Center(child: Text("Loading"));
},
);
}
Widget _buildBody({UsersPodo usersList}) {
_usersPodo = usersList;
_usersPodo.users.add(new Users(id: 1, username: "omishah", password: "somepassword")); // add new user to users array
return Text(_usersPodo.users[1].toJson().toString()); // just for the demo output
// use _usersPodo.toJson() to convert the users object to json
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xfff3f3f3),
appBar: AppBar(backgroundColor: Colors.red[900], title: Text("DEMO")),
body: body());
}
}
// PODO Object class for the JSON mapping
class UsersPodo {
List<Users> users;
UsersPodo({this.users});
UsersPodo.fromJson(Map<String, dynamic> json) {
if (json['users'] != null) {
users = new List<Users>();
json['users'].forEach((v) {
users.add(new Users.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.users != null) {
data['users'] = this.users.map((v) => v.toJson()).toList();
}
return data;
}
}
class Users {
int id;
String username;
String password;
Users({this.id, this.username, this.password});
Users.fromJson(Map<String, dynamic> json) {
id = json['id'];
username = json['username'];
password = json['password'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['username'] = this.username;
data['password'] = this.password;
return data;
}
}

Related

How to get json response in flutter using POST method?

I am beginner in flutter. Please help me get and set below json data into model in flutter. I am using POST method.
'''
{
"success": 1,
"data": {
"user_id": 2,
"email": "ajay.singhal#ollosoft1.com",
"phone": "9414905280",
"password": "1436a615e62482ba4f075c1d4a4fd94b",
"account_status": "Active",
"date_of_birth": "1953-09-07T00:00:00.000Z",
"address": "Jaipur Rajasthan",
"profile_url": "http://18.217.236.99:4200/assets/profile_img/2/RBI-keeps-policy-rate-unchanged-1.jpg",
"first_name": "Ajay",
"last_name": "singhal"
}
}
'''
Below is my Model class named UserInfoModel
import 'UserInfoDataModel.dart';
class UserInfoModel {
final int success;
final UserInfoDataModel data;
UserInfoModel(this.success, this.data);
factory UserInfoModel.fromJson(dynamic json) {
if (json['data'] != null) {
var tagObjsJson = json['data'];
UserInfoDataModel _tags =
tagObjsJson.map((tagJson) => UserInfoDataModel.fromJson(tagJson));
return UserInfoModel(json['success'] as int, _tags);
}
}
#override
String toString() {
return '{${this.success}, ${this.data}}';
}
}
Below is submodel name is UserInfoDataModel
import 'package:flutter/material.dart';
class UserInfoDataModel {
int user_id;
String email;
String phone;
String password;
String account_status;
String date_of_birth;
String address;
String profile_url;
String first_name;
String last_name;
UserInfoDataModel(
{this.user_id,
this.email,
this.phone,
this.password,
this.account_status,
this.date_of_birth,
this.address,
this.profile_url,
this.first_name,
this.last_name});
factory UserInfoDataModel.fromJson(Map<String, dynamic> json) {
return UserInfoDataModel(
user_id: json['user_id'] as int,
email: json['email'],
phone: json['phone'],
password: json['password'],
account_status: json['account_status'],
date_of_birth: json['date_of_birth'],
address: json['address'],
profile_url: json['profile_url'],
first_name: json['first_name'],
last_name: json['last_name'],
);
}
}
My APi Call is below Using POST Method
I am successfully getting response, but unable to set in model
UserInfoModel _userInfoModel;
UserInfoDataModel _userInfoDataModel;
String url = BaseURLHeaders().getBaseURl() + "userInfo";
Map headers = BaseURLHeaders().getHeader();
#override
void initState() {
// TODO: implement initState
super.initState();
getData();
}
Future<UserInfoModel> getData() async {
String user_id = "1";
var mapData = new Map<String, dynamic>();
mapData['user_id'] = user_id;
// mapData['first_name'] = firstName;
var response = await http.post(
url,
headers: headers,
body: mapData,
);
setState(() {
print("userInfoDetails: ${response.body}");
print("urlTop: ${url}");
print("headersTop: ${headers}");
print("responseCode: ${response.statusCode}");
});
if (response.statusCode == 200) {
var res = json.decode(response.body);
_userInfoModel = UserInfoModel.fromJson(res);
if (_userInfoModel.success == 1) {
var data = res["data"];
setState(() {
print("responseBody: ${res}");
print("userInfoSuccess: ${_userInfoModel.success}");
print("dataVaalue: ${data["email"]}");
print("urlBelow: ${url}");
print("headersBelow: ${headers}");
});
}
}
}
UserInfoDataModel _tags =
tagObjsJson.map((tagJson) => UserInfoDataModel.fromJson(tagJson));
here you are actually treated tagObjsJson as a list. but it is a JsonObject so there you don't want the map function.
you can access the object as
UserInfoDataModel _tags =UserInfoDataModel.fromJson(tagJson);
You can use json_serializer in flutter. See flutter docs.
If you use IntelliJ IDEA, you can use DartToJson package. It generates automatically for you and you can use fromJson and toJson method.

How to convert List<CustomModel> to Map<String,dynamic> in Flutter

I'm using HydratedBloc in Flutter. In order to work with HydratedBloc, I need to convert my custom List(parsed from JSON string) List<List<Category>> to Map<String, dynamic>. Here is the model that I'm using to parse my json string
import 'dart:convert';
List<List<Category>> rpTrendingCategoriesFromJson(String str) => List<List<Category>>.from(json.decode(str).map((x) => List<Category>.from(x.map((x) => Category.fromJson(x)))));
String rpTrendingCategoriesToJson(List<List<Category>> data) => json.encode(List<dynamic>.from(data.map((x) => List<dynamic>.from(x.map((x) => x.toJson())))));
class Category {
Category({
this.title,
this.imageLink,
});
String title;
String imageLink;
factory Category.fromJson(Map<String, dynamic> json) => Category(
title: json["title"] == null ? null : json["title"],
imageLink: json["imageLink"] == null ? null : json["imageLink"],
);
Map<String, dynamic> toJson() => {
"title": title == null ? null : title,
"imageLink": imageLink == null ? null : imageLink,
};
}
And here I need to convert that List<List<Category>> to Map<String, dynamic>
class TrendingCategoriesCubit extends Cubit<TrendingCategoriesState>
with HydratedMixin {
Repository repository;
TrendingCategoriesCubit({#required this.repository})
: super(TrendingCategoriesLoading());
Future<void> fetchTrendingCategories() async {
emit(TrendingCategoriesLoading());
List<List<Category>> categories =
await repository.fetchTrendingCategories();
if (categories.isEmpty) {
emit(TrendingCategoriesFetchedEmpty());
} else if (categories.isNotEmpty) {
emit(TrendingCategoriesFetched(categories: categories));
}
}
#override
TrendingCategoriesState fromJson(Map<String, dynamic> json) {
try {
final categories = rpTrendingCategoriesFromJson(json.toString());
return TrendingCategoriesFetched(categories: categories);
} catch (_) {
return null;
}
}
#override
Map<String, dynamic> toJson(TrendingCategoriesState state) {
if (state is TrendingCategoriesFetched) {
return state.categories.toJson(); //coudn't do it
} else {
return null;
}
}
}
If you look at the toJson() method above, I need to return List<List<Categor>> to Map<String,dynamic. How can I do it?
A simple workaround to achieve the desired result would be to just create a Map for the toJson/fromJson part of the Hydrated BLoC:
#override
TrendingCategoriesState fromJson(Map<String, dynamic> json) {
try {
final categoriesJson = json['categories'];
final categories = rpTrendingCategoriesFromJson(json.toString());
return TrendingCategoriesFetched(categories: categories);
} catch (_) {
return null;
}
}
#override
Map<String, dynamic> toJson(TrendingCategoriesState state) {
if (state is TrendingCategoriesFetched) {
return <String, dynamic>{
'categories': state.categories.toJson(),
};
} else {
return null;
}
}
Just adjust the code a little bit for it to compile, but the general idea is to create a "temporary" Map object only to persist and restore the hydrated state.

get value from nested json array and check if it is empty or not in flutter

My json array looks like:
[
{
"sub_categories": [],
"category_id": "82",
"catgory_name": "Andrew Murray 1 Month",
"parent_cat_id": "1"
},
{
"sub_categories": [
{
"category_id": "177",
"catgory_name": "2 Samuel",
"parent_cat_id": "167"
}
],
"category_id": "167",
"catgory_name": "The Bible ASV",
"parent_cat_id": "1"
},
]
First i want to display "catgory_name" in listview and if that catgory_name has sub_categories array than i need to display it in another list , so how can i achieve this.
i get all catgory_name by following code:
class CategoryModel {
final String name;
final List<SubCategoryModel> SubCategory;
CategoryModel({
this.name,
this.SubCategory,
});
factory CategoryModel.fromJson(Map<String, dynamic> json) {
return new CategoryModel(
name: json['catgory_name'].toString(),
SubCategory: parsesub_categories(json['sub_categories']),
// SubCategory:(json['sub_categories'] as List).map((map) => map).toList(),
);
}
static List<SubCategoryModel> parsesub_categories(cateJson) {
List<SubCategoryModel> catlist = new List<SubCategoryModel>.from(cateJson);
return catlist;
}
but sub_categories i could not get that array .
You can create data model as below:
class CategoryModel {
List<SubCateogryModel> subCategories;
String categoryId;
String catgoryName;
String parentCatId;
CategoryModel(
{this.subCategories,
this.categoryId,
this.catgoryName,
this.parentCatId});
CategoryModel.fromJson(Map<String, dynamic> json) {
if (json['sub_categories'] != null) {
subCategories = new List<SubCateogryModel>();
json['sub_categories'].forEach((v) {
subCategories.add(new SubCateogryModel.fromJson(v));
});
}
categoryId = json['category_id'];
catgoryName = json['catgory_name'];
parentCatId = json['parent_cat_id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.subCategories != null) {
data['sub_categories'] =
this.subCategories.map((v) => v.toJson()).toList();
}
data['category_id'] = this.categoryId;
data['catgory_name'] = this.catgoryName;
data['parent_cat_id'] = this.parentCatId;
return data;
}
}
class SubCateogryModel {
String categoryId;
String catgoryName;
String parentCatId;
SubCateogryModel({this.categoryId, this.catgoryName, this.parentCatId});
SubCateogryModel.fromJson(Map<String, dynamic> json) {
categoryId = json['category_id'];
catgoryName = json['catgory_name'];
parentCatId = json['parent_cat_id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['category_id'] = this.categoryId;
data['catgory_name'] = this.catgoryName;
data['parent_cat_id'] = this.parentCatId;
return data;
}
}
Now, you have to parse your json array into Data model array
List<CategoryModel> categoryList = [];
jsonArray.forEach((val){
categoryList.add(CategoryModel.fromJson(val));
});
Now, the UI code,
ListView.builder(
itemBuilder: (context, index) {
return ListTile(
title: Text(categoryList[index].catgoryName),
subtitle: categoryList[index].subCategories.isNotEmpty
? Column(
children: List.generate(
categoryList[index].subCategories.length, (position) {
String subCategory = categoryList[index]
.subCategories[position]
.catgoryName;
return Text(subCategory);
}),
)
: SizedBox(),
);
},
itemCount: categoryList.length,
)
You can use QuickType.io to generate dart classes (PODOs) for json.
import 'dart:convert';
List<CategoryModel> categoryModelFromJson(String str) => List<CategoryModel>.from(json.decode(str).map((x) => CategoryModel.fromJson(x)));
String categoryModelToJson(List<CategoryModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class CategoryModel {
List<CategoryModel> subCategories;
String categoryId;
String catgoryName;
String parentCatId;
CategoryModel({
this.subCategories,
this.categoryId,
this.catgoryName,
this.parentCatId,
});
factory CategoryModel.fromJson(Map<String, dynamic> json) => CategoryModel(
subCategories: json["sub_categories"] == null ? null : List<CategoryModel>.from(json["sub_categories"].map((x) => CategoryModel.fromJson(x))),
categoryId: json["category_id"],
catgoryName: json["catgory_name"],
parentCatId: json["parent_cat_id"],
);
Map<String, dynamic> toJson() => {
"sub_categories": subCategories == null ? null : List<dynamic>.from(subCategories.map((x) => x.toJson())),
"category_id": categoryId,
"catgory_name": catgoryName,
"parent_cat_id": parentCatId,
};
}

flutter : nested json parsing list

I am trying to call Name and Fees from my json code
it is nested array from main array of my json the main array i can deal with it but the sub array i can't
"guideExtraServices": [
{
"Name": "Limousine",
"Fees": 100
},
{
"Name": "Bus",
"Fees": 10000
},
{
"Name": "Mini-Bus",
"Fees": 5000
}
],
And I can't do that because of the error here when iam tring to call 'Name' and 'Fees'
type 'List<ExtraServices>' is not a subtype of type 'String'
and this is my class for mapping tour guide data to use it in list view
class TourGuide{
String id;
String name;
String email;
String password;
List<ExtraServices> extraService;
TourGuide({
this.id,
this.name,
this.email,
this.password,
this.extraService,
});
TourGuide.fromJson(Map<String, dynamic> json){
List<dynamic> extra = json['guideExtraServices'];
List<ExtraServices> extraList = extra.map((i) => ExtraServices.fromJson(i)).toList();
id = json['id'].toString();
name = json['displayName'];
email = json['email'];
password = json['password'];
extraService=extraList;
}
}
and this is a Extra Services class which tour guide class depend on to get the sub array
class ExtraServices{
String name;
double fees;
ExtraServices({
this.name,
this.fees
});
ExtraServices.fromJson(Map<String, dynamic> json){
name = json['Name'];
fees = json['Fees'].toDouble();
}
}
my provider method for decode json using for api
Future<dynamic> tourGuideList() async {
_isLoading = true;
notifyListeners();
print('Starting request');
http.Response response = await http.get(Environment.tourGuide,
headers: Environment.requestHeader);
print('Completed request');
print('respond data : ${response.body}');
Map<String, dynamic> res = json.decode(response.body);
var results;
if (res['code'] == 200) {
print('start load tourguide');
_tourGuide = [];
res['message'].forEach((v) {
_tourGuide.add(new TourGuide.fromJson(v));
});
results = true;
} else {
results =
FailedRequest(code: 400, message: res['error'], status: false);
}
_isLoading = false;
notifyListeners();
return results;
}
and I don't know why I have an error and I can't fix it
I think your json should be like this in total:
{"guideExtraServices": [
{
"Name": "Limousine",
"Fees": 100
},
{
"Name": "Bus",
"Fees": 10000
},
{
"Name": "Mini-Bus",
"Fees": 5000
}
]}
Try
// To parse this JSON data, do
//
// final tourGuide = tourGuideFromJson(jsonString);
import 'dart:convert';
TourGuide tourGuideFromJson(String str) => TourGuide.fromJson(json.decode(str));
String tourGuideToJson(TourGuide data) => json.encode(data.toJson());
class TourGuide {
List<GuideExtraService> guideExtraServices;
TourGuide({
this.guideExtraServices,
});
factory TourGuide.fromJson(Map<String, dynamic> json) => TourGuide(
guideExtraServices: List<GuideExtraService>.from(json["guideExtraServices"].map((x) => GuideExtraService.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"guideExtraServices": List<dynamic>.from(guideExtraServices.map((x) => x.toJson())),
};
}
class GuideExtraService {
String name;
int fees;
GuideExtraService({
this.name,
this.fees,
});
factory GuideExtraService.fromJson(Map<String, dynamic> json) => GuideExtraService(
name: json["Name"],
fees: json["Fees"],
);
Map<String, dynamic> toJson() => {
"Name": name,
"Fees": fees,
};
}
Please try the below code :-
First Create Model :-
class GuideResponseModel {
List<GuideExtraServicesModel> guideExtraServiceList;
GuideResponseModel({
this.guideExtraServiceList
});
factory GuideResponseModel.fromJson(Map<String, dynamic> parsedJson) {
try {
List<GuideExtraServicesModel> guideExtraServiceModelList = new List();
if (parsedJson.containsKey('guideExtraServices')) {
var countryList = parsedJson['guideExtraServices'] as List;
guideExtraServiceModelList =
countryList.map((i) => GuideExtraServicesModel.fromJson(i)).toList();
}
return GuideResponseModel(
guideExtraServiceList: guideExtraServiceModelList
);
} catch (e) {
return null;
}
}
}
class GuideExtraServicesModel {
String name;
int fees;
GuideExtraServicesModel({this.name,this.fees});
factory GuideExtraServicesModel.fromJson(Map<String, dynamic> json) {
return GuideExtraServicesModel(name: json['Name'],fees: json['Fees']);
}
}
Second User the Model:-
String jsonData = '{"guideExtraServices": [{"Name": "Limousine","Fees": 100},{"Name": "Bus","Fees": 10000},{"Name": "Mini-Bus","Fees": 5000}]}';
final dynamic jsonResponse = json.decode(jsonData);
final GuideResponseModel responseModel = GuideResponseModel.fromJson(jsonResponse);
print('======${responseModel.guideExtraServiceList[0].name}----${responseModel.guideExtraServiceList[0].fees}');

Flutter and Distance Matrix API parsing json

I am currently building a flutter app where I want to calculate the distance between some objects and am using the Google Distance Matrix API to do so. I am having trouble parsing the json using Dart. All I want ultimately is a list of the distances from the json results so that I can index them and apply them to the data in my app.
The json results look like this:
{
"destination_addresses" : [
"destination address",
"destination address"
],
"origin_addresses" : [ "Origin addresses here" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "4.3 mi",
"value" : 6998
},
"duration" : {
"text" : "14 mins",
"value" : 848
},
"status" : "OK"
},
{
"distance" : {
"text" : "6.7 mi",
"value" : 10728
},
"duration" : {
"text" : "22 mins",
"value" : 1327
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
I ultimately would like to end up with a list (in dart) that is just a list of the distance "text" values within the elements array but I am having trouble getting this to return. I have tried creating a class and mapping the json results to this but unsuccesfully as I am not very good at parsing json so any advice on how to end up with this list would be gratefully received!
I have tried this code to parse the json but am really struggling to make it work and then apply it:
class Topleveladd {
final String elements;
Topleveladd({this.elements});
factory Topleveladd.fromJson(Map<String, dynamic> parsedJson) {
return Topleveladd(elements: parsedJson['rows']);
}
}
class Elements {
List<Distance> distanceslist;
Elements({this.distanceslist});
factory Elements.fromJson(Map<String, dynamic> parsedJson) {
var list = parsedJson['elements'] as List;
print(list.runtimeType); //returns List<dynamic>
List<Distance> distancesList =
list.map((i) => Distance.fromJson(i)).toList();
return Elements(distanceslist: distancesList);
}
}
class Distance {
String text;
Distance({this.text});
factory Distance.fromJson(Map<String, dynamic> parsedJson) {
return new Distance(
text: parsedJson['distance'],
);
}
}
Okay this is it working with me accessing the JSON you've given as an asset so you'll probably have to change the loadData method for it to fit your needs.
DistanceMatrix class:
import 'dart:convert';
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
class DistanceMatrix {
final List<String> destinations;
final List<String> origins;
final List<Element> elements;
final String status;
DistanceMatrix({this.destinations, this.origins, this.elements, this.status});
factory DistanceMatrix.fromJson(Map<String, dynamic> json) {
var destinationsJson = json['destination_addresses'];
var originsJson = json['origin_addresses'];
var rowsJson = json['rows'][0]['elements'] as List;
return DistanceMatrix(
destinations: destinationsJson.cast<String>(),
origins: originsJson.cast<String>(),
elements: rowsJson.map((i) => new Element.fromJson(i)).toList(),
status: json['status']);
}
static Future<DistanceMatrix> loadData() async {
DistanceMatrix distanceMatrix;
try{
String jsonData = await rootBundle.loadString('assets/data.json');
distanceMatrix = new DistanceMatrix.fromJson(json.decode(jsonData));
} catch (e){
print(e);
}
return distanceMatrix;
}
}
class Element {
final Distance distance;
final Duration duration;
final String status;
Element({this.distance, this.duration, this.status});
factory Element.fromJson(Map<String, dynamic> json) {
return Element(
distance: new Distance.fromJson(json['distance']),
duration: new Duration.fromJson(json['duration']),
status: json['status']);
}
}
class Distance {
final String text;
final int value;
Distance({this.text, this.value});
factory Distance.fromJson(Map<String, dynamic> json) {
return new Distance(text: json['text'], value: json['value']);
}
}
class Duration {
final String text;
final int value;
Duration({this.text, this.value});
factory Duration.fromJson(Map<String, dynamic> json) {
return new Duration(text: json['text'], value: json['value']);
}
}
Main.dart which uses ListView.builder to display the distances text and values as a ListTile:
import 'package:flutter/material.dart';
import 'package:hello_world/distance_matrix.dart';
void main() async {
runApp(new MyApp(
distanceMatrix: await DistanceMatrix.loadData(),
));
}
class MyApp extends StatefulWidget {
final DistanceMatrix distanceMatrix;
#override
_MyAppState createState() => new _MyAppState();
MyApp({this.distanceMatrix});
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Material(
child: ListView.builder(
itemCount: widget.distanceMatrix.elements.length,
itemBuilder: (context, index){
return ListTile(
title: Text(widget.distanceMatrix.elements[index].distance.text),
subtitle: Text(widget.distanceMatrix.elements[index].distance.value.toString()),
);
},
)
)));
}
}
Image to show what you should get: