google / json_serializable.dart

Generates utilities to aid in serializing to/from JSON.
https://pub.dev/packages/json_serializable
BSD 3-Clause "New" or "Revised" License
1.54k stars 393 forks source link

Generate null checking code if the property is nullable when using `@JsonKey(fromJson)` #1356

Open hurelhuyag opened 10 months ago

hurelhuyag commented 10 months ago

Let's consider this example.

@JsonSerializable()
class Product {

  @JsonKey(fromJson: ProductType.byId)
  final ProductType? type;

  const Product({required this.type});

}

Currently when I run build_runner. The generated code will look like this.

Product _$PFromJson(Map<String, dynamic> json) => Product(
      type: ProductType.byId(json['type'] as String),
    );

I'm suggesting if the property is nullable, then the generator can set a null value for the type property.

Product _$PFromJson(Map<String, dynamic> json) => Product(
      type: json['type'] == null ? null : ProductType.byId(json['type'] as String),
    );
ss23 commented 6 months ago

I am not sure if this counts as a new bug, or just part of this one, but when attempting to work around this issue, the annotation @JsonKey(fromJson: foo, defaultValue: null) results in the generated code not having a null default either, so there is no quick work around for this issue that I can see.

mateusfccp commented 4 months ago

Yes, I'm surprised this is not the default behavior.

We have some JSON objects that we have to parse in which we receive date fields as millisecondsSinceEpoch.

I can't to:

@JsonKey(fromJson: DateTime.fromMillisecondsSinceEpoch)
final DateTime? myDate;

Because DateTime.fromMillisecondsSinceEpoch returns a DateTime instead of a DateTime?. Because of this, I have to use a "helper" function:

@JsonKey(fromJson: parseDateTimeFromMilliseconds)
final DateTime? myDate;

// ...

DateTime? parseDateTimeFromMilliseconds(int? milliseconds) {
  if (milliseconds == null) {
    return null;
  } else {
    return DateTime.fromMillisecondsSinceEpoch(millisecond);
  }
}

This seems so unnecessary.