Home > Software engineering >  Flutter Parse JSON to Model with fromJson Function Always Fails
Flutter Parse JSON to Model with fromJson Function Always Fails

Time:07-31

I am very confused about this problem, parsing JSON to model always fails with the message "null is not subtype of type string in type cast". I've made sure all values are not null. When manually initiating the model with the constructor, it works, but using the fromJson function always fails.

This is my model:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user_model.g.dart';
part 'user_model.freezed.dart';

@freezed
class UserModel with _$UserModel {
  const factory UserModel({
    required String id,
    required String identity,
    required String name,
    required String email,
    required String phone,
    required String role,
    required String? createdAt,
    required String? updatedAt,
    required String? accountVerifiedAt,
    required String jsonWebToken,
  }) = _UserModel;

  const UserModel._();

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

This is how I parse with fromJson, but it always throw exception (null is not a subtype of type string in type cast):

    var user = UserModel.fromJson(object['data']);
    

But it works:

    var user = UserModel(
            id: object['data']['id'],
            identity: object['data']['identity'],
            name: object['data']['name'],
            email: object['data']['email'],
            phone: object['data']['phone'],
            role: object['data']['role'],
            createdAt: object['data']['createdAt'],
            updatedAt: object['data']['updatedAt'],
            accountVerifiedAt: object['data']['accountVerifiedAt'],
            jsonWebToken: object['data']['jsonWebToken'],
          );

CodePudding user response:

Maybe your json has null value that you don't recognized. It happens to me all the times. By the way, I never use freezed_annotation because model is easy to write by hands, plus if there is is a bug, it would be easier to fix. You can do like this:

When back-end responds data:

if (json["error_code"] != 0) { // Back-end responds an error
    // handle error
} else {
    YourModel.fromJson(json);
}

And here is your model:

class YourModel {
    String variable;
    
    YourModel(this.variable = <default value>);
    
    YourModel.fromJson(Map<String, dynamic> json) {
        this.variable = json["blah"]["yolo"] ?? <value if json null>;
    }
}

CodePudding user response:

I just figured out, that it's caused by the generated freezed class, my JSON response use camelCase as keys, but the model generates with snake_case. So basically I convert my response keys from camelCase to snake_case before initiating the object using the fromJson function.

Map<String, dynamic> data = {};
      for (var element in Map<String, dynamic>.from(object['data']).entries) {
        data[StringUtils.camelCaseToLowerUnderscore(element.key)] =
            element.value;
      }
      object['data'] = UserModel.fromJson(data);

If anyone facing the same problem, I hope it can help. And if anyone has a better solution, you guys can post it here too. Thank you.

NB: I use basic_utils: ^4.4.3

  • Related