Json_serializable.dart: how to set default value to nested JSON objects?

Created on 18 Jan 2021  路  6Comments  路  Source: google/json_serializable.dart

I am trying to figure out how to properly set the default value to nested JSON fields.
I am trying to avoid null values for missing fields in the response json.

I have tried this:

@JsonSerializable(explicitToJson: true)
class LoginResponse {
  @JsonKey(defaultValue: false)
  bool success;
  @JsonKey(defaultValue: new UserDataModel())
  UserDataModel seeker;
  @JsonKey(defaultValue: 0)
  int timestamp;

but the syntax is not correct as the value must be a constant.

I have also tried this:

@JsonSerializable(explicitToJson: true)
class LoginResponse {
  @JsonKey(defaultValue: false)
  bool success;
  @JsonKey(disallowNullValue: true, defaultValue: {"seeker": {"id": "", "name": "", "email": "",}})
  UserDataModel seeker;
  @JsonKey(defaultValue: 0)
  int timestamp;

Generated code:

LoginResponse _$LoginResponseFromJson(Map<String, dynamic> json) { $checkKeys(json, disallowNullValues: const ['seeker']); return LoginResponse( success: json['success'] as bool ?? false, seeker: json['seeker'] == null ? null : UserDataModel.fromJson(json['seeker'] as Map<String, dynamic>) ?? { 'seeker': { 'id': '', 'name': '', 'email': '' } }, timestamp: json['timestamp'] as int ?? 0, ); }

but when the response does not include the field, it is still set to null.
Any help would be appreciated.

Most helpful comment

This is in demand for us too. We should be able to use an own object as defaultValue, like @JsonKey(defaultValue: PriceData()), so this:

    basePrice: json['basePrice'] == null
        ? null
        : PriceData.fromJson(json['basePrice'] as Map<String, dynamic>),

should be changed into this:

    basePrice: json['basePrice'] == null
        ? PriceData()
        : PriceData.fromJson(json['basePrice'] as Map<String, dynamic>),

All 6 comments

Here is out of jail card :

UserDataModel _$UserDataModel(Map<String, dynamic> json) {
  if (json != null) {
    return UserDataModel(
      personId: json['userDataModelId'] as int ?? 0,
    );
  } else {
    return (UserDataModel(
      personId: 0,
   ));
  }
}

This is in demand for us too. We should be able to use an own object as defaultValue, like @JsonKey(defaultValue: PriceData()), so this:

    basePrice: json['basePrice'] == null
        ? null
        : PriceData.fromJson(json['basePrice'] as Map<String, dynamic>),

should be changed into this:

    basePrice: json['basePrice'] == null
        ? PriceData()
        : PriceData.fromJson(json['basePrice'] as Map<String, dynamic>),

This gets a bit complicated.

We _could_ add in logic to support the encoded version of a type in defaultsTo (or add another configuration option). Then we'd pass that in as PriceData.fromJson(json['price] as Map<String, dynamic>? ?? const {...}

But that gets super complicated!

I'm going to suggest that folks just create a fromJson converter here. Take in Map<String, dynamic>? and handle returning whatever you like in the null case.

I don't think the added complexity here is worth it!

https://github.com/google/json_serializable.dart/issues/849 is the issue to track documening this better!

Hi @kevmoo,
Thanks for replying on this,
Could you please give an example of :

just create a fromJson converter here

Any update on this, have you found any workaround?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hatjs880328s picture hatjs880328s  路  3Comments

FaisalAbid picture FaisalAbid  路  5Comments

fengqiangboy picture fengqiangboy  路  5Comments

broofus picture broofus  路  6Comments

alexantenna picture alexantenna  路  3Comments