Reputation: 123
each time I try to send data to API I got the following error:
" Unhandled Exception: Converting object to an encodable object failed: Instance of 'AddProjectModel' ".
I followed the debugger step by step everything went well, and all data are passed correctly. However, when it reaches the jsonEncode() method it gives the above error.
Anyone can help please, thanks in advance.
Here is my AddProjectModel and other models used inside it:
class AddProjectModel {
AddProjectModel({
required this.name,
required this.city,
required this.district,
required this.address,
required this.size,
required this.completionDate,
required this.infrastructureCost,
required this.currencyID,
required this.description,
required this.isHidden,
required this.companies,
required this.facilities,
required this.picture,
});
late final String name;
late final String city;
late final String district;
late final String address;
late final double size;
late final DateTime completionDate;
late final double infrastructureCost;
late final int currencyID;
late final String description;
late final bool isHidden;
late final List<AddProjectCompaniesModel> companies;
late final List<AddEditFacilitiesModel> facilities;
late final List<AddProjectPicturesModel> picture;
AddProjectModel.fromJson(Map<String, dynamic> json) {
name = json['name'];
city = json['city'];
district = json['district'];
address = json['address'];
size = json['size'].toDouble();
completionDate = json['completeDate'];
infrastructureCost = json['infrastructureCost'].toDouble();
currencyID = json['currencyID'];
description = json['description'];
isHidden = json['isHidden'];
companies = List.from(json['companies'])
.map((e) => AddProjectCompaniesModel.fromJson(e))
.toList();
facilities = List.from(json['facilities'])
.map((e) => AddEditFacilitiesModel.fromJson(e))
.toList();
picture = List.from(json['picture'])
.map((e) => AddProjectPicturesModel.fromJson(e))
.toList();
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['name'] = name;
data['city'] = city;
data['district'] = district;
data['address'] = address;
data['size'] = size;
data['completeDate'] = completionDate;
data['infrastructureCost'] = infrastructureCost;
data['currencyID'] = currencyID;
data['description'] = description;
data['isHidden'] = isHidden;
data['companies'] = companies.map((e) => e.toJson()).toList();
data['facilities'] = facilities.map((e) => e.toJson()).toList();
data['picture'] = picture.map((e) => e.toJson()).toList();
return data;
}
}
class AddProjectCompaniesModel {
AddProjectCompaniesModel({
required this.companyId,
});
late final int companyId;
AddProjectCompaniesModel.fromJson(Map<String, dynamic> json) {
companyId = json['companyId'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['companyId'] = companyId;
return data;
}
}
class AddEditFacilitiesModel {
AddEditFacilitiesModel({
required this.pool,
required this.gym,
required this.garage,
required this.garden,
required this.roofRoom,
required this.barbecuePlace,
required this.cafeterias,
required this.giftShop,
required this.gamingCenter,
required this.supermarket,
required this.atm,
required this.playGround,
required this.parking,
required this.walkingArea,
required this.pharmacy,
required this.dryCleaning,
required this.spaCenter,
required this.medicalServices,
});
late final bool pool;
late final bool gym;
late final bool garage;
late final bool garden;
late final bool roofRoom;
late final bool barbecuePlace;
late final bool cafeterias;
late final bool giftShop;
late final bool gamingCenter;
late final bool supermarket;
late final bool atm;
late final bool playGround;
late final bool parking;
late final bool walkingArea;
late final bool pharmacy;
late final bool dryCleaning;
late final bool spaCenter;
late final bool medicalServices;
AddEditFacilitiesModel.fromJson(Map<String, dynamic> json) {
pool = json['pool'];
gym = json['gym'];
garage = json['garage'];
garden = json['garden'];
roofRoom = json['roofRoom'];
barbecuePlace = json['barbecuePlace'];
cafeterias = json['cafeterias'];
giftShop = json['giftShop'];
gamingCenter = json['gamingCenter'];
supermarket = json['superMarket'];
atm = json['atm'];
playGround = json['playGround'];
parking = json['parking'];
walkingArea = json['walkingArea'];
pharmacy = json['pharmacy'];
dryCleaning = json['drycleaning'];
spaCenter = json['spacenter'];
medicalServices = json['medicalservices'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['pool'] = pool;
data['gym'] = gym;
data['garage'] = garage;
data['garden'] = garden;
data['roofRoom'] = roofRoom;
data['barbecuePlace'] = barbecuePlace;
data['cafeterias'] = cafeterias;
data['giftShop'] = giftShop;
data['gamingCenter'] = gamingCenter;
data['superMarket'] = supermarket;
data['atm'] = atm;
data['playGround'] = playGround;
data['parking'] = parking;
data['walkingArea'] = walkingArea;
data['pharmacy'] = pharmacy;
data['drycleaning'] = dryCleaning;
data['spacenter'] = spaCenter;
data['medicalservices'] = medicalServices;
return data;
}
}
class AddProjectPicturesModel {
AddProjectPicturesModel({
this.url,
required this.file,
this.dateAdded,
});
late String? url;
late final String file;
late String? dateAdded;
AddProjectPicturesModel.fromJson(Map<String, dynamic> json) {
url = json['url'];
file = json['file'];
dateAdded = json['dateAdded'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['url'] = url;
data['file'] = file;
data['dateAdded'] = dateAdded;
return data;
}
}
Here is my addProject() method that posts data to API:
static Future<bool> addProject(
String name,
String city,
String district,
String address,
double size,
DateTime completionDate,
double infrastructureCost,
int currencyID,
String description,
bool isHidden,
List<AddProjectCompaniesModel> companies,
List<AddEditFacilitiesModel> facilities,
List<AddProjectPicturesModel> projectPicture,
) async {
AddProjectModel projectModel = AddProjectModel(
name: name,
city: city,
district: district,
address: address,
size: size,
completionDate: completionDate,
infrastructureCost: infrastructureCost,
currencyID: currencyID,
description: description,
isHidden: isHidden,
companies: companies,
facilities: facilities,
picture: projectPicture,
);
final url = Uri.https(APIRoutes.baseURL, APIRoutes.project);
Map<String, String> requestHeaders = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ${secureStorage.token}',
};
final response = await client.post(
url,
headers: requestHeaders,
body: jsonEncode(projectModel),
);
if (response.statusCode == 201) {
print('Success with: ${response.statusCode}');
return true;
} else {
print('Failed with: ${response.statusCode}');
return false;
}
}
Upvotes: 2
Views: 8338
Reputation: 123
The problem was a failer in converting an Object to an encodable Object through the jsonEncode() method "which is supported in dart:convert library".
Here is Flutter explanation for jsonEncode() method
As shown in the figure above, we are only allowed to convert values of type "number, boolean, string, null, list, or a map with string keys". So, the issue in my question was not in the following objects:
List<AddProjectCompaniesModel> companies
List<AddEditFacilitiesModel> facilities
List<AddProjectPicturesModel> projectPicture
because these are of type List and no issues with them. However, the issue was in the following lines of code
DateTime completionDate, // inside addProject(...)
late final DateTime completionDate; // inside AddProjectModel{}
data['completeDate'] = completionDate; // inside toJson() of AddProjectModel{}
Where I am was trying to convert a value of type DateTime and it is not allowed as shown in method explanation in the figure above. Beacuse of that I had to convert the completionDate variable from 'DateTime' to 'String' before converting it to json format. And after that it works fine.
Therfore, the solution is to change this line of code
data['completeDate'] = completionDate; // inside toJson() of AddProjectModel{}
To
data['completeDate'] = completionDate.toString();
I hope my answer was explained enough. Below you can view the whole corrected code.
AddProjectModel and other models used inside it:
class AddProjectModel {
AddProjectModel({
required this.name,
required this.city,
required this.district,
required this.address,
required this.size,
required this.completionDate,
required this.infrastructureCost,
required this.currencyID,
required this.description,
required this.isHidden,
required this.companies,
required this.facilities,
required this.picture,
});
late final String name;
late final String city;
late final String district;
late final String address;
late final double size;
late final DateTime completionDate;
late final double infrastructureCost;
late final int currencyID;
late final String description;
late final bool isHidden;
late final List<AddProjectCompaniesModel> companies;
late final List<AddEditFacilitiesModel> facilities;
late final List<AddProjectPicturesModel> picture;
AddProjectModel.fromJson(Map<String, dynamic> json) {
name = json['name'];
city = json['city'];
district = json['district'];
address = json['address'];
size = json['size'].toDouble();
completionDate = json['completeDate'];
infrastructureCost = json['infrastructureCost'].toDouble();
currencyID = json['currencyID'];
description = json['description'];
isHidden = json['isHidden'];
companies = List.from(json['companies'])
.map((e) => AddProjectCompaniesModel.fromJson(e))
.toList();
facilities = List.from(json['facilities'])
.map((e) => AddEditFacilitiesModel.fromJson(e))
.toList();
picture = List.from(json['picture'])
.map((e) => AddProjectPicturesModel.fromJson(e))
.toList();
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['name'] = name;
data['city'] = city;
data['district'] = district;
data['address'] = address;
data['size'] = size;
data['completeDate'] = completionDate.toSting(); //Only this line changed
data['infrastructureCost'] = infrastructureCost;
data['currencyID'] = currencyID;
data['description'] = description;
data['isHidden'] = isHidden;
data['companies'] = companies.map((e) => e.toJson()).toList();
data['facilities'] = facilities.map((e) => e.toJson()).toList();
data['picture'] = picture.map((e) => e.toJson()).toList();
return data;
}
}
class AddProjectCompaniesModel {
AddProjectCompaniesModel({
required this.companyId,
});
late final int companyId;
AddProjectCompaniesModel.fromJson(Map<String, dynamic> json) {
companyId = json['companyId'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['companyId'] = companyId;
return data;
}
}
class AddEditFacilitiesModel {
AddEditFacilitiesModel({
required this.pool,
required this.gym,
required this.garage,
required this.garden,
required this.roofRoom,
required this.barbecuePlace,
required this.cafeterias,
required this.giftShop,
required this.gamingCenter,
required this.supermarket,
required this.atm,
required this.playGround,
required this.parking,
required this.walkingArea,
required this.pharmacy,
required this.dryCleaning,
required this.spaCenter,
required this.medicalServices,
});
late final bool pool;
late final bool gym;
late final bool garage;
late final bool garden;
late final bool roofRoom;
late final bool barbecuePlace;
late final bool cafeterias;
late final bool giftShop;
late final bool gamingCenter;
late final bool supermarket;
late final bool atm;
late final bool playGround;
late final bool parking;
late final bool walkingArea;
late final bool pharmacy;
late final bool dryCleaning;
late final bool spaCenter;
late final bool medicalServices;
AddEditFacilitiesModel.fromJson(Map<String, dynamic> json) {
pool = json['pool'];
gym = json['gym'];
garage = json['garage'];
garden = json['garden'];
roofRoom = json['roofRoom'];
barbecuePlace = json['barbecuePlace'];
cafeterias = json['cafeterias'];
giftShop = json['giftShop'];
gamingCenter = json['gamingCenter'];
supermarket = json['superMarket'];
atm = json['atm'];
playGround = json['playGround'];
parking = json['parking'];
walkingArea = json['walkingArea'];
pharmacy = json['pharmacy'];
dryCleaning = json['drycleaning'];
spaCenter = json['spacenter'];
medicalServices = json['medicalservices'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['pool'] = pool;
data['gym'] = gym;
data['garage'] = garage;
data['garden'] = garden;
data['roofRoom'] = roofRoom;
data['barbecuePlace'] = barbecuePlace;
data['cafeterias'] = cafeterias;
data['giftShop'] = giftShop;
data['gamingCenter'] = gamingCenter;
data['superMarket'] = supermarket;
data['atm'] = atm;
data['playGround'] = playGround;
data['parking'] = parking;
data['walkingArea'] = walkingArea;
data['pharmacy'] = pharmacy;
data['drycleaning'] = dryCleaning;
data['spacenter'] = spaCenter;
data['medicalservices'] = medicalServices;
return data;
}
}
class AddProjectPicturesModel {
AddProjectPicturesModel({
this.url,
required this.file,
this.dateAdded,
});
late String? url;
late final String file;
late String? dateAdded;
AddProjectPicturesModel.fromJson(Map<String, dynamic> json) {
url = json['url'];
file = json['file'];
dateAdded = json['dateAdded'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['url'] = url;
data['file'] = file;
data['dateAdded'] = dateAdded;
return data;
}
}
addProject() method that posts data to API:
static Future<bool> addProject(
String name,
String city,
String district,
String address,
double size,
DateTime completionDate,
double infrastructureCost,
int currencyID,
String description,
bool isHidden,
List<AddProjectCompaniesModel> companies,
List<AddEditFacilitiesModel> facilities,
List<AddProjectPicturesModel> projectPicture,
) async {
AddProjectModel projectModel = AddProjectModel(
name: name,
city: city,
district: district,
address: address,
size: size,
completionDate: completionDate,
infrastructureCost: infrastructureCost,
currencyID: currencyID,
description: description,
isHidden: isHidden,
companies: companies,
facilities: facilities,
picture: projectPicture,
);
final url = Uri.https(APIRoutes.baseURL, APIRoutes.project);
Map<String, String> requestHeaders = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ${secureStorage.token}',
};
final response = await client.post(
url,
headers: requestHeaders,
body: jsonEncode(projectModel),
);
if (response.statusCode == 201) {
print('Success with: ${response.statusCode}');
return true;
} else {
print('Failed with: ${response.statusCode}');
return false;
}
}
Upvotes: 4
Reputation: 1792
That's because dart objects are not convertable to json by default, you need to convert it to Map
first or you can use plugins to convert your objects to maps such as json_serializable
Upvotes: 0