1

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.

Heikkisorsa
  • 740
  • 9
  • 31

3 Answers3

2

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());
  }
}
ambiguous58
  • 1,241
  • 1
  • 9
  • 18
1

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,
      };
}
Vu Thanh
  • 319
  • 1
  • 14
  • The `toJson` and `fromJson` method has some redundancy in it and the `name` variable in your model is not null-safe. This is not a response that solves the issue. Just go with my accepted answer as it fulfills the question 100%. – Heikkisorsa Sep 20 '21 at 15:34
  • if JSON return from server don't have key `name` your app will be crash (expect String but got Null ..... ). My code fix this issue. – Vu Thanh Sep 21 '21 at 14:11
  • 1
    First, this was not requested. Second, no it does not. `name: json["name"] == null ? null : json["name"].toString(),` is for multiple reasons useless. You don't need the `toString()` method on a String. You don't need a null check for a nullable type as you declare `final String? name;` above and anyway you are just asigning `null` if it is `null`, so completely redundant. – Heikkisorsa Sep 22 '21 at 08:09
  • Oh. I forgot `final String? name;` set name `null` for default. Thank you! nice. – Vu Thanh Sep 22 '21 at 08:54
0

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,
        );
    }
Heikkisorsa
  • 740
  • 9
  • 31