Use AsyncValue.guard rather than try/catch inside your StateNotifier subclasses

When writing your own StateNotifier subclasses, it's quite common to use try/catch blocks to deal with Futures that can fail:

class SignOutButtonController extends StateNotifier<AsyncValue> { SignOutButtonController({required this.authRepository}) : super(const; final AuthRepository authRepository; Future<void> signOut() async { try { state = const AsyncValue.loading(); await authRepository.signOut(); // this future can fail state = const; } catch (e) { state = AsyncValue.error(e); } } }

In such cases, AsyncValue.guard is a convenient alternative that does all the heavy-lifting for us:

Future<void> signOut() async { state = const AsyncValue.loading(); state = await AsyncValue.guard(() => authRepository.signOut()); }

Here's how this method is implemented in the the AsyncValue class:

abstract class AsyncValue<T> { static Future<AsyncValue<T>> guard<T>(Future<T> Function() future) async { try { return future()); } catch (err, stack) { return AsyncValue.error(err, stackTrace: stack); } } }

Learn more here: AsyncValue.guard() method.

Happy coding!

Want More?

Invest in yourself with my high-quality Flutter courses.

The Complete Dart Developer Guide

The Complete Dart Developer Guide

Learn Dart Programming in depth. Includes: basic to advanced topics, exercises, and projects. Fully updated to Dart 2.15.

The Complete Flutter Course Bundle

The Complete Flutter Course Bundle

Learn about State Management, App Architecture, Navigation, Testing, and much more by building a full-stack Flutter eCommerce app on iOS, Android, and web.

Flutter Animations Masterclass - Full Course

Flutter Animations Masterclass - Full Course

Master Flutter animations and build a completely custom habit tracking application.