jankuss / genq

Instant Data Class Generation for Dart
MIT License
133 stars 0 forks source link

Is there anyway to support a partial migration from freezed to genq #27

Closed BWhiteApps closed 4 months ago

BWhiteApps commented 4 months ago

I work in a very big project and would like to eventually switch most of our data models with a few exceptions from freezed to genq.

However I am running into an issue with json serialization where all properties of genq data models must also be genq models. In a very big project this makes migrating difficult because it will be a big lift to migrate every single data model and even then there are models that need to stay in freezed.

Example:

@Genq(json: true)
class SomeGenqClass with _$SomeGenqClass {
  factory SomeGenqClass({
    required String value,
    required SomeFreezedClass someClass,
  }) = _SomeGenqClass;
}

@freezed
class SomeFreezedClass with _$SomeFreezedClass {
  const factory SomeFreezedClass({
    required String value,
  }) = _SomeFreezedClass;

  factory SomeFreezedClass.fromJson(Map<String, dynamic> json) =>
      _$SomeFreezedClassFromJson(json);
}

Gives an error that The function '$SomeFreezedClassFromJson' isn't defined.

Is there a way around this to make the migration easier?

Thanks

jankuss commented 4 months ago

I see - genq makes assumptions how the serialization/deserialization functions for your types are named. This is the $SomeFreezedClassFromJson you see here. Normally genq will generate these functions for you. When using freezed, private fromJson and toJson prefixed with a underscore are generated instead.

I think the least effort would be defining these functions yourself, referencing the function generated by freezed.

@freezed
class SomeFreezedClass with _$SomeFreezedClass {
  const factory SomeFreezedClass({
    required String value,
  }) = _SomeFreezedClass;

  factory SomeFreezedClass.fromJson(Map<String, dynamic> json) =>
      _$SomeFreezedClassFromJson(json);
}

// Here is the magic:
const $SomeFreezedClassFromJson = _$SomeFreezedClassFromJson;

This way, your genq classes will happily find the missing function, but effectively using the one generated by freezed.

Alternatively, you can specify custom toJson/fromJson function with the @JsonKey annotation. But this basically boils down to providing functions which will need to call _$SomeFreezedClassFromJson under the hood. So might as well just use the first solution 😉