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

DolDurma picture DolDurma · Jul 15, 2021 · Viewed 7.5k times · Source

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

Answer

TronComputers picture TronComputers · Jul 15, 2021

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