How do I make a Freezed object take a generic type? I want to do this:
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:vepo/src/entity_types/option_entity.dart';
part 'vegan_item_tag.freezed.dart';
part 'vegan_item_tag.g.dart';
@freezed
abstract class VeganItemTag<T>
with _$VeganItemTag<T>
implements OptionEntity<T> {
const factory VeganItemTag({int? iconCodePoint, T? id, String? name}) =
_VeganItemTag;
const VeganItemTag._();
factory VeganItemTag.fromJson(Map<String, dynamic> json) =>
_$VeganItemTagFromJson(json);
}
I've tried using @With.fromString('AdministrativeArea<House>')
from the docs but can't apply it correctly to this class.
One of the errors:
lib/src/common/enums/tags/common/vegan_item_tag.freezed.dart:142:32: Error: Too few positional arguments: 2 required, 1 given.
$$_VeganItemTagFromJson(json);
Think I might be on the right track with this, but it no longer generates a vegan_item_tag.g.dart
file:
@freezed
abstract class VeganItemTag<T>
with _$VeganItemTag<T>
implements OptionEntity<T> {
const factory VeganItemTag(
{required int iconCodePoint,
required T id,
required String name}) = _VeganItemTag;
const VeganItemTag._();
factory VeganItemTag.fromJson(
Map<String, Object?> json,
T Function(Object?) fromJsonT,
) => VeganItemTag(
iconCodePoint: json['iconCodePoint'] as int,
id: fromJsonT(json['id']),
name: json['name'] as String,
);
}
There are several solutions to this problem. But in all of them you need to explicitly convert your classes to a generic type Firebase can handle such as
String
orMap<dynamic, String>
.The 3 ways to implement such behavior are:
FromJson ToJson
This is messier to maintain than
JsonConverters
on complex scenarios so I would discard this option for your solution.JsonConverters
It works for automatizing conversions of specific classes or abstract classes through inheritance, but from generic types with different data to store it may not be what you require. If you are always saving the same values from the generic type
T
you may try to use this solution through implemented abstract classes.GenericArgumentFactories
This is what you are actually asking about. Working with genericArgumentFactories on json_serializable and Freezed is not easy and I found a bug on Freezed package meanwhile.
But I managed to get this code working which is the actual solution .
This adds the converters on the
toJson
andfromJson
methods to be used depending on the generic type.NOTE. These methods can't be expressions for some bug as it doesn't compile but it works with block bodies. Freezed does not oficcially support it so you may consider creating this class without Freezed package.
This is a example with an encapsulated class of a
String
and a test class to see how it works:And the test which works fine