2
2

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.

JSONファイルの読み込み(null安全対応)

Last updated at Posted at 2021-09-11

##概要
こちらの記事を参考に、null安全に対応したjsonファイルの読み込みを実装してみた。
https://qiita.com/kurun_pan/items/455a1e7d6bbd91f0f1f3

##参考記事から変えていないところ

  • JSONファイルの中身
  • *.g.dartファイルの自動生成

##参考記事から変えたところ
###model/sample.dart
参考記事では

model/sample.dart
SampleModel({this.id, this.name});

となっていますが、今回は

model/sample.dart
SampleModel({required this.id, required this.name});

としてあげてください。

requiredをつけてあげると、絶対に引数を入れてねっていう書き方になります。

null安全は、引数などに意図しないnullが入る可能性がある場合、コンパイルエラーを起こすことで絶対に値が入ってて欲しいところにnullが入らないようにする仕組みになります。

したがって、requiredをつけることで基本的に意図しないnullが入らないことになるので、変数宣言の際、初期値を代入する必要がありません。
(2023/7/3編集)頂いたコメントで教えていただきましたが、requiredを使ってあげることでnull安全に対応できるというわけではないみたいです。
上のコードはクラスのコンストラクタにあたり、中括弧({}<-これ)で囲まれている変数は名前付き引数というものにすることができ、インスタンスを生成する際、本来は値の指定は任意になります。
しかし、requiredが付けられた名前付き引数は、呼び出す際に値を必ず指定しなければならない、という意味になるみたいです。以下、参考にしてね。
https://dart.dev/codelabs/dart-cheatsheet#named-parameters

###JSONファイルをパースしてモデルに格納
参考記事だと、Stateクラスしか書かれてないけど、ちゃんとStatefulクラス書いてあげないと動かないから気をつけてね。

main.dart
class MyHomePage extends StatefulWidget{
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> { // この行から上でエラー出てたら、スペルミスとかだから、後で教えてください
  Samples? _samples; // nullかもしれないよ〜って型にしてあげる

  @override
  void initState() {
    super.initState();
    _jsonFileLoad().then((value) {
      setState(() {
        _samples = value;
        assert(_samples!.list.isNotEmpty);
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("aaa"), // 今回は引数もらってきてないから適当に書いとく
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: _samples == null // 補足:ここは三項演算子を使っているよ
              ? <Widget>[CircularProgressIndicator()] // _samplesがnullの時(ファイルが読み込みきれてない時)画面に読み込みのぐるぐるを表示させる
              : <Widget>[
            for (int i = 0; i < _samples!.list.length; i++)
              Text(
                'ID: ${_samples!.list[i].id}, NAME: ${_samples!.list[i].name}',
              ),
          ],
        ),
      ),
    );
  }

  Future<dynamic> _jsonFileLoad() async {
    String path = 'assets/sample.json';
    String jsonString;

    try {
      jsonString = await rootBundle.loadString(path);
    } on FlutterError {
      print('Failed to open $path');
      rethrow; // 参考記事のコードだと、ファイルが読み込めなかったとき毎回アプリが落とされるから、今回はエラーが出ても、アプリは開き続けるようにしてる
    }

    return Samples.fromJson(jsonDecode(jsonString));
  }
}

コードを書くとひとまずこんな感じ。
書き換えたところは大体コメントアウトしてあるから読んでみて。

このファイルについてのその他の注意として、Samples型をSwiftでいう、オプショナル型に変更しているので、他の部分で_samples変数を呼び出しているところは、「!」をつけてオプショナルではない型にしてあげる必要があるよ。

###pubspec.yaml
dependenciesとdev_dependenciesは参考記事と同様のものを追加してください。
・(9/12追記)なお、バージョンについてはこちらを参考にしてください。
https://minpro.net/conflicts-between-the-latest-versions-of-json_serializable-and-json_annotation

また、これがいるのかはわからないけど、一応

pubspec.yaml
flutter:
  assets:
    - assets/sample.json

も追加しておくといいかも。

こことmain.dartに言える注意点として、ファイルのパスには気をつけようね。

例えば、libファイルの中に、assetsファイルを作って、その中にjsonファイルを作った場合は
lib/assets/~~~~.json
ってしてあげないと、エラーが出て怒られるよ。

##後書きのようなもの
null安全は初学者の敵

上記のコードがミスってて、エラーが出て動かないとかって時は、コメントで教えていただけるとありがたいです。

2
2
1

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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?