below is a code snippet from a tutorial I am trying to learn. appreciate if you could tell me why we are not using protection : asyncvalue.guard inside build() but later used when calling the same method?
@riverpod
class WeatherFirst extends _$WeatherFirst {
@override
FutureOr<String> build() {
return _getTemp(Cities.seoul);
}
Future<String> _getTemp(Cities city) async {
await Future.delayed(const Duration(seconds: 1));
switch (city) {
case Cities.seoul:
return '${city.name} - 23';
case Cities.london:
throw 'Fail to fetch the temperature of ${city.name}';
case Cities.bangkok:
throw 'Fail to fetch the temperature of ${city.name}';
case Cities.tokyo:
return '${city.name} - 28';
}
}
Future<void> getTemperature(Cities city) async {
state = const AsyncLoading();
state = await AsyncValue.guard(() => _getTemp(city));
}
}
i tried inserting various error scenarios code works fine
This is the code of AsyncValue.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, stack);
}
}
all it is doing is to wrap your function in a try catch
expression to save you few lines of code. if you are sure that _getTemp(city)
cannot throw an error then you don't need to use guard at all. if you think that _getTemp(Cities.seoul)
can throw an error, then you should return AsyncValue.guard(() => _getTemp(Cities.seoul))
in the build method.
in the example that they provided, the city of seoul do not throw an error like london and bangkok, and thats the reason for not using the guard
Edit
I was incorrect in my answer: you should not put a guard in the build method. this is handled for you as its stated in the source code:
/// If this method throws or returns a future that fails, the error
/// will be caught and an [AsyncError] will be emitted.
/// {@endtemplate}
@visibleForOverriding
FutureOr<State> build();