result_notifier 0.2.1 result_notifier: ^0.2.1 copied to clipboard
“Pragmatic state management for Flutter, based on familiar and platform-native concepts”
Result Notifier #
Pragmatic and magic-free state management for Flutter - simply lagom.
Result Notifier is a simple and modest package for state management, based on familiar and platform-native concepts, rather than introducing new abstractions and mental models. In fact, the package really is little more than a few additions to ValueNotifier and ChangeNotifier. As the name of this package alludes to, one of the most important additions is the concept of a Result type, which can represent either some Data, an Error or a Loading state.
Features #
- Familiar and platform-native concepts, based on
ValueNotifier
,ChangeNotifier
,ValueListenableBuilder
etc. - Built around a Result
type that represents some type of data. The result can be in one of three different states:
- Data: The result contains some concrete data.
- Error: Represents an error, along with the previous data, if any.
- Loading: Represents a loading/reloading state, along with the previous data, if any.
- The core class ResultNotifier -
a
ValueNotifier
that holds aResult
value and provides methods for accessing and mutating the value. - Support for updating the data asynchronously (e.g. via an API call) using FutureNotifier.
- Support for cache expiration and refreshing of data when stale.
- An easy way to build the UI based on the current state of the result, using ResultBuilder.
- An auto-disposable store of notifiers, each associated with a key (see ResultStore Makes it easy to support pagination or build a support a parameterised.
- A ResultNotifierProvider
that can be used to handle the lifecycle of a notifier (i.e. creation and disposal), and provide it to a subtree of
widgets.
- There is also ResourceProvider, which can manage the lifecycle and access to arbitrary resources.
Getting Started #
Simply add the dependency and start writing some notifiers!
The simplest form of notifier only holds a value, much like a ValueNotifier
. But with ResultNotifier
, the value is
wrapped in a Result
type, which can represent either some data, an error, or a loading state.
final notifier = ResultNotifier<String>(data: 'Hello...');
notifier.toLoading(); // Convenience method to set the value to Loading, keeping the previous data.
print(notifier.data); // Prints 'Hello...'
notifier.value = Data('Hello Flutter!');
// or:
notifier.data = 'Hello Flutter!';
To use the notifier in a Widget, you can use the ResultBuilder
widget, which is similar to ValueListenableBuilder
,
but makes it easy to handle the different states of the result.
ResultBuilder<String>(
notifier,
onLoading: (context, data) => const CircularProgressIndicator(),
onError: (context, error, stackTrace, data) => Text('Error: $error'),
onData: (context, data) => Text(data),
),
Often you'll want to do something a little more elaborate, like fetching data from an API. In this case, you can
FutureNotifier
(or ResultNotifier.future), which is a ResultNotifier
that uses a "fetcher" function that returns a
Future.
final notifier = ResultNotifier<String>.future(
(_) async {
final response = await http.get(Uri.parse('https://www.boredapi.com/api/activity/'));
final json = jsonDecode(response.body) as Map<String, dynamic>;
return json['activity'] as String;
},
);
You can also use effects (see EffectNotifier
), to build more complex chains of notifiers:
notifier.effect((_, input) => input.toUpperCase());
See also the effects example for a more complete demonstration of these concepts.
Examples #
You can find a more complete example here, and additional examples in the examples directory in the repository.
More examples #
For an even more real-worldish example, check out this fork of Andrea Bizzotto's TMDB Movie App, which uses Result Notifier instead of Riverpod.
Or... rolling your own 🤷️ #
Instead of adding a dependency this package, consider building it yourself. It's really not that hard, especially since you can use the source code of this package as a starting point, and just throw out the parts you don't need/like.
When to use it - and when not to #
Result Notifier is probably most suitable for cases when your state management needs are in the ballpark of "low to moderate", or as we say in Sweden: lagom. If you need more advanced state management, you might want to reach for something more elaborate. But then again, maybe not - as in most cases, this very much depends on your general application architecture and modularization. And remember - excessive use of state management may also be a sign of a flawed architecture or over-engineering.
Things left to do... #
The usual stuff, more tests and more docs 😅.