Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter null safety with fromJson

Recently migrating to Flutter null safety feature, I have a lot of Classes that I need to update.

For my models, I use fromJson to deserialize the data from a json object. This forces me to put the late keyword for each field that is non optional.

Is that the right approach?

class ServerSession {
  late String sessionId;
  late String refreshToken;
  late String accessToken;

  ServerSession({required this.sessionId, required this.refreshToken, required this.accessToken});

  ServerSession.fromJson(Map<String, dynamic> json) {
    sessionId = json['session_id'] ?? json['sessionId'];
    refreshToken = json['refresh_token'] ?? json['refreshToken'];
    accessToken = json['access_token'] ?? json['accessToken'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['sessionId'] = this.sessionId;
    data['refreshToken'] = this.refreshToken;
    data['accessToken'] = this.accessToken;
    return data;
  }
}
like image 442
Scaraux Avatar asked Jun 11 '26 01:06

Scaraux


1 Answers

No, it is not. You should be using the initializer list for initializing fields of your class. You can read more about the initializer list in the language tour.

class ServerSession {
  String sessionId;
  String refreshToken;
  String accessToken;

  ServerSession({required this.sessionId, required this.refreshToken, required this.accessToken});

  ServerSession.fromJson(Map<String, dynamic> json) :
    sessionId = json['session_id'] ?? json['sessionId'],
    refreshToken = json['refresh_token'] ?? json['refreshToken'],
    accessToken = json['access_token'] ?? json['accessToken'];

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['sessionId'] = this.sessionId;
    data['refreshToken'] = this.refreshToken;
    data['accessToken'] = this.accessToken;
    return data;
  }
}

I personally would use the "normal" constructor for the object and make fromJson a factory constructor, though either method works.

class ServerSession {
  String sessionId;
  String refreshToken;
  String accessToken;

  ServerSession({required this.sessionId, required this.refreshToken, required this.accessToken});

  factory ServerSession.fromJson(Map<String, dynamic> json) {
    return ServerSession(
      sessionId: json['session_id'] ?? json['sessionId'],
      refreshToken: json['refresh_token'] ?? json['refreshToken'],
      accessToken: json['access_token'] ?? json['accessToken']
    );
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['sessionId'] = this.sessionId;
    data['refreshToken'] = this.refreshToken;
    data['accessToken'] = this.accessToken;
    return data;
  }
}

like image 64
Christopher Moore Avatar answered Jun 12 '26 19:06

Christopher Moore