I am trying to fetch data from backend and store it in my app. However when I am using method to fetch it i am facing this error Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'StartChapter'
. Is my model set up wrong or the fetching function is written wrong? Can someone advice me something? Thanks
Method that fetches data:
Future<List<Adventures>> getAdventureList() async {
var response = await getAdventures(apiClient);
return List<Adventures>.from((response.data["collection"]).map((json) => Adventures.fromJson(json)));
}
I am trying to fetch data from my backend, example JSON looks like:
{
"collection":[
{
"completed":true,
"creator_id":"4b94b85f-696e-4682-9534-572d1b2bc47f",
"creator_nick":"master_of_adventure69",
"description":"go on a wonderful adventure through the streets of the old town ...",
"favorite":true,
"id":"ffcc3fad-8bc2-4ba3-9b8e-59d77b2bff23",
"name":"The best adventure in the world",
"start_chapter":{
"completed":true,
"description":"at this point you must demonstrate extraordinary intelligence ...",
"id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
"name":"first point in adventure",
"position":{
"lat":53.01379,
"lon":18.598444
},
"question":[
{
"chapter_id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
"description":"What has a tail and barks?",
"id":"3718f6a9-fff1-4a15-9a24-ae3fa90b4141",
"sort":1,
"type":"tip/question"
}
],
"radius":500,
"ridle":{
"answer":"42856",
"id":"ce8545e6-eeca-41c0-9026-9084df5aad13",
"type":"number_lock_5"
},
"tips":[
{
"chapter_id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
"description":"What has a tail and barks?",
"id":"3718f6a9-fff1-4a15-9a24-ae3fa90b4141",
"sort":1,
"type":"tip/question"
}
]
}
}
],
"page":1,
"page_size":50,
"total_pages":1
}
Model
class Adventure {
List<Adventures>? collection;
int page;
int page_size;
int total_pages;
int total_results;
Adventure({ this.collection, required this.page, required this.page_size, required this.total_pages,
required this.total_results });
factory Adventure.fromJson(Map<String, dynamic> json) {
return Adventure(
collection: json['collection'].map((item) => Adventures.fromJson(item)).toList(),
page: json['page'],
page_size: json['page_size'],
total_pages: json['total_pages'],
total_results: json['total_results']
);
}
}
class Adventures {
bool completed;
String creatorId;
String creatorNick;
String? description;
bool favorite;
String id;
String name;
StartChapter startChapter;
Adventures(
{required this.completed,
required this.creatorId,
required this.creatorNick,
this.description,
required this.favorite,
required this.id,
required this.name,
required this.startChapter});
factory Adventures.fromJson(Map<String, dynamic> json) {
return Adventures(
completed: json['completed'],
creatorId: json['creator_id'],
creatorNick: json['creator_nick'],
description: json['description'],
favorite: json['favorite'],
id: json['id'],
name: json['name'],
startChapter: json['start_chapter']
);
}
}
and so on
CodePudding user response:
If you have a already StartChapter model and 'fromJson' method,
try to change like below.
class Adventures {
bool completed;
String creatorId;
String creatorNick;
String? description;
bool favorite;
String id;
String name;
StartChapter startChapter;
Adventures(
{required this.completed,
required this.creatorId,
required this.creatorNick,
this.description,
required this.favorite,
required this.id,
required this.name,
required this.startChapter});
factory Adventures.fromJson(Map<String, dynamic> json) {
return Adventures(
completed: json['completed'],
creatorId: json['creator_id'],
creatorNick: json['creator_nick'],
description: json['description'],
favorite: json['favorite'],
id: json['id'],
name: json['name'],
startChapter: json['start_chapter'] != null ? StartChapter.fromJson(json['start_chapter']) : null
);
}
}
If not, define 'fromJson' into the StartChapter class.
Or change startChapter's type from 'StartChapter' to 'Map<String, dynamic>' class.
class Adventures {
bool completed;
String creatorId;
String creatorNick;
String? description;
bool favorite;
String id;
String name;
Map<String, dynamic> startChapter;
...
CodePudding user response:
This error occurred because you are passing wrong
data type value to the variable
.
start_chapter
accepts type of StartChapter
but you are passing Map here :
"start_chapter":{
"completed":true,
"description":"at this point you must demonstrate extraordinary intelligence ...",
"id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
"name":"first point in adventure",
"position":{
"lat":53.01379,
"lon":18.598444
},
"question":[
{
"chapter_id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
"description":"What has a tail and barks?",
"id":"3718f6a9-fff1-4a15-9a24-ae3fa90b4141",
"sort":1,
"type":"tip/question"
}
],
"radius":500,
"ridle":{
"answer":"42856",
"id":"ce8545e6-eeca-41c0-9026-9084df5aad13",
"type":"number_lock_5"
},
"tips":[
{
"chapter_id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
"description":"What has a tail and barks?",
"id":"3718f6a9-fff1-4a15-9a24-ae3fa90b4141",
"sort":1,
"type":"tip/question"
}
]
}
}
You need to pass data type of StartChapter
to solve this issue.
Use below model :
import 'dart:convert';
Adventure adventureFromJson(String str) => Adventure.fromJson(json.decode(str));
String adventureToJson(Adventure data) => json.encode(data.toJson());
class Adventure {
Adventure({
this.collection,
this.page,
this.pageSize,
this.totalPages,
});
List<Collection> collection;
int page;
int pageSize;
int totalPages;
factory Adventure.fromJson(Map<String, dynamic> json) => Adventure(
collection: json["collection"] == null ? null : List<Collection>.from(json["collection"].map((x) => Collection.fromJson(x))),
page: json["page"] == null ? null : json["page"],
pageSize: json["page_size"] == null ? null : json["page_size"],
totalPages: json["total_pages"] == null ? null : json["total_pages"],
);
Map<String, dynamic> toJson() => {
"collection": collection == null ? null : List<dynamic>.from(collection.map((x) => x.toJson())),
"page": page == null ? null : page,
"page_size": pageSize == null ? null : pageSize,
"total_pages": totalPages == null ? null : totalPages,
};
}
class Collection {
Collection({
this.completed,
this.creatorId,
this.creatorNick,
this.description,
this.favorite,
this.id,
this.name,
this.startChapter,
});
bool completed;
String creatorId;
String creatorNick;
String description;
bool favorite;
String id;
String name;
StartChapter startChapter;
factory Collection.fromJson(Map<String, dynamic> json) => Collection(
completed: json["completed"] == null ? null : json["completed"],
creatorId: json["creator_id"] == null ? null : json["creator_id"],
creatorNick: json["creator_nick"] == null ? null : json["creator_nick"],
description: json["description"] == null ? null : json["description"],
favorite: json["favorite"] == null ? null : json["favorite"],
id: json["id"] == null ? null : json["id"],
name: json["name"] == null ? null : json["name"],
startChapter: json["start_chapter"] == null ? null : StartChapter.fromJson(json["start_chapter"]),
);
Map<String, dynamic> toJson() => {
"completed": completed == null ? null : completed,
"creator_id": creatorId == null ? null : creatorId,
"creator_nick": creatorNick == null ? null : creatorNick,
"description": description == null ? null : description,
"favorite": favorite == null ? null : favorite,
"id": id == null ? null : id,
"name": name == null ? null : name,
"start_chapter": startChapter == null ? null : startChapter.toJson(),
};
}
class StartChapter {
StartChapter({
this.completed,
this.description,
this.id,
this.name,
this.position,
this.question,
this.radius,
this.ridle,
this.tips,
});
bool completed;
String description;
String id;
String name;
Position position;
List<Question> question;
int radius;
Ridle ridle;
List<Question> tips;
factory StartChapter.fromJson(Map<String, dynamic> json) => StartChapter(
completed: json["completed"] == null ? null : json["completed"],
description: json["description"] == null ? null : json["description"],
id: json["id"] == null ? null : json["id"],
name: json["name"] == null ? null : json["name"],
position: json["position"] == null ? null : Position.fromJson(json["position"]),
question: json["question"] == null ? null : List<Question>.from(json["question"].map((x) => Question.fromJson(x))),
radius: json["radius"] == null ? null : json["radius"],
ridle: json["ridle"] == null ? null : Ridle.fromJson(json["ridle"]),
tips: json["tips"] == null ? null : List<Question>.from(json["tips"].map((x) => Question.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"completed": completed == null ? null : completed,
"description": description == null ? null : description,
"id": id == null ? null : id,
"name": name == null ? null : name,
"position": position == null ? null : position.toJson(),
"question": question == null ? null : List<dynamic>.from(question.map((x) => x.toJson())),
"radius": radius == null ? null : radius,
"ridle": ridle == null ? null : ridle.toJson(),
"tips": tips == null ? null : List<dynamic>.from(tips.map((x) => x.toJson())),
};
}
class Position {
Position({
this.lat,
this.lon,
});
double lat;
double lon;
factory Position.fromJson(Map<String, dynamic> json) => Position(
lat: json["lat"] == null ? null : json["lat"].toDouble(),
lon: json["lon"] == null ? null : json["lon"].toDouble(),
);
Map<String, dynamic> toJson() => {
"lat": lat == null ? null : lat,
"lon": lon == null ? null : lon,
};
}
class Question {
Question({
this.chapterId,
this.description,
this.id,
this.sort,
this.type,
});
String chapterId;
String description;
String id;
int sort;
String type;
factory Question.fromJson(Map<String, dynamic> json) => Question(
chapterId: json["chapter_id"] == null ? null : json["chapter_id"],
description: json["description"] == null ? null : json["description"],
id: json["id"] == null ? null : json["id"],
sort: json["sort"] == null ? null : json["sort"],
type: json["type"] == null ? null : json["type"],
);
Map<String, dynamic> toJson() => {
"chapter_id": chapterId == null ? null : chapterId,
"description": description == null ? null : description,
"id": id == null ? null : id,
"sort": sort == null ? null : sort,
"type": type == null ? null : type,
};
}
class Ridle {
Ridle({
this.answer,
this.id,
this.type,
});
String answer;
String id;
String type;
factory Ridle.fromJson(Map<String, dynamic> json) => Ridle(
answer: json["answer"] == null ? null : json["answer"],
id: json["id"] == null ? null : json["id"],
type: json["type"] == null ? null : json["type"],
);
Map<String, dynamic> toJson() => {
"answer": answer == null ? null : answer,
"id": id == null ? null : id,
"type": type == null ? null : type,
};
}