Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic> While working on a Todo App - flutter

I am trying to get data from a local API into my project, i am facing the following problem:
Unhandled Exception: type 'List' is not a subtype of type 'Map<String, dynamic>'
// To parse this JSON data, do
//
// final toDo = toDoFromJson(jsonString);
import 'dart:convert';
import 'package:http/http.dart' as http;
ToDo toDoFromJson(String str) => ToDo.fromJson(json.decode(str));
String toDoToJson(ToDo data) => json.encode(data.toJson());
class ToDo {
ToDo({
required this.id,
required this.img,
required this.name,
required this.title,
required this.done,
required this.note,
required this.priority,
required this.dueDate,
required this.taskOwner,
required this.studentId,
required this.createdAt,
required this.updatedAt,
});
int id;
String img;
String name;
String title;
int done;
String note;
String priority;
String dueDate;
int taskOwner;
String studentId;
String createdAt;
String updatedAt;
factory ToDo.fromJson(Map<String, dynamic> json) => ToDo(
id: json["id"],
img: json["img"],
name: json["name"],
title: json["title"],
done: json["done"],
note: json["note"],
priority: json["priority"],
dueDate: json["due_date"],
taskOwner: json["TaskOwner"],
studentId: json["studentId"],
createdAt: json["createdAt"],
updatedAt: json["updatedAt"],
);
Map<String, dynamic> toJson() => {
"id": id,
"img": img,
"name": name,
"title": title,
"done": done,
"note": note,
"priority": priority,
"due_date": dueDate,
"TaskOwner": taskOwner,
"studentId": studentId,
"createdAt": createdAt,
"updatedAt": updatedAt,
};
}
Future<List<ToDo>> fetchTodos() async {
final response =
await http.get(Uri.parse('http://localhost:3000/task/all/1'));
if (response.statusCode == 200) {
final List<ToDo> todo = toDoFromJson(response.body) as List<ToDo>;
print(todo);
return todo;
} else {
print("nothing found");
return [];
}
}
Json from API is as below:
{
"id": 1,
"img": "assets/images/user/user1.jpg",
"name": "task 1",
"title": "eee",
"done": 0,
"note": "eee",
"priority": "Normal",
"due_date": "2021-07-06T18:30:00.000Z",
"TaskOwner": 1,
"studentId": "2",
"createdAt": "2021-07-26T14:39:54.000Z",
"updatedAt": "2021-07-26T14:39:54.000Z"
},
{
"id": 2,
"img": "assets/images/user/user1.jpg",
"name": "task 2",
"title": "nnjn",
"done": 0,
"note": "2525",
"priority": "High",
"due_date": "2021-07-19T18:30:00.000Z",
"TaskOwner": 1,
"studentId": "7",
"createdAt": "2021-07-27T15:05:31.000Z",
"updatedAt": "2021-07-27T15:05:31.000Z"
},
{
"id": 3,
"img": "assets/images/user/user1.jpg",
"name": "task 3",
"title": "5255",
"done": 0,
"note": "55",
"priority": "Normal",
"due_date": "2021-07-21T18:30:00.000Z",
"TaskOwner": 1,
"studentId": "7",
"createdAt": "2021-07-27T15:05:48.000Z",
"updatedAt": "2021-07-27T15:05:48.000Z"
},
{
"id": 4,
"img": "assets/images/user/user1.jpg",
"name": "task 4",
"title": "kaam kro",
"done": 0,
"note": "test note",
"priority": "Normal",
"due_date": "2021-07-21T18:30:00.000Z",
"TaskOwner": 1,
"studentId": "2",
"createdAt": "2021-08-04T14:45:47.000Z",
"updatedAt": "2021-08-04T14:45:47.000Z"
},

The method you are using to parse todos will return a ToDo object casted to a List<ToDo> which will cause an exception!
What you have to do is converting every single map in json to ToDo and then create a List from them.
Here is what you need to do:
replace this line
final List<ToDo> todo = toDoFromJson(response.body) as List<ToDo>;
with this:
final List<ToDo> todo = List<ToDo>.from(response.body.map((x) => toDoFromJson(x)))

