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.

【Flutter】自由自在にJsonを操るTips集

Posted at

はじめに

FlutterでJsonを扱うならおそらくほとんどの人が使っているjson_serializableですが、
開発で扱う上でこういうのできないんだろうか?と疑問に思い、調べたことを紹介していこうと思います。
ネタが増えたら随時更新していきたいと思います。

インストール

flutter pub add json_annotation
flutter pub add --dev build_runner
flutter pub add --dev json_serializable  

Jsonのキーの名前を変えたい

対象のフィールドに@JsonKey(name: 'xxxx')をつけると、キーを変更できます。

import 'package:json_annotation/json_annotation.dart';

part 'author.g.dart';

@JsonSerializable()
class Author {
  @JsonKey(name: 'author_id')
  final String authorId;
  final String name;

  Author({
    required this.authorId,
    required this.name,
  });

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

  Map<String, dynamic> toJson() => _$AuthorToJson(this);
}
Jsonデータ
  final json = {
    'author_id': "0001",
    'name': "Tanaka Taro",
  };

フィールドすべてを一括で変更したい場合はクラス名の上に、@JsonSerializable(fieldRename: FieldRename.snake)を付けます。

import 'package:json_annotation/json_annotation.dart';

part 'author.g.dart';

@JsonSerializable(fieldRename: FieldRename.snake)
class Author {
  final String authorId;
  final String name;

  Author({
    required this.authorId,
    required this.name,
  });

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

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

nullの場合はJsonに出力しないようにする

nullの場合にJsonに出力したくない場合は@JsonKey(includeIfNull: false)をフィールドに付けます。

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  int id;
  String name;
  @JsonKey(includeIfNull: false)
  String email;

  User({this.id, this.name, this.email});

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

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

  final yamada = User(
    id: "0001",
    name: "Yamada Dai",
    email: "yamada@example.com",
  );
  final tanaka = User(
    id: "0002",
    name: "Tanaka Hiroshi",
  );

 // {id: 0001, name: Yamada Dai, email: yamada@example.com}
  print(yamada.toJson());
 // {id: 0002, name: Tanaka Hiroshi}
  print(tanaka.toJson());

デフォルト値を設定したい

APIレスポンスがnullで返ってきて、アプリケーションではnon nulllで扱いたいときに、@JsonKey(defaultValue: '')で初期値を設定できます。

import 'package:json_annotation/json_annotation.dart';

part 'food.g.dart';

@JsonSerializable()
class Food {
  final String id;
  @JsonKey(defaultValue: '')
  final String name;

  Food({
    required this.id,
    required this.name,
  });
  factory Food.fromJson(Map<String, dynamic> json) => _$FoodFromJson(json);

  Map<String, dynamic> toJson() => _$FoodToJson(this);
}
Jsonサンプル
  // キーがなくても大丈夫
  final json1 = {
    "id": "0001",
  };
  final json2 = {
    "id": "0001",
    "name": null,
  };

List型をJsonから変換時、アイテムがない場合にエラーになる

これも同じくdefaultValueで解決できました。

import 'package:json_annotation/json_annotation.dart';

part 'example.g.dart';

@JsonSerializable()
class Example {
  @JsonKey(defaultValue: [])
  List<String> items;

  Example({required this.items});

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

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

オブジェクトが入れ子になったクラス

複雑なJsonのパースは、専用のメソッドを定義し、@JsonKey(fromJson: _addressFromJson, toJson: _addressToJson)という形で指定することで、パースできるようになります。

import 'package:json_annotation/json_annotation.dart';

@JsonSerializable()
class Person {
  String name;
  int age;
  @JsonKey(fromJson: _addressFromJson, toJson: _addressToJson)
  Address address;

  Person({this.name, this.age, this.address});

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

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

  static Address _addressFromJson(Map<String, dynamic> json) {
    return json == null ? null : Address.fromJson(json);
  }

  static Map<String, dynamic> _addressToJson(Address address) =>
      address?.toJson();
}

@JsonSerializable()
class Address {
  String street;
  String city;

  Address({this.street, this.city});

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

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

Jsonに含めたくない

Jsonに含めたくない場合は@JsonKey(ignore: true)を指定しましょう。

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  int id;
  String name;
  @JsonKey(ignore: true)
  String email;

  User({this.id, this.name, this.email});

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

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

おわりに

JsonKeyには他にも設定できる値があり、カスタマイズしていけそうです。
また、開発していく上で使えそうなものがあれば、記事を更新していきたいと思います!

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?