9

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>);
Alex Hartford
  • 5,110
  • 2
  • 19
  • 36
DolDurma
  • 15,753
  • 51
  • 198
  • 377

3 Answers3

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);
TronComputers
  • 304
  • 2
  • 13
  • i should edit `_$LoginResponseFromJson` in generated freezed class? – DolDurma Jul 15 '21 at 06:19
  • If you are using `json_serialize`, you should use `return LoginResponse.fromJson(response.data);` – TronComputers Jul 15 '21 at 06:21
  • i used `freezed` not `json_serialize` – DolDurma Jul 15 '21 at 06:23
  • It looks same usage for me as `json_serialize` – TronComputers Jul 15 '21 at 06:26
  • is this code correct? ```@freezed class LoginResponse with _$LoginResponse { const factory LoginResponse({ required String message, required int statusCode, }) = _LoginResponse; factory LoginResponse.fromJson(Map json) => _$LoginResponseFromJson(json); }``` could you help me how can i resolve that please? – DolDurma Jul 15 '21 at 06:29
  • 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. – TronComputers Jul 15 '21 at 06:33
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234890/discussion-between-doldurma-and-troncomputers). – DolDurma Jul 15 '21 at 06:37
  • 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'. ` – DolDurma Jul 15 '21 at 06:43
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>);}
Ayush Rawat
  • 152
  • 7
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));

Emad Adly
  • 131
  • 5
  • i get this error: `type '_InternalLinkedHashMap' is not a subtype of type 'String'` – DolDurma Jul 15 '21 at 06:27
  • 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 parsed = json.decode(response.data); print(parsed);' – Emad Adly Jul 15 '21 at 06:52