I have a class which I am trying to use with Freezed, Json Serializable, and Hive. After running dart run build_runner build
and generating the necessary classes, my compiler gives me the following error:
: Error: Can't use '_$FooBarFromJson' because it is declared more than once.
and
: Error: '_$FooBarFromJson' is already declared in this scope.
part 'foobar.freezed.dart';
part 'foobar.g.dart';
@freezed
@JsonSerializable(explicitToJson: true)
@HiveType(typeId: 0)
class FooBar extends HiveObject with _$FooBar {
factory FooBar({
@HiveField(0) required int baz
}) = _FooBar;
factory FooBar.fromJson(Map<String, dynamic> json) =>
_$FooBarFromJson(json);
}
}
After looking through the generated classes, my foobar.g.dart
file contains the following methods:
FooBar _$FooBarFromJson(Map<String, dynamic> json) => FooBar(
baz: json['baz'] as int,
);
Map<String, dynamic> _$FooBarToJson(FooBar instance) =>
<String, dynamic>{
'baz': instance.baz,
};
_$_FooBar _$$_FooBarFromJson(Map<String, dynamic> json) =>
_$_FooBar(
baz: json['baz'] as int,
);
Map<String, dynamic> _$$_FooBarToJson(_$_FooBar instance) =>
<String, dynamic>{
'baz': instance.baz,
};
And my foobar.freezed.dart
contains this method:
FooBar _$FooBarFromJson(Map<String, dynamic> json) {
return _FooBar.fromJson(json);
}
I've noticed that other files that get converted only have the methods with the _$$_
prefix in foobar.g.dart
, whereas _$FooBarFromJson
is being created in both foobar.freezed.dart
and foobar.g.dart
, which is the cause of the errors. What am I missing here?
CodePudding user response:
According to the following this comment in a freezed issue and as shown in the package readme example, you need to place the @JsonSerializable(explicitToJson: true)
inside the class in the following manner:
part 'foobar.freezed.dart';
part 'foobar.g.dart';
@freezed
@HiveType(typeId: 0)
class FooBar extends HiveObject with _$FooBar {
@JsonSerializable(explicitToJson: true) // <~~~ here
factory FooBar({
@HiveField(0) required int baz
}) = _FooBar;
factory FooBar.fromJson(Map<String, dynamic> json) =>
_$FooBarFromJson(json);
}
}
You will notice this will give you the following warning:
The annotation 'JsonSerializable' can only be used on classes
This is a known issue/limitation and the maintainer recommends disabling that specific warning as discussed here.
I believe an alternative approach is to create build.yaml
and specify explicitToJson
in there but I don't have much knowledge there.