2
1

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利用時のトラブルシューティング

Posted at

はじめに

Flutterアプリの開発などでよく利用される freezed を利用する際のハマりポイントとその対応方法をまとめています。

1. json_serializableで、キーの指定が正しいはずなのにデコードができない

JSONでの命名とクラスのプロパティ名が一致している場合は基本的にはデコードが成功するはずです。
しかし、build.yamlで field_rename が指定されている場合、これがうまく動かないケースがあります。

targets:
  $default:
    builders:
      # ...
      json_serializable:
        options:
          # ...
          field_rename: snake # none => スネークケース
          # ...
part 'some_response.freezed.dart';
part 'some_response.g.dart';

@freezed
class SomeResponse with _$SomeResponse {
  const factory SomeResponse({
    required int someValue, // キャメルケース
  }) = _SomeResponse;

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

field_rename の方を変更してしまうとプロジェクト全体に影響が及んでしまうため、この場合は対象のプロパティに @JsonKey を指定してキー名を明示することで問題を回避することが可能です。

part 'some_response.freezed.dart';
part 'some_response.g.dart';

@freezed
class SomeResponse with _$SomeResponse {
  const factory SomeResponse({
-   required int someValue,
+   @JsonKey(name: 'someValue') required int someValue,
  }) = _SomeResponse;

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

2. json_serializableで、ルートがリストのJSONをデコードできない

以下のようなルートがArrayのJSONをデコードする場合、

[
  1,
  2
]

これを下記定義のfromJSONにそのまま渡すとデコードがうまくできません。

part 'some_response.freezed.dart';
part 'some_response.g.dart';

@freezed
class SomeResponse with _$SomeResponse {
  const factory SomeResponse({
    @Default(<int>[]) List<int> ids,
  }) = _SomeResponse;

  factory SomeResponse.fromJson(Map<String, dynamic> json) =>
      _$SomeResponseFromJson(json);
}
final jsonMap = json.decode(response.body) as JsonMap;
final response = SomeResponse.fromJson(jsonMap); // 正しくデコードされない

この形式のデータに対応するには、Dart側で定義したプロパティ名に対応したキーをルートに追加した上でデコードを行うと正しく変換することができます。

- final jsonMap = json.decode(response.body) as JsonMap;
+ final jsonMap = json.decode('{"ids": ${response.body}}') as JsonMap;
final response = SomeResponse.fromJson(jsonMap);
2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?