从服务器颤动中获取用户数据
fetch user data from server flutter
我正在按照开发人员 docs 的教程从互联网上获取数据,但我无法解码对 User
对象的响应。
由于我使用 Postman
检查 API 我可以告诉你我的请求已成功收到并且服务器响应我 200
和一个充满数据的正文(name
、id
和 token
) 但是当我尝试在 try-catch
块中调用 fromJson
方法来创建 User
对象时,它失败了,这个错误是印刷:
flutter: Response 200
flutter: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
这是我的用户 class :
class User extends Equatable {
final String token;
final String name;
final String id;
const User({
required this.token,
required this.name,
required this.id,
});
static const User empty = User(token: "token", name: "name", id: "id");
Map<String, dynamic> toMap() {
return <String, String>{
'token': token,
'name': name,
'id': id,
};
}
factory User.fromMap(Map<String, dynamic> json) {
return User(
token: json['token'] ?? "token",
name: json['name'] ?? "name",
id: json['id'] ?? "id",
);
}
String toJson() => json.encode(toMap());
factory User.fromJson(Map<String, dynamic> jsonMap) => User.fromMap(jsonMap);
@override
String toString() {
return token + ' ' + name + ' ' + id + '\n';
}
@override
List<Object?> get props => [token, name, id];
}
UserCredentials
这只是用户名和密码的包装器:
class UserCredentials {
final String name;
final String email;
final String password;
UserCredentials(
{required this.name, required this.email, required this.password});
factory UserCredentials.fromJson(Map<String, dynamic> json) {
return UserCredentials(
name: json['name'] as String,
email: json['email'] as String,
password: json['password'] as String,
);
}
Map<String, String> toJsonRegistration() {
return {
"name": name,
"email": email,
"password": password,
};
}
Map<String, String> toJsonLogin() {
return {
"email": email,
"password": password,
};
}
@override
String toString() {
return name + " " + email + " " + password + '\n';
}
}
这是我用来从服务器获取数据的 user_repository
函数:
Future<User> _login(UserCredentials user) async {
User? userFetched;
//print(user);
http.Response response = await http.post(
Uri.parse("http://link_to_repo"),
body: user.toJsonLogin(),
);
print("Inizio");
print((response.body));
print(jsonDecode(response.body));
print(User.fromJson(jsonDecode(response.body)));
print("fine");
if (response.statusCode == 200) {
print(response.statusCode);
try {
userFetched = User.fromJson(jsonDecode(response.body));
print(userFetched);
} catch (e) {
print(e);
}
print("End");
return userFetched!;
} else {
print("Login Failure from repository");
throw Exception("Email already taken");
}
}
正如您在上面看到的,它能够打印“Response 200”,但无法成功完成 try-catch
块内的操作。
编辑:
这是 response.body
:
{"data" : {"token":"50|IUMNqKgc7Vffmz8elRd0MIZeSyuEgHL418KwQ0Jz","name":"test","id":1}}
和jsonDecode(response.body))
:
{data: {token: 50|IUMNqKgc7Vffmz8elRd0MIZeSyuEgHL418KwQ0Jz, name: test, id: 1}}
解决方案:
这个post有点混乱但要清楚:
Clucera
给了我获取数据和创建 User
对象的确切解决方案,所以我接受了它的答案。
Josip Domazet
的回答帮助我修复了错误,但他没有解决问题,因为我仍然无法创建 User
数据。
jsonDecode(response.body)
会 return 一个 Map
。但是,您的构造函数 User.fromJson
将 String
作为参数。解码一次就足够了,从那时起你就可以使用你已经拥有的 Map
了。所以不需要在 fromJson
中再次调用 jsonDecode
,这应该可以正常工作:
factory User.fromJson(Map<String, dynamic> jsonMap) =>
User.fromMap(jsonMap);
如果我们查看您的异常,它会告诉我们:
flutter: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
您的构造函数需要一个 String
但收到一个映射 (_InternalLinkedHashMap
)。
查看您的代码,您似乎在执行以下操作
User.fromJson(jsonDecode(response.body));
然后您将使用以下工厂创建 User 实例
factory User.fromMap(Map<String, dynamic> json) {
return User(
token: json['token'] ?? "token",
name: json['name'] ?? "name",
id: json['id'] ?? "id",
);
问题是您的 Json 包含在另一个名为“数据”的 json 中,如您的打印响应所示
{data: {token: 50|IUMNqKgc7Vffmz8elRd0MIZeSyuEgHL418KwQ0Jz, name: test, id: 1}}
在这种情况下,您有两种解决方案,要么将键嵌套在构造函数中(不建议您采用这种方法)
factory User.fromMap(Map<String, dynamic> json) {
return User(
token: json['data']['token'] ?? "token",
name: json['data']['name'] ?? "name",
id: json['data']['id'] ?? "id",
);
或者在你解析 json 的地方你可以直接提取 data
json (我建议你这个选项)
User.fromJson(jsonDecode(response.body)['data']);
我正在按照开发人员 docs 的教程从互联网上获取数据,但我无法解码对 User
对象的响应。
由于我使用 Postman
检查 API 我可以告诉你我的请求已成功收到并且服务器响应我 200
和一个充满数据的正文(name
、id
和 token
) 但是当我尝试在 try-catch
块中调用 fromJson
方法来创建 User
对象时,它失败了,这个错误是印刷:
flutter: Response 200
flutter: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
这是我的用户 class :
class User extends Equatable {
final String token;
final String name;
final String id;
const User({
required this.token,
required this.name,
required this.id,
});
static const User empty = User(token: "token", name: "name", id: "id");
Map<String, dynamic> toMap() {
return <String, String>{
'token': token,
'name': name,
'id': id,
};
}
factory User.fromMap(Map<String, dynamic> json) {
return User(
token: json['token'] ?? "token",
name: json['name'] ?? "name",
id: json['id'] ?? "id",
);
}
String toJson() => json.encode(toMap());
factory User.fromJson(Map<String, dynamic> jsonMap) => User.fromMap(jsonMap);
@override
String toString() {
return token + ' ' + name + ' ' + id + '\n';
}
@override
List<Object?> get props => [token, name, id];
}
UserCredentials
这只是用户名和密码的包装器:
class UserCredentials {
final String name;
final String email;
final String password;
UserCredentials(
{required this.name, required this.email, required this.password});
factory UserCredentials.fromJson(Map<String, dynamic> json) {
return UserCredentials(
name: json['name'] as String,
email: json['email'] as String,
password: json['password'] as String,
);
}
Map<String, String> toJsonRegistration() {
return {
"name": name,
"email": email,
"password": password,
};
}
Map<String, String> toJsonLogin() {
return {
"email": email,
"password": password,
};
}
@override
String toString() {
return name + " " + email + " " + password + '\n';
}
}
这是我用来从服务器获取数据的 user_repository
函数:
Future<User> _login(UserCredentials user) async {
User? userFetched;
//print(user);
http.Response response = await http.post(
Uri.parse("http://link_to_repo"),
body: user.toJsonLogin(),
);
print("Inizio");
print((response.body));
print(jsonDecode(response.body));
print(User.fromJson(jsonDecode(response.body)));
print("fine");
if (response.statusCode == 200) {
print(response.statusCode);
try {
userFetched = User.fromJson(jsonDecode(response.body));
print(userFetched);
} catch (e) {
print(e);
}
print("End");
return userFetched!;
} else {
print("Login Failure from repository");
throw Exception("Email already taken");
}
}
正如您在上面看到的,它能够打印“Response 200”,但无法成功完成 try-catch
块内的操作。
编辑:
这是 response.body
:
{"data" : {"token":"50|IUMNqKgc7Vffmz8elRd0MIZeSyuEgHL418KwQ0Jz","name":"test","id":1}}
和jsonDecode(response.body))
:
{data: {token: 50|IUMNqKgc7Vffmz8elRd0MIZeSyuEgHL418KwQ0Jz, name: test, id: 1}}
解决方案:
这个post有点混乱但要清楚:
Clucera
给了我获取数据和创建 User
对象的确切解决方案,所以我接受了它的答案。
Josip Domazet
的回答帮助我修复了错误,但他没有解决问题,因为我仍然无法创建 User
数据。
jsonDecode(response.body)
会 return 一个 Map
。但是,您的构造函数 User.fromJson
将 String
作为参数。解码一次就足够了,从那时起你就可以使用你已经拥有的 Map
了。所以不需要在 fromJson
中再次调用 jsonDecode
,这应该可以正常工作:
factory User.fromJson(Map<String, dynamic> jsonMap) =>
User.fromMap(jsonMap);
如果我们查看您的异常,它会告诉我们:
flutter: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
您的构造函数需要一个 String
但收到一个映射 (_InternalLinkedHashMap
)。
查看您的代码,您似乎在执行以下操作
User.fromJson(jsonDecode(response.body));
然后您将使用以下工厂创建 User 实例
factory User.fromMap(Map<String, dynamic> json) {
return User(
token: json['token'] ?? "token",
name: json['name'] ?? "name",
id: json['id'] ?? "id",
);
问题是您的 Json 包含在另一个名为“数据”的 json 中,如您的打印响应所示
{data: {token: 50|IUMNqKgc7Vffmz8elRd0MIZeSyuEgHL418KwQ0Jz, name: test, id: 1}}
在这种情况下,您有两种解决方案,要么将键嵌套在构造函数中(不建议您采用这种方法)
factory User.fromMap(Map<String, dynamic> json) {
return User(
token: json['data']['token'] ?? "token",
name: json['data']['name'] ?? "name",
id: json['data']['id'] ?? "id",
);
或者在你解析 json 的地方你可以直接提取 data
json (我建议你这个选项)
User.fromJson(jsonDecode(response.body)['data']);