fixed this by adding for loop to the Future function, refer to the code below -
Future<List<ToDo>> fetchTodos() async {
List<ToDo> todos = [];
final response =
await http.get(Uri.parse('https://dhulltransport.com:20625/task/all/1'));
if (response.statusCode == 200) {
var jsonList = jsonDecode(response.body);
for (var t in jsonList) {
todos.add(ToDo.fromJson(t));
}
print(todos.length);
return todos;
} else {
return [];
}
}

Related

type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>' Flutter

I need help on the following error type 'List' is not a subtype of type 'Map<String, dynamic>'
I tried every possible solution but I still cannot be able to solve it.
Future<List<Autogenerated>?> signInData() async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
try {
Response response = await _dio.post('$_baseUrl/api/gateway',
data: {
"ClientPackageId": "0cdd231a-d7ad-4a68-a934-d373affb5100",
"PlatformId": "ios",
"ClientUserId": "AhmedOmar",
"VinNumber": VINumber
},
options: Options(
headers: {
"Content-Type": "application/json;charset=UTF-8",
"Charset": 'utf-8',
"Authorization": "Bearer $token",
},
));
print("data is here");
print(json.encode(response.data));
print(response.statusCode);
if (response.statusCode == 200) {
print("decoded");
// return List<Autogenerated>.from(
// response.data.map((i) => Autogenerated.fromJson(i)));
//return Autogenerated.fromJson(jsonDecode(json.encode(response.data)));
return (response.data as List)
.map((e) => Autogenerated.fromJson(e))
.toList();
} else if (response.statusCode == 500) {
// call your refresh token api here and save it in shared preference
print(response.statusCode);
await getToken();
signInData();
} else {
throw Exception('Failed to load data');
}
} catch (e) {
print(e);
}
}
I am getting error in the following line:
return (response.data as List)
.map((e) => Autogenerated.fromJson(e))
.toList();
My model class below
class Autogenerated {
int? id;
int? sourceId;
int? serviceId;
int? categoryId;
String? category;
String? description;
int? serviceResponsePropertyId;
int? mappingId;
bool? isVisible;
int? packageRequestId;
int? sortOrder;
Value? value;
Autogenerated(
{this.id,
this.sourceId,
this.serviceId,
this.categoryId,
this.category,
this.description,
this.serviceResponsePropertyId,
this.mappingId,
this.isVisible,
this.packageRequestId,
this.sortOrder,
this.value});
Autogenerated.fromJson(Map<String, dynamic> json) {
id = json['Id'];
sourceId = json['SourceId'];
serviceId = json['ServiceId'];
categoryId = json['CategoryId'];
category = json['Category'];
description = json['Description'];
serviceResponsePropertyId = json['ServiceResponsePropertyId'];
mappingId = json['MappingId'];
isVisible = json['IsVisible'];
packageRequestId = json['PackageRequestId'];
sortOrder = json['SortOrder'];
value = json['Value'] != null ? new Value.fromJson(json['Value']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Id'] = this.id;
data['SourceId'] = this.sourceId;
data['ServiceId'] = this.serviceId;
data['CategoryId'] = this.categoryId;
data['Category'] = this.category;
data['Description'] = this.description;
data['ServiceResponsePropertyId'] = this.serviceResponsePropertyId;
data['MappingId'] = this.mappingId;
data['IsVisible'] = this.isVisible;
data['PackageRequestId'] = this.packageRequestId;
data['SortOrder'] = this.sortOrder;
if (this.value != null) {
data['Value'] = this.value!.toJson();
}
return data;
}
}
class Value {
String? make;
String? type;
String? model;
int? year;
String? body;
String? driveType;
String? fueType;
Value(
{this.make,
this.type,
this.model,
this.year,
this.body,
this.driveType,
this.fueType});
Value.fromJson(Map<String, dynamic> json) {
make = json['make'];
type = json['type'];
model = json['model'];
year = json['year'];
body = json['body'];
driveType = json['drive_type'];
fueType = json['fue_type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['make'] = this.make;
data['type'] = this.type;
data['model'] = this.model;
data['year'] = this.year;
data['body'] = this.body;
data['drive_type'] = this.driveType;
data['fue_type'] = this.fueType;
return data;
}
}
My response from API(It's long, I just shorten it)
[
{
"Id": 0,
"SourceId": 0,
"ServiceId": 11,
"CategoryId": 5,
"Category": "Valuation",
"Description": "AdjustedValues",
"Value": [],
"ServiceResponsePropertyId": 474,
"MappingId": 0,
"IsVisible": true,
"PackageRequestId": 13853506,
"SortOrder": 1
},
{
"Id": 0,
"SourceId": 0,
"ServiceId": 11,
"CategoryId": 1,
"Category": "General",
"Description": "ServiceStatus",
"Value": {
"StatusCode": 1,
"StatusDescription": "Ok",
"StatusDetail": "",
"RestServiceStatus": null,
"ServiceResource": null
},
"ServiceResponsePropertyId": 475,
"MappingId": 0,
"IsVisible": false,
"PackageRequestId": 13853506,
"SortOrder": 1
},
{
"Id": 0,
"SourceId": 0,
"ServiceId": 6,
"CategoryId": 1,
"Category": "General",
"Description": "CarId",
"Value": 120354,
"ServiceResponsePropertyId": 100,
"MappingId": 0,
"IsVisible": false,
"PackageRequestId": 13853506,
"SortOrder": 1
},
{
"Id": 0,
"SourceId": 0,
"ServiceId": 6,
"CategoryId": 1,
"Category": "General",
"Description": "Year",
"Value": 2017,
"ServiceResponsePropertyId": 103,
"MappingId": 0,
"IsVisible": true,
"PackageRequestId": 13853506,
"SortOrder": 6
},
{
"Id": 0,
"SourceId": 0,
"ServiceId": 6,
"CategoryId": 1,
"Category": "General",
"Description": "Full Model Description",
"Value": "2017 AUDI A3 Sedan 1.0T FSI S tronic [2016-2017]",
"ServiceResponsePropertyId": 104,
"MappingId": 0,
"IsVisible": false,
"PackageRequestId": 13853506,
"SortOrder": 1
},
I cannot display data in lisview and I think it is because of this error. Please can you check there and please assist. Thank you in advance.
The error probably has been mis-attributed to the method Autogenerated.fromJson.
Problem
The method Value.fromJson() expects a Map<String, dynamic>:
Value.fromJson(Map<String, dynamic> json).
But the response.data shows that Value can be many things:
a List: "Value": []
a String: "Value": "abc"
a Map: "Value": { ... }
a Int: "Value": 123
Note
The first Value item in your response.data is a List. Which explains why the code is complaining about expecting a Map but getting a List.
Solution
Value.fromJson(...) needs to be able to handle lists, Strings, Ints, Maps etc. Not only Maps.

Dart - Convert Map of objects fetched via HTTP REST-API

For my Calendar i get the following data as JSON from the Backend (*JAVA-Type = Map<LocalDate, List<Event>>):
{
"2022-05-28": [
{
"id": 2,
"title": "Multi day Event",
"fromDate": "2022-05-27T12:22:03.873569",
"toDate": "2022-05-28T11:22:03.873569",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "sozial"
}
],
"2022-05-27": [
{
"id": 2,
"title": "Multi day Event",
"fromDate": "2022-05-27T12:22:03.873569",
"toDate": "2022-05-28T11:22:03.873569",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "sozial"
},
{
"id": 1,
"title": "Testevent",
"fromDate": "2022-05-27T11:21:04.573754",
"toDate": "2022-05-27T12:21:04.573754",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "normal"
}
],
}
My Event Class looks like:
Class Event {
int id;
String title;
DateTime fromDate;
DateTime toDate;
Room room;
User user;
String eventType;
}
Now i need the same structure i had in the Backend (Map<DateTime, <List<Event>>) for my Calendar widget and i have no real clue on how to do it. I know how to convert json data into an object if i get a list of an object, but how can i store the date as key of the resulting map?
My code by now:
Future<Map<DateTime, List<Event>>> getEvents(DateTime _fromDate, DateTime
_endDate) async {
String _from = _fromDate.toString().split('.').first;
String _end = _endDate.toString().split('.').first;
final response = await get('${_url}calendar/events/$_from/$_end',
headers: {HttpHeaders.authorizationHeader: 'Bearer $_bearer'});
if (response.status.hasError) {
return Future.error('${response.statusText}');
} else {
final parsed = jsonDecode(response.body);
return parsed;
}
}
You need to do something like that:
var json = {...}; // <-- json obj
// method to parse data to map with list Event
dynamic fromJson(Map<String, dynamic> json){
var map = new Map();
json.keys.forEach((key){
// key is the date
map[key] = json[key].map((e) => Event.fromJson(e)).toList(); // <- need to create a method fromJson in your Event class
});
return map;
}
(...)
class Event {
int id;
String title;
DateTime fromDate;
DateTime toDate;
Room room;
User user;
String eventType;
fromJson(Map<String, dynamic> json) => Event(...); // <- parse json to Event class
}

type '(dynamic) => Product' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform'

I am trying to consume data from an API. I used quicktype.io to create a model class to parse the JSON data. The JSON data contains nested maps.
Now I am getting an error
The error is [type '(dynamic) => Product' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform']
This is the code for API request;
Future<void> setSpecials(String restaurantId) async {
try {
final url = Uri.parse(
ENDPOINT + 'restaurant/specials?restaurantId=$restaurantId&page=0');
final response = await http.get(url);
print(response.statusCode);
if (response.statusCode == 200) {
final List<Product> specials = productFromJson(response.body);
_specialsList = specials;
}
print(_specialsList.length);
notifyListeners();
} catch (e) {
print(e.toString());
}}
This is the model
List<Product> productFromJson(String str) => List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
String productToJson(List<Product> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Product {
Product({
required this.id,
required this.name,
required this.image,
required this.description,
required this.isFavourite,
required this.dishes,
required this.diet,
});
String id;
String name;
String image;
String description;
bool isFavourite;
List<Dish> dishes;
String diet;
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json["_id"],
name: json["name"],
image: json["image"],
description: json["description"],
isFavourite: json["isFavourite"],
dishes: List<Dish>.from(json["dishes"].map((x) => Dish.fromJson(x))),
diet: json["diet"] == null ? null : json["diet"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"name": name,
"image": image,
"description": description,
"isFavourite": isFavourite,
"dishes": List<dynamic>.from(dishes.map((x) => x.toJson())),
"diet": diet == null ? null : diet,
};
}
class Dish {
Dish({
required this.name,
required this.price,
required this.offerIds,
required this.id,
});
String name;
double price;
List<dynamic> offerIds;
String id;
factory Dish.fromJson(Map<String, dynamic> json) => Dish(
name: json["name"],
price: double.parse(json["price"].toString()),
offerIds: List<dynamic>.from(json["offerIds"].map((x) => x)),
id: json["_id"],
);
Map<String, dynamic> toJson() => {
"name": name,
"price": price,
"offerIds": List<dynamic>.from(offerIds.map((x) => x)),
"_id": id,
};
}
The JSON data is
[
{
"_id": "60edb147d91f7820c80585c9",
"name": "Chicken Biriyani",
"image": "localhost:3031\\images\\1626190484369-chicken-Biryani.jpg",
"description": "Chicken, Motton",
"isFavourite": false,
"dishes": [
{
"name": "Full",
"price": 200,
"offerIds": [],
"_id": "610e1cd618319924b45ef9cd"
},
{
"name": "Half",
"price": 150,
"offerIds": [],
"_id": "610e1cd618319924b45ef9ce"
},
{
"name": "Quarter",
"price": 100,
"offerIds": [],
"_id": "610e1cd618319924b45ef9cf"
}
]
},
{
"_id": "610cb83c231052429899df76",
"name": "Shavrma",
"image": "157.245.96.189:3031/images/1632371901688-IMG-20210922-WA0123.jpg",
"description": "Chicken Shavrma",
"diet": "Veg",
"isFavourite": false,
"dishes": [
{
"name": "Plate",
"price": 80,
"offerIds": [],
"_id": "610cb83c231052429899df77"
},
{
"name": "Roll",
"price": 60,
"offerIds": [],
"_id": "610cb83c231052429899df78"
}
]
}
]

How to display Nested api data using model class in listview in Flutter?

I am tried to display data in listview.
I have Json Response as below.
[
{
"success": 1,
"subject": [
{
"subject_id": "5e32874c714fa",
"subject_name": "Account",
"image": "upload/subject/Account.png",
"active": "1",
"standard_id": "5d1594e283e1a",
"medium_id": "5d15938aa1344"
},
{
"subject_id": "5da9ff659fb7c",
"subject_name": "Biology",
"image": "upload/subject/03_logo-1164x484.png",
"active": "1",
"standard_id": "5d1594e283e1a",
"medium_id": "5d15938aa1344"
},
{
"subject_id": "5da9ff990b1c6",
"subject_name": "Chemisty",
"image": "upload/subject/02_logo-1168x490.png",
"active": "1",
"standard_id": "5d1594e283e1a",
"medium_id": "5d15938aa1344"
},
{
"subject_id": "5de76afbd064e",
"subject_name": "Computer",
"image": "upload/subject/07_logo-1169x486.png",
"active": "1",
"standard_id": "5d1594e283e1a",
"medium_id": "5d15938aa1344"
},
{
"subject_id": "5d788906c431b",
"subject_name": "Devsatya Paperset March 2020",
"image": "upload/subject/04_logo-1174x491.png",
"active": "1",
"standard_id": "5d1594e283e1a",
"medium_id": "5d15938aa1344"
}
]
}
]
as above response i create a model class as below
// To parse this JSON data, do
//
// final subjectByUser = subjectByUserFromJson(jsonString);
import 'dart:convert';
List<SubjectByUser> subjectByUserFromJson(String str) =>
List<SubjectByUser>.from(
json.decode(str).map((x) => SubjectByUser.fromJson(x)));
String subjectByUserToJson(List<SubjectByUser> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class SubjectByUser {
SubjectByUser({
required this.success,
required this.subject,
});
int success;
List<Subject> subject;
factory SubjectByUser.fromJson(Map<String, dynamic> json) => SubjectByUser(
success: json["success"],
subject:
List<Subject>.from(json["subject"].map((x) => Subject.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"success": success,
"subject": List<dynamic>.from(subject.map((x) => x.toJson())),
};
}
class Subject {
Subject({
required this.subjectId,
required this.subjectName,
required this.image,
required this.active,
required this.standardId,
required this.mediumId,
});
String subjectId;
String subjectName;
String image;
String active;
String standardId;
String mediumId;
factory Subject.fromJson(Map<String, dynamic> json) => Subject(
subjectId: json["subject_id"],
subjectName: json["subject_name"],
image: json["image"],
active: json["active"],
standardId: json["standard_id"],
mediumId: json["medium_id"],
);
Map<String, dynamic> toJson() => {
"subject_id": subjectId,
"subject_name": subjectName,
"image": image,
"active": active,
"standard_id": standardId,
"medium_id": mediumId,
};
}
I write below code, now how can i display subjects data like subjectName, image, etc in list view?
in print i can get the subject name on index 3.
Future getUserSubject(List subject) async {
final subjectUrl =
"$baseUrl/subject/get_by_user_plan?user_id=609cab2cd5b6c&order_id=1620889722609cd07a601af469889697609cab2cd5b6c&standard_id=5d1594e283e1a&medium_id=5d15938aa1344";
final response = await http.get(Uri.parse(subjectUrl));
final subjects = response.body;
final decodedData = jsonDecode(subjects);
SubjectByUserModel subjectByUserModel =
SubjectByUserModel.fromJson(decodedData);
print(subjectByUserModel.subject?[2].subjectName);
}
I put all codes in separate file also view
You can use ListView.builder
ListView.builder(
itemCount: subjectByUserModel.subject ?? 0,
itemBuilder: (BuildContext context, int index) {
print(subjectByUserModel.subject?[index].subjectName);
print(subjectByUserModel.subject?[index].standardId); // so on
// Now you can build any widget for per subject.
// like card, listTile or simple text.
return Text('');
});

Flutter return array from response from server

in this part of my code await webApi.getKeywords(); return array which that can get from server, now when i try to return that i get error:
type 'List<dynamic>' is not a subtype of type 'String'
get data from server code:
Future<List<KeywordsResponse>> _getKeywords(BuildContext context) async {
try {
final webApi = Provider.of<WebApi>(context);
final response = await webApi.getKeywords();
List<KeywordsResponse> list = List();
if (response.statusCode == 200) {
list = (json.decode(response.body) as List)
.map((data) => new KeywordsResponse.fromJson(data))
.toList();
return list;
} else {
throw Exception('Failed to load photos');
}
} catch (error) {
print(error);
return null;
}
}
KeywordsResponse class:
#JsonSerializable(nullable: true)
class KeywordsResponse{
#JsonKey(name:'id')
final int id;
#JsonKey(name:'title')
final String title;
#JsonKey(name:'description')
final String description;
KeywordsResponse(this.id, this.title, this.description);
factory KeywordsResponse.fromJson(Map<String, dynamic> json) => _$KeywordsResponseFromJson(json);
Map<String, dynamic> toJson() => _$KeywordsResponseToJson(this);
}
return of response.body:
[
{
"id": 1,
"user_id": 1,
"title": "asdasdasd",
"description": "asdasdasd",
"type": "post",
"slug": "asdasdad",
"featured_images": {
"images": {
"300": "/uploads/post_images/2019/300_1573573784.png",
"600": "/uploads/post_images/2019/600_1573573784.png",
"900": "/uploads/post_images/2019/900_1573573784.png",
"original": "/uploads/post_images/2019/1573573784.png"
},
"thumbnail": "/uploads/post_images/2019/300_1573573784.png"
},
"lang": "fa",
"visit": 0,
"categories": [
{
"id": 1,
"title": "aaaaaaa",
"lang": "fa",
"parent": 0,
"pivot": {
"contents_id": 1,
"content_categories_id": 1
}
}
]
},
{
"id": 2,
"user_id": 1,
"title": "asdasdasd",
"description": "asdadasd",
"type": "post",
"slug": "asdasdasda",
"featured_images": {
"images": {
"300": "/uploads/post_images/2019/300_1573573846.png",
"600": "/uploads/post_images/2019/600_1573573846.png",
"900": "/uploads/post_images/2019/900_1573573846.png",
"original": "/uploads/post_images/2019/1573573846.png"
},
"thumbnail": "/uploads/post_images/2019/300_1573573846.png"
},
"lang": "fa",
"visit": 0,
"categories": [
{
"id": 2,
"title": "bbbbbbbb",
"lang": "fa",
"parent": 0,
"pivot": {
"contents_id": 2,
"content_categories_id": 2
}
}
]
}
]
problem is on this line of code:
json.decode(response.body)
Try this:
list = List<KeywordsResponse>.from(response.body.map((x) => KeywordsResponse.fromJson(x)));