Heikkisorsa
Heikkisorsa

Reputation: 905

Null-safety for fromJson like methods

I want to define a simple class model UserResponse in Flutter 2.0.5 and build a fromJson method attached to this class to create an instance easily after receiving the data from the backend in json format.

class UserResponse {
  String name;

  UserResponse ({
    required this.name,
  });

  UserResponse.fromJson(Map<String, dynamic> json) {
    name= json['name'].toString();
  }
}

The dart compiler however throws an error here: dart(not_initialized_non_nullable_instance_field)

Furthermore: Non-nullable instance field 'name' must be initialized. Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.

If I know that I will only call the fromJson method if I have all the required data, how should I create the new Instance in this method? I don't want to change the name field in the class to late.

Upvotes: 1

Views: 2263

Answers (3)

Vu Thanh
Vu Thanh

Reputation: 398

For null-safety. You need to be check null right way. And front-end need handle server don't return this key, we need mock data and sure app can't crash.

class UserResponse {
  UserResponse({
    this.name,
  });

  final String? name;

  factory UserResponse.fromRawJson(String str) =>
      UserResponse.fromJson(json.decode(str));

  String toRawJson() => json.encode(toJson());

  factory UserResponse.fromJson(Map<String, dynamic> json) => UserResponse(
        name: json["name"] == null ? null : json["name"].toString(),
      );

  Map<String, dynamic> toJson() => {
        "name": name == null ? null : name,
      };
}

Upvotes: 1

Heikkisorsa
Heikkisorsa

Reputation: 905

According to this very similar question there are mainly to ways:

  1. Use an initializer list for the method

  2. Use a factory method

Thus,

UserResponse.fromJson(Map<String, dynamic> json) :
        name= json['name'] as String;

or

factory UserResponse.fromJson(Map<String, dynamic> json) {
        return UserResponse(
            name: json['name'] as String,
        );
    }

Upvotes: 0

ambiguous58
ambiguous58

Reputation: 1411

Use a factory constructor.

class UserResponse {
  final String name;

  UserResponse({
    required this.name,
  });

  factory UserResponse.fromJson(Map<String, dynamic> json) {
    return UserResponse(name: json['name'].toString());
  }
}

Upvotes: 2

Related Questions