i create flutter app which use the api from server when i get the JSON response from the server I parse the response and retrieve the sicke, serviceName, date, user, status and some more information about sicks, The problem is that some sicks in the JSON response don't have the doctororder key or medicalImagingOrder key and has diffrent key . When I try to get those JSON key values the program throws an error how i should handel this in the flutter?
this is how i create my object
class Datum {
Datum({
this.id,
this.sicke,
this.serviceName,
this.doctorOrder,
this.date,
this.user,
this.statusNumber,
this.status,
this.statusHistory,
this.insertDate,
this.statuses,
this.excessInvoice,
this.price,
this.shippingCosts,
this.vat,
this.netPrice,
this.totalPrice,
this.orderNumber,
this.v,
this.cancleReason,
this.medicalImagingOrder,
this.laboratoryOrder,
this.serviceProvider,
this.nurseOrder,
});
String id;
Sicke sicke;
String serviceName;
DoctorOrder doctorOrder;
DateTime date;
User user;
int statusNumber;
StatusEnum status;
List<StatusHistory> statusHistory;
DateTime insertDate;
List<StatusElement> statuses;
List<dynamic> excessInvoice;
int price;
int shippingCosts;
int vat;
int netPrice;
int totalPrice;
int orderNumber;
int v;
String cancleReason;
Order medicalImagingOrder;
LaboratoryOrder laboratoryOrder;
String serviceProvider;
Order nurseOrder;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["_id"],
sicke: json["sicke"] == null ? null : Sicke.fromJson(json["sicke"]),
serviceName: json["serviceName"],
doctorOrder: json["doctorOrder"] == null ? null : DoctorOrder.fromJson(json["doctorOrder"]),
date: DateTime.parse(json["date"]),
user: userValues.map[json["user"]],
statusNumber: json["statusNumber"],
status: statusEnumValues.map[json["status"]],
statusHistory: List<StatusHistory>.from(json["statusHistory"].map((x) => StatusHistory.fromJson(x))),
insertDate: DateTime.parse(json["insertDate"]),
statuses: List<StatusElement>.from(json["statuses"].map((x) => StatusElement.fromJson(x))),
excessInvoice: List<dynamic>.from(json["excessInvoice"].map((x) => x)),
price: json["price"],
shippingCosts: json["shippingCosts"],
vat: json["VAT"],
netPrice: json["netPrice"],
totalPrice: json["totalPrice"],
orderNumber: json["orderNumber"],
v: json["__v"],
cancleReason: json["cancleReason"] == null ? null : json["cancleReason"],
medicalImagingOrder: json["medicalImagingOrder"] == null ? null : Order.fromJson(json["medicalImagingOrder"]),
laboratoryOrder: json["laboratoryOrder"] == null ? null : LaboratoryOrder.fromJson(json["laboratoryOrder"]),
serviceProvider: json["serviceProvider"] == null ? null : json["serviceProvider"],
nurseOrder: json["nurseOrder"] == null ? null : Order.fromJson(json["nurseOrder"]),
);
and this is my json response
You have a list of Datum in your json response. So you can start with :
List<Datum> datumFromJson(String str) => List<Datum>.from(json.decode(str).map((x) => Datum.fromJson(x)));
String datumToJson(List<Datum> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
After that you can start the class:
class Datum {
Datum({
this.id,
this.sicke,
this.serviceName,
this.doctorOrder,
this.date,
this.user,
this.statusNumber,
this.status,
this.statusHistory,
this.insertDate,
this.statuses,
this.excessInvoice,
this.price,
this.shippingCosts,
this.vat,
this.netPrice,
this.totalPrice,
this.orderNumber,
this.v,
this.cancleReason,
this.medicalImagingOrder,
this.laboratoryOrder,
this.serviceProvider,
this.nurseOrder,
});
String id;
LaboratoryOrder sicke;
String serviceName;
String doctorOrder;
String date;
LaboratoryOrder user;
int statusNumber;
LaboratoryOrder status;
List<LaboratoryOrder> statusHistory;
String insertDate;
List<LaboratoryOrder> statuses;
List<LaboratoryOrder> excessInvoice;
int price;
int shippingCosts;
int vat;
int netPrice;
int totalPrice;
int orderNumber;
int v;
String cancleReason;
LaboratoryOrder medicalImagingOrder;
LaboratoryOrder laboratoryOrder;
String serviceProvider;
LaboratoryOrder nurseOrder;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
sicke: LaboratoryOrder.fromJson(json["sicke"]),
serviceName: json["serviceName"],
doctorOrder: json["doctorOrder"],
date: json["date"],
user: LaboratoryOrder.fromJson(json["user"]),
statusNumber: json["statusNumber"],
status: LaboratoryOrder.fromJson(json["status"]),
statusHistory: List<LaboratoryOrder>.from(json["statusHistory"].map((x) => LaboratoryOrder.fromJson(x))),
insertDate: json["insertDate"],
statuses: List<LaboratoryOrder>.from(json["statuses"].map((x) => LaboratoryOrder.fromJson(x))),
excessInvoice: List<LaboratoryOrder>.from(json["excessInvoice"].map((x) => LaboratoryOrder.fromJson(x))),
price: json["price"],
shippingCosts: json["shippingCosts"],
vat: json["vat"],
netPrice: json["netPrice"],
totalPrice: json["totalPrice"],
orderNumber: json["orderNumber"],
v: json["v"],
cancleReason: json["cancleReason"],
medicalImagingOrder: LaboratoryOrder.fromJson(json["medicalImagingOrder"]),
laboratoryOrder: LaboratoryOrder.fromJson(json["laboratoryOrder"]),
serviceProvider: json["serviceProvider"],
nurseOrder: LaboratoryOrder.fromJson(json["nurseOrder"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"sicke": sicke.toJson(),
"serviceName": serviceName,
"doctorOrder": doctorOrder,
"date": date,
"user": user.toJson(),
"statusNumber": statusNumber,
"status": status.toJson(),
"statusHistory": List<dynamic>.from(statusHistory.map((x) => x.toJson())),
"insertDate": insertDate,
"statuses": List<dynamic>.from(statuses.map((x) => x.toJson())),
"excessInvoice": List<dynamic>.from(excessInvoice.map((x) => x.toJson())),
"price": price,
"shippingCosts": shippingCosts,
"vat": vat,
"netPrice": netPrice,
"totalPrice": totalPrice,
"orderNumber": orderNumber,
"v": v,
"cancleReason": cancleReason,
"medicalImagingOrder": medicalImagingOrder.toJson(),
"laboratoryOrder": laboratoryOrder.toJson(),
"serviceProvider": serviceProvider,
"nurseOrder": nurseOrder.toJson(),
};}
And finaly a class of your specific objects:
class LaboratoryOrder {
LaboratoryOrder();
factory LaboratoryOrder.fromJson(Map<String, dynamic> json) => LaboratoryOrder(
);
Related
can anyone please help me?, I created a login function with api, when the user wants to login and succeeds then it is directed to the profilescreen the user details appear, but when it switches to the homescreen and switches to the profilescreen again, the user details that previously appeared are lost and become null.
I thought of using sharedpreferences to save user response data after login, but I don't know if it was saved or not
Future<LoginModels> postLogin(String email, String password) async {
var dio = Dio();
String baseurl = url;
Map<String, dynamic> data = {'email': email, 'password': password};
try {
final response = await dio.post(
'$baseurl/api/login',
data: data,
options: Options(headers: {'Content-type': 'application/json'}),
);
print('Respon -> ${response.data} + ${response.statusCode}');
if (response.statusCode == 200) {
final loginModel = LoginModels.fromJson(response.data);
return loginModel;
}
} catch (e) {
print('Error di $e');
}
return LoginModels();}
i tried adding sharedpreference in the part after response.statuscode == 200 , like this
SharedPreferences pref = await SharedPreferences.getInstance();
String jsonUser = jsonEncode(loginModel);
pref.setString('userDetail', jsonUser);
print('data nih $jsonUser');
and the output is like this
LoginModels loginModelsFromJson(String str) => LoginModels.fromJson(
json.decode(str),
);
String loginModelsToJson(LoginModels data) => json.encode(data.toJson());
class LoginModels {
LoginModels({
this.isActive,
this.message,
this.data,
});
bool? isActive;
String? message;
Data? data;
factory LoginModels.fromJson(Map<String, dynamic> json) => LoginModels(
isActive: json["is_active"],
message: json["message"],
data: Data.fromJson(json["data"]),
);
Map<String, dynamic> toJson() => {
"is_active": isActive,
"message": message,
"data": data?.toJson(),
};
}
class Data {
Data({
this.iduser,
this.nama,
this.profesi,
this.email,
this.password,
this.roleId,
this.isActive,
this.tanggalInput,
this.modified,
});
String? iduser;
String? nama;
String? profesi;
String? email;
String? password;
String? roleId;
String? isActive;
String? tanggalInput;
String? modified;
factory Data.fromJson(Map<String, dynamic> json) => Data(
iduser: json["iduser"],
nama: json["nama"],
profesi: json["profesi"],
email: json["email"],
password: json["password"],
roleId: json["role_id"],
isActive: json["is_active"],
tanggalInput: json["tanggal_input"],
modified: json["modified"],
);
Map<String, dynamic> toJson() => {
"iduser": iduser,
"nama": nama,
"profesi": profesi,
"email": email,
"password": password,
"role_id": roleId,
"is_active": isActive,
"tanggal_input": tanggalInput,
"modified": modified,
};
}
class User {
String? id;
String? nama;
String? profesi;
String? email;
String? password;
String? roleId;
String? isActive;
String? tanggalInput;
String? modified;
User();
User.fromJson(Map<String, dynamic> json)
: id = json["iduser"],
nama = json['nama'],
profesi = json['profesi'],
email = json['email'],
password = json['password'],
roleId = json['role_id'],
isActive = json['is_active'],
tanggalInput = json['tanggal_input'],
modified = json['modified'];
Map<String, dynamic> toJson() => {
'id': id,
'nama': nama,
'profesi': profesi,
'email': email,
'password': password,
'role_id': roleId,
'is_active': isActive,
'tanggal_input': tanggalInput,
'modified': modified,
};
}
if it is already stored how do I retrieve the data? or is there another alternative to solve the problem I have?
you can use key-value for store in pref. if u want to save user's email,name,id than store it like this (note:this is example of GetX)
//to store data
var storeUserData = Get.find<SharedPreferences>();
storeUserData.setString('use_name',userName);
// to retrive data
var userName = storeUserData.getString('use_name');
set this userName to your profilescreen's text and you are done.
While storing this in SharedPreferences call the toMap() method on the object This will return a Map<String, dynamic> representation of your current object.
Map<String, dynamic> productsMap = products.toMap();
After that Convert the object to String by using json.encode() and store it !
storedCart(productsMap){
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('userData', json.encode(productsMap));
}
you'll notice that when we convert our object to JSON it becomes a big String, Therefore it is possible for us to store it in SharedPreferences using the "putString()" method.
Also you can store single single value store in SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("user", token);
Also When you want to get data from sharedPref
you have to call
var value = prefs.getString(key);
After that you have to decode the value.
var decodeValue = json.decode(value)
final loginModel = LoginModels.fromJson(decodeValue).
after that you can find every data base on your model class
Don't forget to use .apply() once you update the fields in the code.
I am new in Flutter. I have tried to developed Model class in dart. but always show the error message
Exception:type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String', tt:#0 new User.fromJson
I don't understand, where my code will error. I want to solutions.
I want to convert model class in dart.
[
{
"route": {
"routeID": "aaaaaaaa",
"routeTitle": "bbbbbbbb"
},
"distributor": {
"distributorID": "cccccccccccc",
"distributorName": "ddddddddddd"
},
"visitDate": null
}
]
I have been tried to my source code. like below code
import 'dart:convert';
List<User> userFromJson(String str) =>
List<User>.from(json.decode(str).map((x) => User.fromJson(x)));
String userToJson(List<User> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class User {
User({
this.visitDate,
this.route,
this.distributor,
});
String visitDate;
String route;
String distributor;
factory User.fromJson(Map<String, dynamic> json) => User(
visitDate: json["visitDate"],
route: json["route"],
distributor: json["distributor"],
);
Map<String, dynamic> toJson() => {
"visitDate": visitDate,
"route": route,
"distributor": distributor,
};
}
Route RouteFromJson(String str) => Route.fromJson(json.decode(str));
String RouteToJson(Route data) => json.encode(data.toJson());
class Route {
Route({
this.routeID,
this.routeTitle,
});
String routeID;
String routeTitle;
factory Route.fromJson(Map<String, dynamic> json) => Route(
routeID: json["routeID"],
routeTitle: json["routeTitle"],
);
Map<String, dynamic> toJson() => {
"routeID": routeID,
"routeTitle": routeTitle,
};
}
Distributor DistributorFromJson(String str) => Distributor.fromJson(json.decode(str));
String DistributorToJson(Distributor data) => json.encode(data.toJson());
class Distributor {
Distributor({
this.distributorID,
this.distributorName,
});
String distributorID;
String distributorName;
factory Distributor.fromJson(Map<String, dynamic> json) => Distributor(
distributorID: json["distributorID"],
distributorName: json["distributorName"],
);
Map<String, dynamic> toJson() => {
"distributorID": distributorID,
"distributorName": distributorName,
};
}
how to correct my model class. please help me. thanks
Change your User class like this :
class User {
User({
this.visitDate,
this.route,
this.distributor,
});
String visitDate;
Route route;
Distributor distributor;
factory User.fromJson(Map<String, dynamic> json) => User(
visitDate: json["visitDate"],
route = json['route'] != null ? Route.fromJson(json['route']) : null;
distributor = json['distributor'] != null
? Distributor.fromJson(json['distributor'])
: null;
);
Map<String, dynamic> toJson() => {
"visitDate": visitDate,
if (route != null) {
data['route'] = this.route.toJson();
}
if (distributor != null) {
data['distributor'] = this.distributor.toJson();
}
};
}
You can also check out the json_serializable package for that.
This way, you don't have to write this code yourself.
https://pub.dev/packages/json_serializable
Flutter Box.!
You just need to do simple job is to visit following website. And need to put your response or map/list that you want to convert in model class and rest will be done by server.
By the way,
For your List<Map<String, dynamic> data's model class is,
// To parse this JSON data, do
//
// final routeModelClass = routeModelClassFromJson(jsonString);
import 'dart:convert';
List<RouteModelClass> routeModelClassFromJson(String str) => List<RouteModelClass>.from(json.decode(str).map((x) => RouteModelClass.fromJson(x)));
String routeModelClassToJson(List<RouteModelClass> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class RouteModelClass {
RouteModelClass({
this.route,
this.distributor,
this.visitDate,
});
Route route;
Distributor distributor;
dynamic visitDate;
factory RouteModelClass.fromJson(Map<String, dynamic> json) => RouteModelClass(
route: Route.fromJson(json["route"]),
distributor: Distributor.fromJson(json["distributor"]),
visitDate: json["visitDate"],
);
Map<String, dynamic> toJson() => {
"route": route.toJson(),
"distributor": distributor.toJson(),
"visitDate": visitDate,
};
}
class Distributor {
Distributor({
this.distributorId,
this.distributorName,
});
String distributorId;
String distributorName;
factory Distributor.fromJson(Map<String, dynamic> json) => Distributor(
distributorId: json["distributorID"],
distributorName: json["distributorName"],
);
Map<String, dynamic> toJson() => {
"distributorID": distributorId,
"distributorName": distributorName,
};
}
class Route {
Route({
this.routeId,
this.routeTitle,
});
String routeId;
String routeTitle;
factory Route.fromJson(Map<String, dynamic> json) => Route(
routeId: json["routeID"],
routeTitle: json["routeTitle"],
);
Map<String, dynamic> toJson() => {
"routeID": routeId,
"routeTitle": routeTitle,
};
}
List/Map to Model class
I would like to make a get requests and to convert results to a list of objects.
Actually i did that :
post_model.dart
#JsonSerializable()
class Post {
Post({
required this.userId,
required this.id,
required this.title,
required this.body,
});
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
Map<String, dynamic> toJson() => _$PostToJson(this);
final int userId;
final int id;
final String title;
final String body;
}
http_service.dart :
class HttpService {
final String url = 'https://jsonplaceholder.typicode.com';
final String postsURL = '/posts';
final Map<String, String> headers = {
'Content-Type': 'application/json'
};
List<Post> parsePosts(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Post>((json) => Post.fromJson(json)).toList();
}
Future<List<Post>> fetchPosts() async {
final http.Response response = await http.get(Uri.https(url, postsURL));
if (response.statusCode == 200) {
return compute(parsePosts,response.body);
} else {
throw Exception("Failed to load posts ${response.statusCode}");
}
}
}
But i encouter all in red on the parsePosts method.
On the final parsed :
Missing variable type for 'parsed'.
Try adding an explicit type, or remove implicit-dynamic from your analysis options file.dart(implicit_dynamic_variable)
and on the return :
A value of type 'dynamic' can't be returned from the method 'parsePosts' because it has a return type of 'List<Post>'
I just don't understand what i'm doing wrong, because i have follow the flutter doc here :
https://flutter.dev/docs/cookbook/networking/background-parsing
Thanks for any help
Some time ago I did this code for that API:
import 'dart:async';
import 'package:wnetworking/wnetworking.dart';
class Post {
int? userId, id;
String? title, body;
Post.fromJson(Map<String, dynamic> data) {
userId = data['userId'];
id = data['id'];
title = data['title'];
body = data['body'];
}
}
class JsonPlaceHolder {
static const baseUrl = 'https://jsonplaceholder.typicode.com';
/* ---------------------------------------------------------------------------- */
static FutureOr<void> _doGet(String path, {void doThis(var response)?}) async {
await HttpReqService.getJson(baseUrl + path)
.then((response) => doThis == null ? print(response) : doThis(response))
.whenComplete(() => print('\nFetching done!'));
}
/* ---------------------------------------------------------------------------- */
static FutureOr<void> _doPost(String path, {required Object body, int okCode = 200}) async {
await HttpReqService.post<Map<String, dynamic>>(baseUrl + path, body: body, okCode: okCode)
.then((response) => print(response))
.whenComplete(() => print('\nPost sent successfully'));
}
/* ---------------------------------------------------------------------------- */
static FutureOr<void> fetchPosts({int? id, bool onlyComments = false, bool useObjList = false}) async {
var path = '/posts/${id ?? ''}';
if (id != null && onlyComments) path += '/comments';
useObjList
? await _doGet(path, doThis: (response) {
if (response != null) {
print((response as List).map<Post>((m) => Post.fromJson(m as Map<String, dynamic>)));
}
})
: await _doGet(path);
}
/* ---------------------------------------------------------------------------- */
static FutureOr<void> fetchComments([int? postId]) => _doGet('/comments${postId != null ? '?postId='+postId.toString() : ''}');
static FutureOr<void> fetchAlbums() => _doGet('/albums');
static FutureOr<void> fetchPhotos() => _doGet('/photos');
static FutureOr<void> fetchTodos() => _doGet('/todos');
static FutureOr<void> fetchUsers() => _doGet('/users');
}
void main(List<String> args) async {
// await JsonPlaceHolder.fetchComments(1);
await JsonPlaceHolder.fetchPosts(useObjList: true);
print('Finished!');
}
Result:
(Instance of 'Post', Instance of 'Post', Instance of 'Post', ..., Instance of 'Post', Instance of 'Post')
Fetching done!
Finished!
Note
wnetworking package is not ready to publish yet, it contains operations related to API, etc. You can replace HttpReqService.getJson and HttpReqService.post with your typical http.get and http.post respectively but keep in mind the return value and exceptions.
Use Uri.parse
Those errors are due to a dart version.
A fix has been made by another user on github : https://github.com/flutter/website/pull/5798
Following this PR, it's works
i need to fetch data from server and sometimes the data can be empty response from logcat is data snapshot.data is returning instance of my model Instance of 'MyItems' and the response from server when data is not available is
{
"data": []
}
the problem is snapshot.hasData is always returning true for empty response i have tested snapshot.data == null still its true.
Model class
import 'dart:convert';
MyItems myItemsFromJson(String str) => MyItems.fromJson(json.decode(str));
String myItemsToJson(MyItems data) => json.encode(data.toJson());
class MyItems {
MyItems({
this.dataa,
});
List<Datumm> dataa;
factory MyItems.fromJson(Map<String, dynamic> json) => MyItems(
dataa: List<Datumm>.from(json["data"].map((x) => Datumm.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(dataa.map((x) => x.toJson())),
};
}
class Datumm {
Datumm({
this.userId,
this.Name,
this.MiddelName,
});
String userId;
String Name;
String MiddelName;
factory Datumm.fromJson(Map<String, dynamic> json) => Datumm(
userId: json["user_id"],
Name: json["Name"],
MiddelName: json["MiddleName"],
);
Map<String, dynamic> toJson() => {
"user_id": userId,
"Name": crbtCode,
"MiddelName": artistName,
};
}
My Future api call
Future<MyItems> getUdata(String aName) async {
var url =
'https://cvbgng.com/test/${aName}';
final response = await http.get(url).timeout(Duration(seconds: 15000));
if (response.statusCode == 200) {
return MyItems.fromJson(json.decode(response.body));
} else {
throw Exception('Faild to load');
}
}
check the condition as snapshot.data.dataa.isEmpty if it is true you have empty response.
I'm trying to to parse JSON from cloud, the data was received,
I tried so many solution here in stackOverflow but the haven't work to me, I'm just string to get familiar with flutter and dart.
but i got this error:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<Category>'
here it is my code:
JSON data I received:
{
"totalRowCount": 1,
"pageSize": 100,
"categories": [{
"CategoryName": "Beverages",
"CategoryID": 1
}]
}
Services.dart
import 'package:http/http.dart' as http;
import 'Category.dart';
class Services {
static const String url = 'http://example.com/category';
static Future<List<Category>> getCategories() async {
http.Response response = await http.get(url, headers: {"Accept": "application/json"});
if(response.statusCode == 200){
final category = categoryFromJson(response.body);
return category;
} else{
return List<Category>();
}
}
}
Category.dart
import 'dart:convert';
List<Category> categoryFromJson(String str) => List<Category>.from(json.decode(str));
class Category {
Category({
this.totalRowCount,
this.pageSize,
this.categories,
});
final int totalRowCount;
final int pageSize;
final List<CategoryElement> categories;
factory Category.fromJson(Map<String, dynamic> json){
return Category(
totalRowCount: json["totalRowCount"],
pageSize: json["pageSize"],
categories: List<CategoryElement>.from(json["categories"]),
);
}
Map<String, dynamic> toJson() => {
"totalRowCount": totalRowCount,
"pageSize": pageSize,
"categories": List<dynamic>.from(categories.map((x) => x.toJson())),
};
}
class CategoryElement {
CategoryElement({
this.categoryName,
this.categoryId,
});
final String categoryName;
final int categoryId;
factory CategoryElement.fromJson(Map<String, dynamic> json) => CategoryElement(
categoryName: json["CategoryName"],
categoryId: json["CategoryID"],
);
Map<String, dynamic> toJson() => {
"CategoryName": categoryName,
"CategoryID": categoryId,
};
}
any help
You need to call jsonDecode on response.body to convert the response to a Map.
import 'dart:convert';
final category = Category.fromJson(jsonDecode(response.body));
Remove the following line, it's causing the issue. Decode it right away using the factory instead of creating another function. That function is invalid because List.from accepts an iterable and you're supplying a Map. Also, the json response is not a List.
List<Category> categoryFromJson(String str) => List<Category>.from(json.decode(str));