Skip to content

Instantly share code, notes, and snippets.

@tayormi
Created June 8, 2021 16:24
Show Gist options
  • Select an option

  • Save tayormi/d99eb198debe9c008c5590921186bafb to your computer and use it in GitHub Desktop.

Select an option

Save tayormi/d99eb198debe9c008c5590921186bafb to your computer and use it in GitHub Desktop.
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
part 'request_state_notifier.freezed.dart';
abstract class RequestStateNotifier<T> extends StateNotifier<RequestState<T>> {
RequestStateNotifier() : super(RequestState.idle());
//It returns a Future with state if you want to avoid ProviderListener
Future<RequestState<T>> makeRequest(Future<T> Function() function) async {
try {
state = RequestState<T>.loading();
final response = await function();
final newState = RequestState<T>.success(response);
if (mounted) {
state = newState;
}
return newState;
} catch (e, st) {
final newState = RequestState<T>.error(e, st);
if (mounted) {
state = newState;
}
return newState;
}
}
}
@freezed
abstract class RequestState<T> with _$RequestState<T> {
const factory RequestState.idle() = Idle<T>;
const factory RequestState.loading() = Loading<T>;
const factory RequestState.success(@nullable T value) = Success<T>;
const factory RequestState.error(Object error, [StackTrace stackTrace]) =
Error<T>;
}
// Which I override for a page when I just want to do some request:
final signInEmailRequestProvider =
StateNotifierProvider<SignInEmailRequestNotifier>(
(ref) => SignInEmailRequestNotifier(ref.watch(apiProvider)),
);
class SignInEmailRequestNotifier extends RequestStateNotifier<void> {
final NetworkApi _api;
SignInEmailRequestNotifier(this._api);
Future<void> signIn(String email) => makeRequest(() => _api.signIn(email));
}
// Then I can use signInEmailRequestProvider to call the method and listen to the states using useProvider and/or ProviderListener.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment