🧖
【Flutter】RiverpodのAsyncValueのguardメソッドが便利
ととのっていきましょう。AsyncValueについてのリファクタリングの小ネタです。
AsyncValueとは
RiverpodのAsyncValue(公式ドキュメント)というクラス。
これを使うことで、非同期でデータを処理する際、ローディング中か、エラーが発生したかといった状態を簡単に管理できます。
ローディングとエラーのハンドリング漏れや、人によるコーディングのバラツキを減らせるでしょう。
便利なguardメソッド
AsyncValueの公式ドキュメントを改めて見ていたら、guardメソッドなるものをみつけました。
ゴニョゴニョと説明するよりサンプルコードを見ていただくとその便利さが伝わるでしょう。
↓のようなStateNotifierクラスがあり、_fetchDataメソッドで非同期でSampleDataを取得するとします。
class SampleScreenModel extends StateNotifier<AsyncValue<SampleData>> {
SampleScreenModel(this._reader) : super(const AsyncValue.loading()) {
_fetchData();
}
final Reader _reader;
SampleService get _sampleService => _reader(sampleServiceProvider);
Future<void> _fetchData() async {
// ローディングを開始
state = const AsyncValue.loading();
// エラーハンドリングしてデータを取得
try {
final data = await _sampleService.fetchData();
state = AsyncValue.data(data);
} catch (err, stack) {
state = AsyncValue.error(err, stackTrace: stack);
}
}
}
このtry/catchの部分に注目してください。
AsyncValueのguardメソッドを使うと、↓のようになります。
try {
final data = await _sampleService.fetchData();
state = AsyncValue.data(data);
} catch (err, stack) {
state = AsyncValue.error(err, stackTrace: stack);
}
これが、
state = await AsyncValue.guard(() async {
final data = await _sampleService.fetchData();
return data;
});
これになります。
冗長だったエラーハンドリングがguardメソッドによってシンプルになりましたね。
guardメソッドの定義
定義は↓のようになっています。
static Future<AsyncValue<T>> guard<T>(Future<T> Function() future) async {
try {
return AsyncValue.data(await future());
} catch (err, stack) {
return AsyncValue.error(err, stackTrace: stack);
}
}
try/catchをラップしていて、エラーも返してくれていることがわかります。
Discussion
めっちゃ便利ですね!知りませんでした
しかも今回のサンプルコードだと↓まで省略できちゃいますね!!
さらにスッキリしましたね!コメントありがとうございます😄