How to convert an object to json using freezed in flutter

2.5k Views Asked by At

I have written a freezed data class.

@freezed
class GithubRepoDTO with _$GithubRepoDTO {
  const GithubRepoDTO._();
  const factory GithubRepoDTO({
    required UserDTO owner,
    required String name,
    @JsonKey(fromJson: _fromJson) required String description,
    @JsonKey(name: 'stargazers_count') required int stargazersCount,
  }) = _GithubRepoDTO;

  factory GithubRepoDTO.fromJson(Map<String, dynamic> json) =>
      _$GithubRepoDTOFromJson(json);

}

So I can write fromJson with freezed. But when I tried to have a toJson. I can't write it. So I used jsonSerializable, so now I can have a toJson, this is the updated code.

@freezed
@JsonSerializable()
class GithubRepoDTO with _$GithubRepoDTO {
  const GithubRepoDTO._();
  const factory GithubRepoDTO({
    required UserDTO owner,
    required String name,
    @JsonKey(fromJson: _fromJson) required String description,
    @JsonKey(name: 'stargazers_count') required int stargazersCount,
  }) = _GithubRepoDTO;

  factory GithubRepoDTO.toGithubRepoDTO(Map<String, dynamic> json) =>
      _$GithubRepoDTOFromJson(json);

  Map<String, dynamic> toJson() => _$GithubRepoDTOToJson(this);


}

Now I can have toJson, but in this way, the problem is now I need to name fromJson any other name , I cant use fromJson now, when i used it shows duplicated reference found on auto generated code. So here i renamed fromJson to toGithubRepoDTO.

  1. Why can't I name fromJson same but for toJson i can name it same?
  2. Is this approach correct?
  3. Can i do this without json_serializable?
1

There are 1 best solutions below

3
cem256 On

According to freezed documentation you need to put @JsonSerializable(explicitToJson: true) inside the class since you are using nested freezed objects (e.g. UserDTO). Also, you need to implement your custom json converter for the _fromJson method.

class YourJsonConverter extends JsonConverter<String?, String?> {
  const YourJsonConverter();
  // TODO implement from/toJson
}

@freezed
class GithubRepoDTO with _$GithubRepoDTO {
  const GithubRepoDTO._();
  @JsonSerializable(explicitToJson: true)
  const factory GithubRepoDTO({
    required UserDTO owner,
    required String name,
    @YourJsonConverter() required String description,
    @JsonKey(name: 'stargazers_count') required int stargazersCount,
  }) = _GithubRepoDTO;

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

Putting the @JsonSerializable() annotation inside the class will give you invalid annotation target warning. However, this is a known issue about the package and you can disable it as its mentioned here

Now you can name it as fromJson since there are no duplicate fromJson methods in the generated code.