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

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

##参考記事から変えていないところ
- JSONファイルの中身
- *.g.dartファイルの自動生成

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

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

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

```dart: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クラス書いてあげないと動かないから気をつけてね。

```dart: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));
  }
}
```
コードを書くとひとまずこんな感じ。
書き換えたところは大体コメントアウトしてあるから読んでみて。<br>
このファイルについてのその他の注意として、Samples型をSwiftでいう、オプショナル型に変更しているので、他の部分で_samples変数を呼び出しているところは、「!」をつけてオプショナルではない型にしてあげる必要があるよ。


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


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

```dart:pubspec.yaml
flutter:
  assets:
    - assets/sample.json
```
も追加しておくといいかも。<br>

こことmain.dartに言える注意点として、ファイルのパスには気をつけようね。<br>
例えば、libファイルの中に、assetsファイルを作って、その中にjsonファイルを作った場合は
lib/assets/~~~~.json
ってしてあげないと、エラーが出て怒られるよ。

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

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