bon_notifiers 1.0.0
bon_notifiers: ^1.0.0 copied to clipboard
A collection of custom notifiers and notifier mixins
bon_notifiers #
bon_notifiers is a collection of custom notifiers and mixins that I use in my projects. This package provides various utilities to extend on flutters Notifier principle. Primarily focussing on handling asynchronous operations with less boilerplate.
For a full statemanagement solution you can bundle this package with provider and flutters default notifiers.
Features #
AsyncNotifier<T>: A notifier taylored for handling asynchronous data.AsyncListenableBuilder<T>: A widget that listens toAsyncListenableand rebuilds based on the state changes.mixins: Reusable functionality for handling different states like loading, error, and result in your custom notifiers.
Example usage #
Async Notifier #
Using asyncnotifier as an object
final notifier = AsyncNotifier<String>();
// Set value
notifier.set('Data');
// Set error
notifier.setError('Something went wrong', error);
// Check flags
if (notifier.isLoading) {
// Show loading indicator
} else if (notifier.hasError) {
// From this point it is safe to acces error
print(notifier.error!);
} else if (notifier.hasResult) {
// From this point it is safe to acces result
print(notifier.result!);
}
Extending async notifier
//For more complex usecases extending AsyncNotifier can be useful
class ComplexAsyncNotifier extends AsyncNotifier<Data> {
ComplexAsyncNotifier({required this.repo}) {
_init();
}
final ExampleRepository repo;
//add more complex behaviours
Future<void> _init(){
try{
final result = await repo.getData();
set(result);
}
catch(e){
setError('Failed fetch data', error);
}
}
//add custom methods
void editName(String newName) {
setLoading();
try{
final data = await repo.update(result!.copyWith(name: newName));
set(data);
}
catch(error, stackTrace){
setError('Failed to update data' ,error);
}
}
}
final complexNotifier = ComplexAsyncNotifier();
// Using extended functionality
complexNotifier.editName('Alice');
AsyncListenableBuilder #
AsyncListenableBuilder<String>(
//pass the asyncNotifier (or a custom async listenable)
asyncListenable: notifier,
//the resultBuilder is executed when the asyncListenable optains a (new) result
resultBuilder: (context, result, child) => Text(result),
//the errorBuilder is executed when the asyncListenable optains an error
errorBuilder: (context, error, child) => Text('Error: $error'),
//a loadingIndicator can be optionally passed, this defaults to CircularProgressIndicator.adaptive
loadingIndicator: CircularProgressIndicator(),
//Like the native flutter ListenableBuilders, a static child can be provided if a part of the widget tree is not dependant on the notifier
child: Text('This is a static widget'),
)
Error Mixin #
The error mixin can be used as follows:
class MyErrorNotifier extends ChangeNotifier with ErrorNotifier {
// A method to simulate fetching data and setting an error
void fetchData() {
try {
throw Exception("Data fetch failed");
} catch (error) {
setError('Failed to fetch data', error);
}
}
}
final notifier = MyErrorNotifier();
//The mixin exposes hasError and error getters
if(notifier.hasError){
print(notifier.error);
}
Loading mixin #
The loading mixin can be used as follows:
class MyLoadingNotifier extends ChangeNotifier with LoadingNotifier {
// A method to simulate data loading process
void fetchData() {
setLoading(); // Starts the loading state using LoadingNotifier
// Simulating data fetch
Future.delayed(Duration(seconds: 2), () {
setNotLoading(); // Ends the loading state once data is fetched
});
}
}
final notifier = MyErrorNotifier();
//The mixin exposes a loading boolean flag
print(notifier.isLoading);
Listening for errors: #
The AsyncListenable class exposes a listener that can be added to handle or log errors from one place.
AsyncListenable.errorListener = (message, notifier, error, stackTrace){
//log errors from one place so we dont have to put logger calls in every notifier
logger.e(
'$message in ${notifier.runtimeType}',
error: error,
stackTrace: stackTrace
);
}
This method will be called any time an error occurs in either an AsyncNotifier or a ChangeNotifier with the ErrorNotifier mixin
Every public class and method in this package is documented, for more documentation see the api reference
License #
This project is licensed under the MIT License - see the LICENSE file for details.