Closed5

Flutter freezed で JSON をパースする

みなみみなみ

パッケージをインストール

pubspec.yaml に以下追加

dependencies:
 freezed_annotation:
 json_serializable:

dev_dependencies:
 build_runner:
 freezed:

各種パッケージの最新バージョンについては以下をご参照ください

freezed
freezed_annotation
build_runner
json_serializable: こいつがないと fromJson/ToJson を利用することができないです

みなみみなみ

コードを書く

以下のコードを記述する時点ではエラーが出てしまうのですが、build_runner でコード生成をすると消えるので一旦スルーします。

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';

part 'User.freezed.dart';
part 'User.g.dart';


abstract class User implements _$User {
  
  const User._();

  const factory User({
    (name: 'id') int id,
    (name: 'name') String name,
    (name: 'subscribe_plan') Plan plan, // json の subscribe_plan キーを plan にマッピング
  }) = _User;

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

 void fuga() {
   print('メソッドを追加するには implements にする必要がある');
 }

}
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';

part 'Plan.freezed.dart';
part 'Plan.g.dart';


abstract class Plan with _$Plan {

  const factory Plan({
    (name: 'id') int id,
    (name: 'name') String name,
  }) = _Plan;

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

}

ここでのつまづきと解決法

  1. User の中に Plan がネストしている構造の場合は同一ファイルではなく 別ファイル としておかないとコードの自動生成でファイルが生成されませんでした。新規ファイルに分割して解消
  2. 他の方の freezed の記事だと user.freezed.dart と全て小文字になっているが、 クラス名に依存する ため User.freezed.dart と大文字にしたら動作しました(クラス名頭文字小文字がよいのか..?)
  3. json のキーマッピングのやり方がうまくわからなかった... @JsonKey(name: 'id') のようにすればよい
  4. fromJson/ToJson が使えなかった。json_serializablepubspeck.yaml に記述して解決
みなみみなみ

build_runner でコード生成する

  • @freezed のアノテーションが付与されたクラスに対してコードを自動生成してくれます。
  • part 'User.g.dart';
    factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
    記述を行うと fromJson / ToJson が利用できるようになる

以下を実行すると自動的にコードが生成されます

 flutter pub run build_runner build
みなみみなみ

利用する

final jsonString = '''
  {
    "id": 100,
    "name": "minami"
  }
''';

final user = User.fromJson(json.decode(jsonString));
user.fuga();

おしまい!

waddy_uwaddy_u

トピック名を fluttter から flutter へ修正することをご検討ください。

このスクラップは2021/03/03にクローズされました