tryCatch<T> static method
Future<AsyncValue<T> >
tryCatch<T>(
- Future<
T> future(), { - WritableBeacon<
AsyncValue< ? beacon,T> > - T? optimisticResult,
Executes the future provided and returns AsyncData with the result if successful or AsyncError if an exception is thrown.
Supply an optional WritableBeacon that will be set throughout the various states.
Supply an optional optimisticResult that will be set while loadin, instead of AsyncLoading.
/// Example:
Future<String> fetchUserData() {
// Imagine this is a network request that might throw an error
return Future.delayed(Duration(seconds: 1), () => 'User data');
}
beacon.value = AsyncLoading();
beacon.value = await AsyncValue.tryCatch(fetchUserData);
You can also pass the beacon as a parameter.
loading,data and error states,
as well as the last successful data will be set automatically.
await AsyncValue.tryCatch(fetchUserData, beacon: beacon);
Without tryCatch, handling the potential error requires more
boilerplate code:
beacon.value = AsyncLoading();
try {
beacon.value = AsyncData(await fetchUserData());
} catch (err,stacktrace) {
beacon.value = AsyncError(err, stacktrace);
}
Implementation
static Future<AsyncValue<T>> tryCatch<T>(
Future<T> Function() future, {
WritableBeacon<AsyncValue<T>>? beacon,
T? optimisticResult,
}) async {
T? oldData;
if (beacon != null) {
oldData = beacon.peek().lastData;
if (optimisticResult != null) {
beacon.set(AsyncData(optimisticResult));
} else {
beacon.set(AsyncLoading()..setLastData(oldData));
}
}
try {
final data = AsyncData(await future());
beacon?.set(data);
return data;
} catch (e, s) {
final error = AsyncError<T>(e, s)..setLastData(oldData);
beacon?.set(error);
return error;
}
}