I tried tojson in flutter, but I get the following error:
[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: type 'List<Tag>' is not a subtype of type 'String' in type cast
this is my code
import 'package:flutter_traveling/model/Tag.dart';
class Diary {
String? title;
String? location;
String? address;
List<Tag>? tagList;
List<Pages>? pages;
String? date;
Diary({
this.title,
this.location,
this.tagList,
this.pages,
this.date,
this.address,
});
Diary.fromJson(Map<String, dynamic> json) {
title = json['title'] ?? "";
location = json['location'] ?? "";
address = json["address"] ?? "";
tagList = json['tag_list'] ?? <Tag>[];
pages = json['pages'] ?? <Pages>[];
date = json['date'] == null ? '' : json['date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['title'] = this.title;
data['location'] = this.location;
data['tag_list'] = this.tagList;
data['pages'] = this.pages;
data['date'] = this.date;
data['address'] = this.address;
return data;
}
}
class Pages {
int? order;
String? description;
List<String>? images;
Pages({
this.order,
this.description,
this.images,
});
Pages.fromJson(Map<String, dynamic> json) {
order = json['order'] ?? 0;
description = json['description'] ?? "";
images = json['images'] == null ? [] : json["images"].cast<String>();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['order'] = this.order;
data['description'] = this.description;
data['images'] = this.images;
return data;
}
}
class Tag {
int? id;
String? tagName;
Tag({this.id, this.tagName});
Tag.fromJson(Map<String, dynamic> json) {
id = json['id'];
tagName = json['tag_name'] ?? "";
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tag_name'] = this.tagName;
return data;
}
}
I don't know what causes this error to occur. please help
My guess is that when I run tojson, there seems to be a problem with the type, but I don't know which part and how to fix it, I'm just starting out with flutter, any advice would be appreciated.
i got err when change code like this.
data['tag_list'] = this.tagList.toString();
data['pages'] = this.pages.toString();
error is
Unhandled Exception: type 'String' is not a subtype of type 'List<Tag>?'
Try to replace
tagList = json['tag_list'] ?? <Tag>[];
with
tagList = List<Tag>.from(json["tag_list"].map((x) => Tag.fromJson(x)))
And this line
data['tag_list'] = this.tagList;
with
data['tag_list'] = this.tagList.map((tag) => tag.toJson()),
you should call the toJson() methods from your tags as well:
data['tag_list'] = this.tagList.map((tag) => tag.toJson()),
Related
Why does this code give me this error? In the emulator, I have this problem Format Exception: Unexpected Character (at character 1)Instance of 'VerifyData'. I don't know resolve of this.
static VerifyData? fromObject(Object? data) {
try {
if (data != null) {
var jsonObject = json.decode(data.toString());
return VerifyData.fromJson(jsonObject);
}
} catch (e) {
return null;
}
}
this is class VerifyData and json. what's wrong in this my code? because I think it is in accordance with the contents of the API that I have made
class VerifyData {
int? id;
String? user;
String? name;
String? level;
String? photo;
String? email;
String? phone;
String? address;
String? time;
String? v;
int? iat;
int? exp;
VerifyData(
{this.id,
this.user,
this.name,
this.level,
this.photo,
this.email,
this.phone,
this.address,
this.time,
this.v,
this.iat,
this.exp});
VerifyData.fromJson(Map<String, dynamic> json) {
id = json['id'];
user = json['user'];
name = json['name'];
level = json['level'];
photo = json['photo'];
email = json['email'];
phone = json['phone'];
address = json['address'];
time = json['time'];
v = json['v'];
iat = json['iat'];
exp = json['exp'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['user'] = this.user;
data['name'] = this.name;
data['level'] = this.level;
data['photo'] = this.photo;
data['email'] = this.email;
data['phone'] = this.phone;
data['address'] = this.address;
data['time'] = this.time;
data['v'] = this.v;
data['iat'] = this.iat;
data['exp'] = this.exp;
return data;
}
I/flutter ( 5881): Data : {"id":1,"user":"admin","name":"Admin","level":"employee","photo":null,"email":"admin#gmail.com","phone":null,"address":"Jl. Asem Daerah","time":"2022-10-11T02:34:55.138Z","v":"p","iat":1122355694,"exp":1122259294}
You might want to check this out: https://docs.flutter.dev/development/data-and-backend/json
class ProductModel {
late String name;
late int id;
late String status;
late String price;
late List<Images> images;
ProductModel(
this.name,
this.id,
this.status,
this.images,
this.price,
);
ProductModel.fromJson(Map<String, dynamic> json) {
name = json['name'];
id = json['id'];
status = json['status'];
//images = json['images'];
images = json['image'];
if (json['images'] != null) {
images = new List<Images>(); // error on List<Images>() "The default 'List' constructor //isn't available when null safety is enabled.
json['images'].forEach((v) {
images.add(new Images.fromJson(v));
});
}
price = json['price'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['id'] = this.id;
data['status'] = this.status;
if (this.images != null) {
data['images'] = this.images.map((v) => v.toJson()).toList();
}
data['price'] = this.price;
return data;
}
}
// ignore: camel_case_types
class Images {
late int id;
late String src;
late String title;
Images({
this.id = 0,
this.src = "",
this.title = "",
});
Images.fromJson(Map<String, dynamic> json) {
id = json['id'];
src = json['src'];
title = json['title'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['src'] = this.src;
data['title'] = this.title;
return data;
}
}
I want to list the products of my Woocommerce site in the Flutter app, But getting an error mentioned in the code, please help. Please guide me the best way to model the JSON into Dart class. Tried converting online using https://javiercbk.github.io/json_to_dart/ but this gives lots of errors
Well it seems you are initializing the List incorrectly.
It should be:
images = <Images>[];
Also, you do not need to initialize with the new keyword anymore.
Future<bool> login({username, password}) async {
var api = API();
_status = LoginStatus.loading;
notifyListeners();
var url = Uri.parse(api.baseUrl + api.auth);
final response = await http.post(
url,
body: jsonEncode({
"identifier": "$username",
"password": "$password",
}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
if (response.statusCode == 200) {
final parsed = jsonDecode(response.body).cast<Map<String, dynamic>>();
parsed
.map<UserModel>((json) => UserModel.fromJson(json))
.toList();
final token = jsonDecode(response.body)['jwt'];
print(token);
await saveToken(token);
return true;
} else {
_status = LoginStatus.error;
_error = response.body;
notifyListeners();
return false;
}
}
Code Screen Shot
How Should I save this parsed JSON to UserModel? I have encountered many problems and figured out many things on my own but I am not yet able to add data to the model.
By the way I am using strapi as a back end and every api is working. And I amso use a website called json to dart converter so that my models are correct(As I Assume).
Please help !!!!!!!!!!!!
UserModel
class UserModel {
User user;
UserModel({this.user});
UserModel.fromJson(Map<String, dynamic> json) {
user = json['user'] != null ? new User.fromJson(json['user']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.user != null) {
data['user'] = this.user.toJson();
}
return data;
}
}
class User {
int id;
String username;
String email;
String provider;
bool confirmed;
bool blocked;
Role role;
String displayName;
String createdAt;
String updatedAt;
Avatar avatar;
List<UserCategories> userCategories;
User(
{this.id,
this.username,
this.email,
this.provider,
this.confirmed,
this.blocked,
this.role,
this.displayName,
this.createdAt,
this.updatedAt,
this.avatar,
this.userCategories});
User.fromJson(Map<String, dynamic> json) {
id = json['id'];
username = json['username'];
email = json['email'];
provider = json['provider'];
confirmed = json['confirmed'];
blocked = json['blocked'];
role = json['role'] != null ? new Role.fromJson(json['role']) : null;
displayName = json['displayName'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
avatar =
json['avatar'] != null ? new Avatar.fromJson(json['avatar']) : null;
if (json['user_categories'] != null) {
userCategories = new List<UserCategories>();
json['user_categories'].forEach((v) {
userCategories.add(new UserCategories.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['username'] = this.username;
data['email'] = this.email;
data['provider'] = this.provider;
data['confirmed'] = this.confirmed;
data['blocked'] = this.blocked;
if (this.role != null) {
data['role'] = this.role.toJson();
}
data['displayName'] = this.displayName;
data['created_at'] = this.createdAt;
data['updated_at'] = this.updatedAt;
if (this.avatar != null) {
data['avatar'] = this.avatar.toJson();
}
if (this.userCategories != null) {
data['user_categories'] =
this.userCategories.map((v) => v.toJson()).toList();
}
return data;
}
}
class Role {
int id;
String name;
String description;
String type;
Role({this.id, this.name, this.description, this.type});
Role.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
description = json['description'];
type = json['type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['description'] = this.description;
data['type'] = this.type;
return data;
}
}
class Avatar {
int id;
String name;
String alternativeText;
String caption;
int width;
int height;
Formats formats;
String hash;
String ext;
String mime;
double size;
String url;
Null previewUrl;
String provider;
Null providerMetadata;
String createdAt;
String updatedAt;
Avatar(
{this.id,
this.name,
this.alternativeText,
this.caption,
this.width,
this.height,
this.formats,
this.hash,
this.ext,
this.mime,
this.size,
this.url,
this.previewUrl,
this.provider,
this.providerMetadata,
this.createdAt,
this.updatedAt});
Avatar.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
alternativeText = json['alternativeText'];
caption = json['caption'];
width = json['width'];
height = json['height'];
formats =
json['formats'] != null ? new Formats.fromJson(json['formats']) : null;
hash = json['hash'];
ext = json['ext'];
mime = json['mime'];
size = json['size'];
url = json['url'];
previewUrl = json['previewUrl'];
provider = json['provider'];
providerMetadata = json['provider_metadata'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['alternativeText'] = this.alternativeText;
data['caption'] = this.caption;
data['width'] = this.width;
data['height'] = this.height;
if (this.formats != null) {
data['formats'] = this.formats.toJson();
}
data['hash'] = this.hash;
data['ext'] = this.ext;
data['mime'] = this.mime;
data['size'] = this.size;
data['url'] = this.url;
data['previewUrl'] = this.previewUrl;
data['provider'] = this.provider;
data['provider_metadata'] = this.providerMetadata;
data['created_at'] = this.createdAt;
data['updated_at'] = this.updatedAt;
return data;
}
}
class Formats {
Thumbnail thumbnail;
Formats({this.thumbnail});
Formats.fromJson(Map<String, dynamic> json) {
thumbnail = json['thumbnail'] != null
? new Thumbnail.fromJson(json['thumbnail'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.thumbnail != null) {
data['thumbnail'] = this.thumbnail.toJson();
}
return data;
}
}
class Thumbnail {
String name;
String hash;
String ext;
String mime;
int width;
int height;
double size;
Null path;
String url;
Thumbnail(
{this.name,
this.hash,
this.ext,
this.mime,
this.width,
this.height,
this.size,
this.path,
this.url});
Thumbnail.fromJson(Map<String, dynamic> json) {
name = json['name'];
hash = json['hash'];
ext = json['ext'];
mime = json['mime'];
width = json['width'];
height = json['height'];
size = json['size'];
path = json['path'];
url = json['url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['hash'] = this.hash;
data['ext'] = this.ext;
data['mime'] = this.mime;
data['width'] = this.width;
data['height'] = this.height;
data['size'] = this.size;
data['path'] = this.path;
data['url'] = this.url;
return data;
}
}
class UserCategories {
int id;
String categoryName;
int usersPermissionsUser;
String publishedAt;
String createdAt;
String updatedAt;
UserCategories(
{this.id,
this.categoryName,
this.usersPermissionsUser,
this.publishedAt,
this.createdAt,
this.updatedAt});
UserCategories.fromJson(Map<String, dynamic> json) {
id = json['id'];
categoryName = json['categoryName'];
usersPermissionsUser = json['users_permissions_user'];
publishedAt = json['published_at'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['categoryName'] = this.categoryName;
data['users_permissions_user'] = this.usersPermissionsUser;
data['published_at'] = this.publishedAt;
data['created_at'] = this.createdAt;
data['updated_at'] = this.updatedAt;
return data;
}
}
The UserModel.fromJson method will only work if the response.body content is a User, so to fix your issue, instead of using UserModel.fromJson on the response.body json decoded variable, rather use the fromJson() function on data that you are sure will conform to your class definition.
For example:
class User{
final String name;
final String surname;
final String email;
User({this.name, this.surname, this.email});
factory User.fromJson(Map<String,dynamic> json){
return User(
'name': json['name'],
'surname': json['surname'],
'email': json['email']
);
}
}
The json response that is recieved from the api:
{
"name" : "John",
"surname": "Smith",
"email": "johnsmith#mail.com"
}
In your function, decode response and cast to the User model class:
final parsed = jsonDecode(response.body); // or Map<String,dynamic> parsed = jsonDecode(response.body);
User user = User.fromJson(parsed)
Recently migrating to Flutter null safety feature, I have a lot of Classes that I need to update.
For my models, I use fromJson to deserialize the data from a json object. This forces me to put the late keyword for each field that is non optional.
Is that the right approach?
class ServerSession {
late String sessionId;
late String refreshToken;
late String accessToken;
ServerSession({required this.sessionId, required this.refreshToken, required this.accessToken});
ServerSession.fromJson(Map<String, dynamic> json) {
sessionId = json['session_id'] ?? json['sessionId'];
refreshToken = json['refresh_token'] ?? json['refreshToken'];
accessToken = json['access_token'] ?? json['accessToken'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['sessionId'] = this.sessionId;
data['refreshToken'] = this.refreshToken;
data['accessToken'] = this.accessToken;
return data;
}
}
No, it is not. You should be using the initializer list for initializing fields of your class. You can read more about the initializer list in the language tour.
class ServerSession {
String sessionId;
String refreshToken;
String accessToken;
ServerSession({required this.sessionId, required this.refreshToken, required this.accessToken});
ServerSession.fromJson(Map<String, dynamic> json) :
sessionId = json['session_id'] ?? json['sessionId'],
refreshToken = json['refresh_token'] ?? json['refreshToken'],
accessToken = json['access_token'] ?? json['accessToken'];
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['sessionId'] = this.sessionId;
data['refreshToken'] = this.refreshToken;
data['accessToken'] = this.accessToken;
return data;
}
}
I personally would use the "normal" constructor for the object and make fromJson a factory constructor, though either method works.
class ServerSession {
String sessionId;
String refreshToken;
String accessToken;
ServerSession({required this.sessionId, required this.refreshToken, required this.accessToken});
factory ServerSession.fromJson(Map<String, dynamic> json) {
return ServerSession(
sessionId: json['session_id'] ?? json['sessionId'],
refreshToken: json['refresh_token'] ?? json['refreshToken'],
accessToken: json['access_token'] ?? json['accessToken']
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['sessionId'] = this.sessionId;
data['refreshToken'] = this.refreshToken;
data['accessToken'] = this.accessToken;
return data;
}
}
I am getting this Error Unhandled Exception: type '(dynamic) => Null' is not a subtype of type '(String, dynamic) => void' of 'f' decoding a json from an API, I believe the problem may be from the Data class in the model but i don't know how to solve it.
The model class
class UserLogin {
bool success;
int statusCode;
String code;
String message;
List<Data> data;
UserLogin({
this.code,
this.success,
this.message,
this.statusCode,
this.data,
});
UserLogin.fromJson(Map<String, dynamic>json){
success = json['success'];
statusCode = json['statusCode'];
code = json['code'];
message = json['message'];
//data = json['data'] != null ? new Data.fromJson(json['data']) : null;
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['success'] = this.success;
data['statuCode'] = this.statusCode;
data['code'] = this.code;
data['message'] = this.message;
if(this.data != null) {
data['data'] = this.data.toList();
}
return data;
}
#override toString() => this.toJson().toString();
}
class Data {
String token;
int id;
String email;
String nicename;
String firstname;
String lastname;
String displayName;
Data(
{this.token,
this.id,
this.email,
this.nicename,
this.firstname,
this.lastname,
this.displayName});
Data.fromJson(Map<String, dynamic> json){
token = json['token'];
id = json['id'];
email = json['email'];
nicename = json['nicename'];
firstname = json['firstname'];
displayName = json['displayName'];
}
Map<String, dynamic> toJson(){
final Map<String, dynamic> data = new Map<String, dynamic>();
data['token'] = this.token;
data['id'] = this.id;
data['email'] = this.email;
data['nicename'] = this.nicename;
data['firstname'] = this.firstname;
data['displayName'] = this.displayName;
return data;
}
}
The async function calling the api
Future<UserLogin> loginCustomer(String username, String password ) async {
//List<UserLogin> model = new List<UserLogin>();
UserLogin model;
try {
var response = await Dio().post(
Config.tokenURL,
data: {
"username" : username,
"password" : password,
},
options: new Options(
headers: {
HttpHeaders.contentTypeHeader: "application/x-www-form-urlencoded",
},
),
);
if(response.statusCode == 200) {
print(response.data);
model = UserLogin.fromJson(response.data);
}
} on DioError catch (e) {
print(e.message);
}
return model;
}
Response from Api
{success: true, statusCode: 200, code: jwt_auth_valid_credential, message: Credential is valid, data: {token:***, id: 1, email: ***, nicename: ***, firstName: ***, lastName: ***, displayName: ****}}
Updated Code
class UserLogin {
bool success;
int statusCode;
String code;
String message;
Data data;
UserLogin({
this.code,
this.success,
this.message,
this.statusCode,
this.data,
});
UserLogin.fromJson(Map<String, dynamic>json){
success = json['success'];
statusCode = json['statusCode'];
code = json['code'];
message = json['message'];
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
}
Map<String, dynamic> toJson(){
final Map<String, dynamic> data = new Map<String, dynamic>();
data['success'] = this.success;
data['statuCode'] = this.statusCode;
data['code'] = this.code;
data['message'] = this.message;
if(this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
#override toString() => this.toJson().toString();
}
class Data {
String token;
int id;
String email;
String nicename;
String firstname;
String lastname;
String displayName;
Data(
{this.token,
this.id,
this.email,
this.nicename,
this.firstname,
this.lastname,
this.displayName});
Data.fromJson(Map<String, dynamic> json){
token = json['token'];
id = json['id'];
email = json['email'];
nicename = json['nicename'];
firstname = json['firstname'];
displayName = json['displayName'];
}
Map<String, dynamic> toJson(){
final Map<String, dynamic> data = new Map<String, dynamic>();
data['token'] = this.token;
data['id'] = this.id;
data['email'] = this.email;
data['nicename'] = this.nicename;
data['firstname'] = this.firstname;
data['displayName'] = this.displayName;
return data;
}
}
Based on the response.data, your data is an object, but you defined it as List in UserLogin model class, which is wrong.
The correct should beData data;