Im using Dio package to maintain REST API connections.
when I call this particular API end point. I get a response but when I try to parse that to an object it gives me the error
type _internalLinkedHashMap<String, dynamic> is not a subtype of type String occurred
I tried so many things but still no solution worked for me.
Object class
import 'dart:convert';
DetailsModel detailsModelFromJson(String str) =>
DetailsModel.fromJson(json.decode(str));
String detailsModelToJson(DetailsModel data) => json.encode(data.toJson());
class DetailsModel {
DetailsModel({
this.venueId,
this.lat,
this.lng,
this.events,
this.hasEvents,
this.categories,
this.name,
this.overall,
this.accuracy,
this.attitude,
this.createdTime,
this.updatedTime,
});
String? venueId;
String? lat;
String? lng;
List<Event>? events;
bool? hasEvents;
List<Category>? categories;
String? name;
String? overall;
String? accuracy;
String? attitude;
DateTime? createdTime;
DateTime? updatedTime;
factory DetailsModel.fromJson(Map<String, dynamic> json) => DetailsModel(
venueId: json["venueId"],
lat: json["lat"],
lng: json["lng"],
events: List<Event>.from(json["events"].map((x) => Event.fromJson(x))),
hasEvents: json["hasEvents"],
categories: List<Category>.from(
json["categories"].map((x) => Category.fromJson(x))),
name: json["name"],
overall: json["overall"],
accuracy: json["accuracy"],
attitude: json["attitude"],
createdTime: DateTime.parse(json["createdTime"]),
updatedTime: DateTime.parse(json["updatedTime"]),
);
Map<String, dynamic> toJson() => {
"venueId": venueId,
"lat": lat,
"lng": lng,
"events": List<dynamic>.from(events!.map((x) => x.toJson())),
"hasEvents": hasEvents,
"categories": List<dynamic>.from(categories!.map((x) => x.toJson())),
"name": name,
"overall": overall,
"accuracy": accuracy,
"attitude": attitude,
"createdTime": createdTime!.toIso8601String(),
"updatedTime": updatedTime!.toIso8601String(),
};
}
class Category {
Category({
this.categoryId,
this.name,
this.subCategories,
});
int? categoryId;
String? name;
List<SubCategory>? subCategories;
factory Category.fromJson(Map<String, dynamic> json) => Category(
categoryId: json["categoryId"],
name: json["name"],
subCategories: List<SubCategory>.from(
json["subCategories"].map((x) => SubCategory.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"categoryId": categoryId,
"name": name,
"subCategories":
List<dynamic>.from(subCategories!.map((x) => x.toJson())),
};
}
class SubCategory {
SubCategory({
this.subCategoryId,
this.name,
this.properties,
});
int? subCategoryId;
String? name;
List<Property>? properties;
factory SubCategory.fromJson(Map<String, dynamic> json) => SubCategory(
subCategoryId: json["subCategoryId"],
name: json["name"],
properties: List<Property>.from(
json["properties"].map((x) => Property.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"subCategoryId": subCategoryId,
"name": name,
"properties": List<dynamic>.from(properties!.map((x) => x.toJson())),
};
}
class Property {
Property({
this.propertyId,
this.name,
});
int? propertyId;
String? name;
factory Property.fromJson(Map<String, dynamic> json) => Property(
propertyId: json["propertyId"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"propertyId": propertyId,
"name": name,
};
}
class Event {
Event({
this.eventId,
this.name,
this.description,
this.startTime,
this.endTime,
this.ticketPrice,
this.url,
this.createdTime,
this.updatedTime,
});
String? eventId;
String? name;
String? description;
DateTime? startTime;
DateTime? endTime;
String? ticketPrice;
String? url;
DateTime? createdTime;
DateTime? updatedTime;
factory Event.fromJson(Map<String, dynamic> json) => Event(
eventId: json["eventId"],
name: json["name"],
description: json["description"],
startTime: DateTime.parse(json["startTime"]),
endTime: DateTime.parse(json["endTime"]),
ticketPrice: json["ticketPrice"],
url: json["url"],
createdTime: DateTime.parse(json["createdTime"]),
updatedTime: DateTime.parse(json["updatedTime"]),
);
Map<String, dynamic> toJson() => {
"eventId": eventId,
"name": name,
"description": description,
"startTime": startTime!.toIso8601String(),
"endTime": endTime!.toIso8601String(),
"ticketPrice": ticketPrice,
"url": url,
"createdTime": createdTime!.toIso8601String(),
"updatedTime": updatedTime!.toIso8601String(),
};
}
json response
{
"venueId": "ChIJny1e18LOsGoRGigq07mJVR4",
"lat": "-34.9379400000",
"lng": "138.6115300000",
"events": [
{
"eventId": "da0dd1c7-3fec-4031-a4ea-e2edf5942a69",
"name": "",
"description": "this is test description",
"startTime": "2022-02-14T07:13:33.598Z",
"endTime": "2022-02-14T04:32:41.374Z",
"ticketPrice": "0.00",
"url": "https://www.isa.org",
"createdTime": "2022-02-11T20:34:36.177Z",
"updatedTime": "2022-02-11T20:34:36.177Z"
}
],
"hasEvents": true,
"categories": [
{
"categoryId": 1,
"name": "Access",
"subCategories": [
{
"subCategoryId": 7,
"name": "Path",
"properties": [
{
"propertyId": 9,
"name": "Flat"
}
]
}
]
}
],
"name": "Marshmallow Playground",
"overall": "0.00",
"accuracy": "0.00",
"attitude": "0.00",
"createdTime": "2022-02-11T20:16:09.612Z",
"updatedTime": "2022-02-11T20:16:09.000Z"
}
The api handler function I implemented is as follows.
Future<dynamic> getVenueDetailsById({String? id}) async {
late int? _responseCode;
try {
final response = await _dio.get(
APIEndpoints.getVenueById "$id",
);
//
_responseCode = response.statusCode;
//
if (_responseCode == 200) {
if (response.data != null) {
//this is the point where the error shows up
DetailsModel res =
await DetailsModel.fromJson(jsonDecode(response.data));
log("get success ------------ ");
return HTTPResponse<dynamic>(
true,
res,
message: 'success',
code: _responseCode!,
);
}
} else {
log("get failed response ------------");
}
} on DioError catch (e) {
log("exception ------------ ${e.message}");
return HTTPResponse<dynamic>(
false,
null,
message: 'error: ${e.message}',
code: e.response!.statusCode!,
);
}
}
what should I do to make this success?
CodePudding user response:
A quick look at Dio documentation, it seems you should invoke toString on response.data:
DetailsModel res = await DetailsModel.fromJson(jsonDecode(response.data.toString()));
You can see the implementation here: https://pub.dev/documentation/dio/latest/dio/Response/toString.html
CodePudding user response:
You don't need jsonDecode
or await
on this line. But it's jsonDecode
thats causing the issue.
DetailsModel res = await DetailsModel.fromJson(jsonDecode(response.data));
Your response.data
is already in the form of a Map
so pass that directly into your DetailsModel.fromJson
.
As it stands now you're passing in a Map
into jsonDecode
which expects a String
, which explains the error you're getting.
Just change it to this and you should be good to go.
DetailsModel res = DetailsModel.fromJson(response.data);