I want to initialise a my StateNotifier asynchronously.
I think I can do it, I just want to check what I am doing is best practice.
This is a bit pseudo but hopefully makes sense...
final signInProvider = StateNotifierProvider<ExampleNotifier, SignInState>((ref) {
return ExampleNotifier();
});
class ExampleNotifier extends StateNotifier<SignInState> {
//emits loading state to start with
ExampleNotifier() : super(Loading()) {
//We then invoke a function that gets some data... from an api
getAsyncDate();
}
void getAsyncDate() async {
final foo = await someAsyncCall();
//once its returned we set the state to it...
state = foo;
}
}
Basically is it ok to use the constructor invoke a function that will then set the state on the StateNotifier ?
Thanks
CodePudding user response:
Yes, it's great practice. The new version of Riverpod 2.0 has a class AsyncNotifier<State>
(like as StateNotifier<State>
):
import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class SignInNotifier extends AsyncNotifier<void> {
// Override the [build] method to return a [FutureOr]
@override
FutureOr<void> build() {
// Return a value (or do nothing if the return type is void)
}
Future<void> signIn() async {
// Read the repository using ref
final authRepository = ref.read(authRepositoryProvider);
// Set the loading state
state = const AsyncLoading();
// Sign in and update the state (data or error)
state = await AsyncValue.guard(authRepository.signIn);
}
}
The provider for this class looks like this:
// Using a constructor tear-off:
final signInProvider = AsyncNotifierProvider<SignInNotifier, void>(SignInNotifier.new)
Note how the function that creates the provider doesn't have a ref
argument.
However, ref
is always accessible as a property inside Notifier
or AsyncNotifier
subclasses, making it easy to read other providers.
More info: