guard method
Transforms a Future that may fail into something that is safe to read.
This is useful to avoid having to do a tedious loading and try/catch
.
Instead of writing:
class MyNotifier extends AsyncNotifier<MyData> {
@override
Future<MyData> build() => Future.value(MyData());
Future<void> sideEffect() async {
state = const AsyncValue.loading().copyWithPrevious(state);
try {
final response = await dio.get('my_api/data');
final data = MyData.fromJson(response);
state = AsyncValue.data(data);
} catch (err, stack) {
state = AsyncValue.error(err, stack);
}
}
}
We can use guard to simplify it:
class MyNotifier extends AsyncNotifier<MyData> {
@override
Future<MyData> build() => Future.value(MyData());
Future<void> sideEffect() async {
// does the loading and try/catch for us like previously
await guard(() async {
final response = await dio.get('my_api/data');
return Data.fromJson(response);
});
}
}
Implementation
Future<void> guard(Future<T> Function() future) async {
state = AsyncValue<T>.loading().copyWithPrevious(state);
try {
state = AsyncValue.data(await future());
} catch (err, stack) {
state = AsyncValue.error(err, stack);
}
}