0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

freezedクラスにListオブジェクトを持たせてつまずいた件

Posted at

プロパティにListオブジェクトを持たせてFirestoreに保存したかったのですが、JSON変換エラーになってしまい、軽くつまずいたので共有します。

最初のコード

hoge.dart
@freezed
class ParentHoge with _$ParentHoge {
  const factory ParentHoge({
    required List<ChildHoge> childHoges,
  }) = _ParentHoge;
  const ParentHoge._();

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

エラー内容

Unhandled Exception: Invalid argument: Instance of '_$_ChildHoge'

どうやらPOSTしようとしたけどオブジェクトの部分が、うまくJSONに変換できなかったもよう。
freezedで自動生成されたファイルを見てみると👇のようになってました。

hoge.g.dart
Map<String, dynamic> _$$_ParentHogeToJson(_$_ParentHoge instance) => 
  <String, dynamic>{
      'childHoges': instance.childHoges
  };

解決策

どうやらネストしたクラスがシリアライズされるためには@JsonSerializable(JSONがネストしていることを示すアノテーション)にexplicitToJson: trueを設定する必要があるらしいです。

json_serializable.dartファイルのexplicitToJsonの説明に下記のように記載がありました。

If true, generated toJson methods will explicitly call toJson on nested objects.
trueの場合、生成された toJson メソッドは、ネストしたオブジェクトに対して明示的に toJson を呼び出します。

Afterコード

JsonSerializableで指定してあげたらFirestoreに保存ができるようになりました!

@freezed
class ParentHoge with _$ParentHoge {
  @JsonSerializable(explicitToJson: true)  // <- これを追加
  const factory ParentHoge({
    required List<ChildHoge> childHoges,
  }) = _ParentHoge;
  const ParentHoge._();

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

freezedで自動生成されたファイルを見てみると、mapでそれぞれJSONに変換してからList化してくれてますね!

hoge.g.dart
Map<String, dynamic> _$$_ParentHogeToJson(_$_ParentHoge instance) => 
  <String, dynamic>{
      'childHoges': instance.childHoges.map((e) => e.toJson()).toList()
  };

おまけ

デフォルトtrueでよくない?って思ったけど過去に同じ疑問を持った方がissueをあげてました。

どうやらあまり使用されていない反面、コードに多くの複雑さを与えてたため、デフォルトtrueにはしなかったみたいですね🤔

その他参考URL

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?