在颤振转换中解析 JSON<RK, RV>() => map<RK, RV>, 没有这样的方法错误


Future<List<CurrentUser>> getCurrUserSettings() async {
int id = await getCurrentUser();
print(id);
final _storage = FlutterSecureStorage();
_token = await _storage.read(key: "token");
var api = API();
// TODO resolve id so that we have it on the start and not called everytime
String newUrl = "${api.baseUrl}${api.cuUser}$id";
var url = Uri.parse(newUrl);
var response = await http.get(
url,
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': "Bearer $_token",
},
);
if (response.statusCode == 200) {
final parsed = jsonDecode(response.body).cast<Map<String, dynamic>>();
return parsed
.map<CurrentUser>((json) => CurrentUser.fromJson(json))
.toList();
} else {
print(response.statusCode);
}
return null; }

这是我用来调用当前用户数据的代码。此函数返回一个列表。我已经用同样的技术进行了许多其他API调用,所有这些调用都运行得很好,但只有在这个方法中,我才会得到以下错误。

E/flutter (14954): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'cast' with matching arguments.
E/flutter (14954): Receiver: _LinkedHashMap len:16
E/flutter (14954): Tried calling: cast<Map<String, dynamic>>()
E/flutter (14954): Found: cast<RK, RV>() => Map<RK, RV>
E/flutter (14954): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
E/flutter (14954): #1      AuthService.getCurrUserSettings
package:App/…/Services/Auth.dart:73
E/flutter (14954): <asynchronous suspension>
E/flutter (14954): #2      DrawerUserInfo.getUserInfo
package:App/…/components/drawerProvider.dart:10
E/flutter (14954): <asynchronous suspension>

我也在分享模型文件,请看一看。有一段时间我一直被这个问题困扰着,我使用了许多不同的模型,每个模型的错误都是一样的。

响应Json

{
"id": 3,
"username": "PlayPizza",
"email": "play@pizza.com",
"provider": "local",
"confirmed": true,
"blocked": null,
"role": {
"id": 1,
"name": "Authenticated",
"description": "Default role given to authenticated user.",
"type": "authenticated"
},
"displayName": "PlayPizza",
"user_information": {
"id": 1,
"country": "India",
"state": "Delhi",
"address": "Some address",
"postalcode": "110092",
"users_permissions_user": 3,
"published_at": "2021-07-04T21:24:46.324Z",
"created_at": "2021-07-04T21:24:43.063Z",
"updated_at": "2021-07-04T21:24:46.409Z",
"certificate": {
"id": 1,
"name": "1_9cb3b3b033.jpg",
"alternativeText": "",
"caption": "",
"width": 300,
"height": 300,
"formats": {
"thumbnail": {
"ext": ".jpg",
"url": "/uploads/thumbnail_1_9cb3b3b033_7980eea4f5.jpg",
"hash": "thumbnail_1_9cb3b3b033_7980eea4f5",
"mime": "image/jpeg",
"name": "thumbnail_1_9cb3b3b033.jpg",
"path": null,
"size": 2.48,
"width": 156,
"height": 156
}
},
"hash": "1_9cb3b3b033_7980eea4f5",
"ext": ".jpg",
"mime": "image/jpeg",
"size": 5.28,
"url": "/uploads/1_9cb3b3b033_7980eea4f5.jpg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2021-07-04T15:03:55.744Z",
"updated_at": "2021-07-04T15:03:55.798Z"
}
},
"feedback": "hello",
"created_at": "2021-07-04T19:59:30.024Z",
"updated_at": "2021-07-04T21:26:41.314Z",
"avatar": {
"id": 10,
"name": "customer_3_008140d19d.png",
"alternativeText": "",
"caption": "",
"width": 180,
"height": 180,
"formats": {
"thumbnail": {
"ext": ".png",
"url": "/uploads/thumbnail_customer_3_008140d19d_a96cc0a5e3.png",
"hash": "thumbnail_customer_3_008140d19d_a96cc0a5e3",
"mime": "image/png",
"name": "thumbnail_customer_3_008140d19d.png",
"path": null,
"size": 62.71,
"width": 156,
"height": 156
}
},
"hash": "customer_3_008140d19d_a96cc0a5e3",
"ext": ".png",
"mime": "image/png",
"size": 65.81,
"url": "/uploads/customer_3_008140d19d_a96cc0a5e3.png",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2021-07-04T17:59:44.000Z",
"updated_at": "2021-07-04T17:59:44.024Z"
},
"user_categories": [
{
"id": 1,
"categoryName": "GymGoer",
"users_permissions_user": 3,
"published_at": "2021-07-04T15:53:43.824Z",
"created_at": "2021-07-04T15:53:39.228Z",
"updated_at": "2021-07-04T21:26:41.307Z"
}
],
"workoutplaces": [
{
"id": 2,
"title": "Gym Nation",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
"location": "145 Marlee Ave, York, ON M6B 3H3, Canada",
"price": 88.26,
"rating": 4.5,
"latitude": 43.80946617910369,
"longitude": -79.26975142707997,
"users_permissions_user": 3,
"published_at": "2021-07-04T17:09:53.162Z",
"created_at": "2021-07-04T17:09:50.238Z",
"updated_at": "2021-07-04T21:26:41.308Z",
"coverimg": {
"id": 8,
"name": "large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3.jpg",
"alternativeText": "",
"caption": "",
"width": 1000,
"height": 666,
"formats": {
"small": {
"ext": ".jpg",
"url": "/uploads/small_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3_fe08736916.jpg",
"hash": "small_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3_fe08736916",
"mime": "image/jpeg",
"name": "small_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3.jpg",
"path": null,
"size": 27.34,
"width": 500,
"height": 333
},
"medium": {
"ext": ".jpg",
"url": "/uploads/medium_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3_fe08736916.jpg",
"hash": "medium_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3_fe08736916",
"mime": "image/jpeg",
"name": "medium_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3.jpg",
"path": null,
"size": 48.79,
"width": 750,
"height": 500
},
"thumbnail": {
"ext": ".jpg",
"url": "/uploads/thumbnail_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3_fe08736916.jpg",
"hash": "thumbnail_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3_fe08736916",
"mime": "image/jpeg",
"name": "thumbnail_large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3.jpg",
"path": null,
"size": 9.3,
"width": 234,
"height": 156
}
},
"hash": "large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3_fe08736916",
"ext": ".jpg",
"mime": "image/jpeg",
"size": 74.23,
"url": "/uploads/large_sule_makaroglu_Y_Fmvj_O3_TP_s_unsplash_c546ce68c3_fe08736916.jpg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2021-07-04T17:05:47.094Z",
"updated_at": "2021-07-04T17:05:47.104Z"
}
}
],
"upcomming_classes": [
{
"id": 1,
"name": "Yoga house",
"description": "Some Description",
"date": "2021-07-13",
"time": "01:30:00",
"confirmed": true,
"paid": true,
"price": 59.33,
"workoutplace": 1,
"users_permissions_user": 3,
"month": "July",
"published_at": null,
"created_at": "2021-07-04T21:26:23.276Z",
"updated_at": "2021-07-04T21:26:41.309Z"
}
]}

