##概要
こちらの記事を参考に、null安全に対応したjsonファイルの読み込みを実装してみた。
https://qiita.com/kurun_pan/items/455a1e7d6bbd91f0f1f3
##参考記事から変えていないところ
- JSONファイルの中身
- *.g.dartファイルの自動生成
##参考記事から変えたところ
###model/sample.dart
参考記事では
SampleModel({this.id, this.name});
となっていますが、今回は
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クラス書いてあげないと動かないから気をつけてね。
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
また、これがいるのかはわからないけど、一応
flutter:
assets:
- assets/sample.json
も追加しておくといいかも。
こことmain.dartに言える注意点として、ファイルのパスには気をつけようね。
例えば、libファイルの中に、assetsファイルを作って、その中にjsonファイルを作った場合は
lib/assets/~~~~.json
ってしてあげないと、エラーが出て怒られるよ。
##後書きのようなもの
null安全は初学者の敵
上記のコードがミスってて、エラーが出て動かないとかって時は、コメントで教えていただけるとありがたいです。