Type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast error
Asked Answered
S

4

10

In my sample project I implemented project with riverpod package and freezed. In the code below, I can get data from the server successfully, but when I try to use model.fromJson I get this error:

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

Server response data:

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

login model to cast data and structure of server response:

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);
}

Here on LoginResponse class I defined two parameters message and statusCode which are returned by server. When I try to use this request such as:

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) {
    ///
  }
}

I get the previously mentioned error on this line of getResponse method:

return loginModelFromJson(response.data as Map<String, dynamic>);
Shiri answered 15/7, 2021 at 6:9 Comment(0)
O
6

Your response JSON is empty or contains incorrect content. That is why Dart is not able to cast it as Map<String, dynamic>. You have to do it manually

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

CHANGE

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

TO

return LoginResponse.fromJson(response.data);
Opiate answered 15/7, 2021 at 6:14 Comment(8)
i should edit _$LoginResponseFromJson in generated freezed class?Shiri
If you are using json_serialize, you should use return LoginResponse.fromJson(response.data);Opiate
i used freezed not json_serializeShiri
It looks same usage for me as json_serializeOpiate
is this code correct? @freezed class LoginResponse with _$LoginResponse { const factory LoginResponse({ required String message, required int statusCode, }) = _LoginResponse; factory LoginResponse.fromJson(Map<String, dynamic> json) => _$LoginResponseFromJson(json); } could you help me how can i resolve that please?Shiri
I am not using freezed. If this code is autogenerated it is probably correct. Your usage of it is not. In Dart/Flutter you can't just cast directy to specific type. Dart is not that smart in most cases. See the edit of my answer.Opiate
Let us continue this discussion in chat.Shiri
for your updated code i get this error: A value of type 'LoginResponse' can't be returned from the method 'getResponse' because it has a return type of 'Future<LoginModel>'. Shiri
P
3

you are getting a null response. Try this code and see if the error still there or not.

if(response.data!=null)
{return loginModelFromJson(response.data as Map<String, dynamic>);}
Palmer answered 15/7, 2021 at 6:18 Comment(0)
P
0

Use the json.decode() to obtain the Map<String, dynamic> object from json string.

Update the line return loginModelFromJson(response.data as Map<String, dynamic>); to return loginModelFromJson(json.decode(response.data));

Patentor answered 15/7, 2021 at 6:23 Comment(2)
i get this error: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'Shiri
Could you put these 3 lines before the return statement and check the console output? Need to see the exact value of the response.data 'print(response.data); Map<String, dynamic> parsed = json.decode(response.data); print(parsed);'Patentor
G
0

In my case, the solution that helped me is null-safety!

This error can be handled by Dart null-safety. Using all variables in the Model class with null-safety is a good practice.

Example for you can:

CHANGE below

required String message,
required int statusCode,

WITH

required String? message,
required int? statusCode,

And while using the variable you can use like: Text(message ?? ''),

Georama answered 30/1, 2024 at 11:48 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.