【问题标题】:Type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast error类型转换错误中的“Null”类型不是“Map<String, dynamic>”类型的子类型
【发布时间】:2021-07-15 06:09:03
【问题描述】:

在我的示例项目中,我使用riverpod 包和freezed 实现了项目。在下面的代码中,我可以成功地从服务器获取数据,但是当我尝试使用model.fromJson 时,我得到了这个错误:

getting type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast

服务器响应数据:

{
  "message": "test message",
  "statusCode": 1
}

login 模型转换服务器响应的数据和结构:

LoginModel loginModelFromJson(Map<String, dynamic> str) => LoginModel.fromJson(str);

String loginModelToJson(LoginModel data) => json.encode(data.toJson());

@freezed
class LoginModel with _$LoginModel {
  const factory LoginModel({
    required LoginResponse response,
  }) = _LoginModel;

  factory LoginModel.fromJson(Map<String, dynamic> json) => _$LoginModelFromJson(json);
}

@freezed
class LoginResponse with _$LoginResponse {
  const factory LoginResponse({
    required String message,
    required int statusCode,
  }) = _LoginResponse;

  factory LoginResponse.fromJson(Map<String, dynamic> json) => _$LoginResponseFromJson(json);
}

在LoginResponse 类中,我定义了两个参数message 和statusCode,它们由服务器返回。当我尝试使用此请求时,例如:

Future<LoginModel> getResponse(String mobileNumber) async {
  const endPoint = 'http://192.168.1.11/api';
  try {
    final response = await _read(dioProvider).get('${endPoint}/register');

    /*GETTING ERROR HERE*/
    return loginModelFromJson(response.data as Map<String, dynamic>);
  } on DioError catch (e) {
    ///
  }
}

我在getResponse方法的这一行得到了前面提到的错误:

return loginModelFromJson(response.data as Map<String, dynamic>);

【问题讨论】:

    标签: flutter dart riverpod flutter-freezed


    【解决方案1】:

    您的响应 JSON 为空或包含不正确的内容。这就是 Dart 无法将其转换为 Map&lt;String, dynamic&gt; 的原因。您必须手动完成

    LoginResponse _$LoginResponseFromJson(Map<String, dynamic> json) {
      return LoginResponse(
        message: json['message'] as String,
        statusCode: json['statusCode'] as int,
      );
    }
    

    改变

    return loginModelFromJson(response.data as Map<String, dynamic>);
    

    到

    return LoginResponse.fromJson(response.data);
    

    【讨论】:

    • 我应该在生成的冻结类中编辑_$LoginResponseFromJson?
    • 如果你使用json_serialize,你应该使用return LoginResponse.fromJson(response.data);
    • 我用的是freezed而不是json_serialize
    • 它看起来和json_serialize的用法一样
    • 这段代码正确吗? @freezed class LoginResponse with _$LoginResponse { const factory LoginResponse({ required String message, required int statusCode, }) = _LoginResponse; factory LoginResponse.fromJson(Map&lt;String, dynamic&gt; json) =&gt; _$LoginResponseFromJson(json); }你能帮我解决这个问题吗?
    【解决方案2】:

    你得到一个空响应。试试这段代码,看看错误是否仍然存在。

    if(response.data!=null)
    {return loginModelFromJson(response.data as Map<String, dynamic>);}
    

    【讨论】:

      【解决方案3】:

      使用json.decode()从json字符串中获取Map对象。

      将return loginModelFromJson(response.data as Map&lt;String, dynamic&gt;); 行更新为return loginModelFromJson(json.decode(response.data));

      【讨论】:

      • 我收到此错误:type '_InternalLinkedHashMap&lt;String, dynamic&gt;' is not a subtype of type 'String'
      • 你能把这 3 行放在 return 语句之前并检查控制台输出吗?需要查看response.data 'print(response.data); 的确切值Map 已解析 = json.decode(response.data);打印(解析);'
      猜你喜欢
      • 1970-01-01
      • 2021-08-23
      • 2020-12-21
      • 1970-01-01
      • 2020-03-03
      • 2022-08-10
      • 2021-04-03
      • 2022-08-12
      • 2021-04-13
      相关资源
      最近更新 更多