模型文件

import 'dart:convert';
CurrentUser currentUserFromJson(String str) =>
CurrentUser.fromJson(json.decode(str));
String currentUserToJson(CurrentUser data) => json.encode(data.toJson());
class CurrentUser {
CurrentUser({
this.id,
this.username,
this.email,
this.provider,
this.confirmed,
this.blocked,
this.role,
this.displayName,
this.userInformation,
this.feedback,
this.createdAt,
this.updatedAt,
this.avatar,
this.userCategories,
this.workoutplaces,
this.upcommingClasses,
});
int id;
String username;
String email;
String provider;
bool confirmed;
dynamic blocked;
Role role;
String displayName;
UserInformation userInformation;
String feedback;
DateTime createdAt;
DateTime updatedAt;
Avatar avatar;
List<UserCategory> userCategories;
List<Workoutplace> workoutplaces;
List<UpcommingClass> upcommingClasses;
factory CurrentUser.fromJson(Map<String, dynamic> json) => CurrentUser(
id: json["id"],
username: json["username"],
email: json["email"],
provider: json["provider"],
confirmed: json["confirmed"],
blocked: json["blocked"],
role: Role.fromJson(json["role"]),
displayName: json["displayName"],
userInformation: UserInformation.fromJson(json["user_information"]),
feedback: json["feedback"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
avatar: Avatar.fromJson(json["avatar"]),
userCategories: List<UserCategory>.from(
json["user_categories"].map((x) => UserCategory.fromJson(x))),
workoutplaces: List<Workoutplace>.from(
json["workoutplaces"].map((x) => Workoutplace.fromJson(x))),
upcommingClasses: List<UpcommingClass>.from(
json["upcomming_classes"].map((x) => UpcommingClass.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"username": username,
"email": email,
"provider": provider,
"confirmed": confirmed,
"blocked": blocked,
"role": role.toJson(),
"displayName": displayName,
"user_information": userInformation.toJson(),
"feedback": feedback,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
"avatar": avatar.toJson(),
"user_categories":
List<dynamic>.from(userCategories.map((x) => x.toJson())),
"workoutplaces":
List<dynamic>.from(workoutplaces.map((x) => x.toJson())),
"upcomming_classes":
List<dynamic>.from(upcommingClasses.map((x) => x.toJson())),
};
}
class Avatar {
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,
});
int id;
String name;
String alternativeText;
String caption;
int width;
int height;
AvatarFormats formats;
String hash;
String ext;
String mime;
double size;
String url;
dynamic previewUrl;
String provider;
dynamic providerMetadata;
DateTime createdAt;
DateTime updatedAt;
factory Avatar.fromJson(Map<String, dynamic> json) => Avatar(
id: json["id"],
name: json["name"],
alternativeText: json["alternativeText"],
caption: json["caption"],
width: json["width"],
height: json["height"],
formats: AvatarFormats.fromJson(json["formats"]),
hash: json["hash"],
ext: json["ext"],
mime: json["mime"],
size: json["size"].toDouble(),
url: json["url"],
previewUrl: json["previewUrl"],
provider: json["provider"],
providerMetadata: json["provider_metadata"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"alternativeText": alternativeText,
"caption": caption,
"width": width,
"height": height,
"formats": formats.toJson(),
"hash": hash,
"ext": ext,
"mime": mime,
"size": size,
"url": url,
"previewUrl": previewUrl,
"provider": provider,
"provider_metadata": providerMetadata,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
class AvatarFormats {
AvatarFormats({
this.thumbnail,
});
Thumbnail thumbnail;
factory AvatarFormats.fromJson(Map<String, dynamic> json) => AvatarFormats(
thumbnail: Thumbnail.fromJson(json["thumbnail"]),
);
Map<String, dynamic> toJson() => {
"thumbnail": thumbnail.toJson(),
};
}
class Thumbnail {
Thumbnail({
this.ext,
this.url,
this.hash,
this.mime,
this.name,
this.path,
this.size,
this.width,
this.height,
});
String ext;
String url;
String hash;
String mime;
String name;
dynamic path;
double size;
int width;
int height;
factory Thumbnail.fromJson(Map<String, dynamic> json) => Thumbnail(
ext: json["ext"],
url: json["url"],
hash: json["hash"],
mime: json["mime"],
name: json["name"],
path: json["path"],
size: json["size"].toDouble(),
width: json["width"],
height: json["height"],
);
Map<String, dynamic> toJson() => {
"ext": ext,
"url": url,
"hash": hash,
"mime": mime,
"name": name,
"path": path,
"size": size,
"width": width,
"height": height,
};
}
class Role {
Role({
this.id,
this.name,
this.description,
this.type,
});
int id;
String name;
String description;
String type;
factory Role.fromJson(Map<String, dynamic> json) => Role(
id: json["id"],
name: json["name"],
description: json["description"],
type: json["type"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"description": description,
"type": type,
};
}
class UpcommingClass {
UpcommingClass({
this.id,
this.name,
this.description,
this.date,
this.time,
this.confirmed,
this.paid,
this.price,
this.workoutplace,
this.usersPermissionsUser,
this.month,
this.publishedAt,
this.createdAt,
this.updatedAt,
});
int id;
String name;
String description;
DateTime date;
String time;
bool confirmed;
bool paid;
double price;
int workoutplace;
int usersPermissionsUser;
String month;
dynamic publishedAt;
DateTime createdAt;
DateTime updatedAt;
factory UpcommingClass.fromJson(Map<String, dynamic> json) => UpcommingClass(
id: json["id"],
name: json["name"],
description: json["description"],
date: DateTime.parse(json["date"]),
time: json["time"],
confirmed: json["confirmed"],
paid: json["paid"],
price: json["price"].toDouble(),
workoutplace: json["workoutplace"],
usersPermissionsUser: json["users_permissions_user"],
month: json["month"],
publishedAt: json["published_at"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"description": description,
"date":
"${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
"time": time,
"confirmed": confirmed,
"paid": paid,
"price": price,
"workoutplace": workoutplace,
"users_permissions_user": usersPermissionsUser,
"month": month,
"published_at": publishedAt,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
class UserCategory {
UserCategory({
this.id,
this.categoryName,
this.usersPermissionsUser,
this.publishedAt,
this.createdAt,
this.updatedAt,
});
int id;
String categoryName;
int usersPermissionsUser;
DateTime publishedAt;
DateTime createdAt;
DateTime updatedAt;
factory UserCategory.fromJson(Map<String, dynamic> json) => UserCategory(
id: json["id"],
categoryName: json["categoryName"],
usersPermissionsUser: json["users_permissions_user"],
publishedAt: DateTime.parse(json["published_at"]),
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"categoryName": categoryName,
"users_permissions_user": usersPermissionsUser,
"published_at": publishedAt.toIso8601String(),
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
class UserInformation {
UserInformation({
this.id,
this.country,
this.state,
this.address,
this.postalcode,
this.usersPermissionsUser,
this.publishedAt,
this.createdAt,
this.updatedAt,
this.certificate,
});
int id;
String country;
String state;
String address;
String postalcode;
int usersPermissionsUser;
DateTime publishedAt;
DateTime createdAt;
DateTime updatedAt;
Avatar certificate;
factory UserInformation.fromJson(Map<String, dynamic> json) =>
UserInformation(
id: json["id"],
country: json["country"],
state: json["state"],
address: json["address"],
postalcode: json["postalcode"],
usersPermissionsUser: json["users_permissions_user"],
publishedAt: DateTime.parse(json["published_at"]),
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
certificate: Avatar.fromJson(json["certificate"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"country": country,
"state": state,
"address": address,
"postalcode": postalcode,
"users_permissions_user": usersPermissionsUser,
"published_at": publishedAt.toIso8601String(),
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
"certificate": certificate.toJson(),
};
}
class Workoutplace {
Workoutplace({
this.id,
this.title,
this.description,
this.location,
this.price,
this.rating,
this.latitude,
this.longitude,
this.usersPermissionsUser,
this.publishedAt,
this.createdAt,
this.updatedAt,
this.coverimg,
});
int id;
String title;
String description;
String location;
double price;
double rating;
double latitude;
double longitude;
int usersPermissionsUser;
DateTime publishedAt;
DateTime createdAt;
DateTime updatedAt;
Coverimg coverimg;
factory Workoutplace.fromJson(Map<String, dynamic> json) => Workoutplace(
id: json["id"],
title: json["title"],
description: json["description"],
location: json["location"],
price: json["price"].toDouble(),
rating: json["rating"].toDouble(),
latitude: json["latitude"].toDouble(),
longitude: json["longitude"].toDouble(),
usersPermissionsUser: json["users_permissions_user"],
publishedAt: DateTime.parse(json["published_at"]),
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
coverimg: Coverimg.fromJson(json["coverimg"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"description": description,
"location": location,
"price": price,
"rating": rating,
"latitude": latitude,
"longitude": longitude,
"users_permissions_user": usersPermissionsUser,
"published_at": publishedAt.toIso8601String(),
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
"coverimg": coverimg.toJson(),
};
}
class Coverimg {
Coverimg({
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,
});
int id;
String name;
String alternativeText;
String caption;
int width;
int height;
CoverimgFormats formats;
String hash;
String ext;
String mime;
double size;
String url;
dynamic previewUrl;
String provider;
dynamic providerMetadata;
DateTime createdAt;
DateTime updatedAt;
factory Coverimg.fromJson(Map<String, dynamic> json) => Coverimg(
id: json["id"],
name: json["name"],
alternativeText: json["alternativeText"],
caption: json["caption"],
width: json["width"],
height: json["height"],
formats: CoverimgFormats.fromJson(json["formats"]),
hash: json["hash"],
ext: json["ext"],
mime: json["mime"],
size: json["size"].toDouble(),
url: json["url"],
previewUrl: json["previewUrl"],
provider: json["provider"],
providerMetadata: json["provider_metadata"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"alternativeText": alternativeText,
"caption": caption,
"width": width,
"height": height,
"formats": formats.toJson(),
"hash": hash,
"ext": ext,
"mime": mime,
"size": size,
"url": url,
"previewUrl": previewUrl,
"provider": provider,
"provider_metadata": providerMetadata,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
class CoverimgFormats {
CoverimgFormats({
this.small,
this.medium,
this.thumbnail,
});
Thumbnail small;
Thumbnail medium;
Thumbnail thumbnail;
factory CoverimgFormats.fromJson(Map<String, dynamic> json) =>
CoverimgFormats(
small: Thumbnail.fromJson(json["small"]),
medium: Thumbnail.fromJson(json["medium"]),
thumbnail: Thumbnail.fromJson(json["thumbnail"]),
);
Map<String, dynamic> toJson() => {
"small": small.toJson(),
"medium": medium.toJson(),
"thumbnail": thumbnail.toJson(),
};
}

问题是,在您的响应中,您并没有用户列表,您只有一个用户,并且您正试图将其解析为用户列表。因此,请更换

final parsed = jsonDecode(response.body).cast<Map<String, dynamic>>();
return parsed
.map<CurrentUser>((json) => CurrentUser.fromJson(json))
.toList();

对单个用户进行解析:

final parsed = json.decode(resource);
final user = CurrentUser.fromJson(parsed);

最新更新