stated_result 0.2.0-preview.3
stated_result: ^0.2.0-preview.3 copied to clipboard
A bloc that accepts async source as input
stated_result #
A library built upon Bloc_Flutter and Provider to make it easy to support async operation
This library includes 4 sub-modules:
Multi-State Result #
The library includes 4 different types of MultiStateResult, each has different state to indicates its internal state. The type is immutable data type, and can be pattern matched like enum.
ActionResult: A result has 2 states:CompletedandFailed. It can be used to represents the result of an action without return value.AsyncActionResult: A result has 4 states:Pending,Busy,Completed, andFailed. It represents the full lifecycle of an async action without a return value.QueryResult<T>: A result has 2 states:SucceededandFailed, in whichSucceededwould holds a value of given typeT. It represents the result of a query that returns a certain type of data.AsyncQueryResult<T>: A result has 4, states:Pending,Busy,Suceeded, andFailed. It represents a full lifecycle of a query that returns a certain type of data. Potentially, an extra stateDefaultcan be used, it is likePendingindicates the query hasn't been started yet, but also holds avaluelikeSucceeded. It can be used to indicates the scenario which app provides default value as optimistic updates.
How it works #
Typically, the result can be used to represent the result of an async operation, such as calling API or loading data from DB, or time consuming data processing.
Typically, the result itself should be AsyncActionResult or AsyncQueryResult, depends on whether app cares about the return value or not, and UI would renders accordingly, such as loading screen error screen or the successful screen.
The query/action itself, would be represented as Future<QueryResult>/Future<ActionResult>, which can be used to update AsyncQueryResult and AsyncActionResult accordingly.
Typically, AsyncActionResult would be holds by a Bloc or ValueNotifier, which will be discussed below.
Convert Sync Result to Async Result #
asAsyncResult can convert sync result into its async counterpart accordingly.
AsyncActionResult asyncActionResult = actionResult.asAsyncResult();
AsyncQueryResult asyncQueryResult = queryResult.asAsyncResult();
Convert Future Types #
Future.asActionResult can materialise any future into Future<ActionResult> . The new future would always fulfills, when original future failed, it captures the error into a FailedResult accordingly.
Future<ActionResult>.asActionResult would flatten the hierarchy and respect the failed value from original future.
Future<T>.asQueryResult would matertialse the future of T into Future<QueryResult<T>>. The new future would always fulfills, when original future failed, it captures the error into a FailedResult accordingly.
Multi-State Result Builder #
MultiStateResult types provide map and/or mapOr method to pattern match and map the value, which can be used to build UI manually.
ActionResultBuilder and QueryResultBuilder #
In practise, ActionResultBuilder and QueryResultBuilder provided by this library can be more convenient, with a few extra features.
ActionResultBuilder and QueryResultBuilder accepts different builder function to build the UI according to the state of the AsyncActionResult or the AsyncQueryResult.
An simple example:
Widget build(BuildContext context, AsyncActionResult result) =>
ActionResultBuilder(
result: result,
pendingBuilder: (_context) => Center(child: Text("No Data")),
busyBuilder: (_context) => Center(child: CircularProgressIndicator()),
failedBuilder: (_context, error, _stackTrace) => Center(
child: Text("Error: $error"),
),
completedBuilder: (_context) => Center(child: Text("Completed")),
);
Non critical state default builders #
For ActionResultBuilder and QueryResultBuilder, completed and succeeded are considered as critical builder, which is mandatory each time to instantiate the Widget. While pendingBuilder, busyBuilder, and failedBuilder are optional, which can be omitted.
When the given builder is omitted, the ResultBuilder would search the widget hierarchy to find any default builder has been given. Just like Text would search DefaultTextStyle if textStyle is not explicitly given.
Accordingly, DefaultPendingResultBuilder, DefaultBusyResultBuilder, and DefaultFailedResultBuilder can be used to provide those default builders to their children along the widget tree.
DefaultResultBuilder #
If more than one default builder needs to be configured, rather than nested DefaultXXXResultBuilder, which results a relatively ugly code, DefaultResultBuilder can be used, which allow to configure multiple default builders at once.
DefaultResultBuilder can be use to setup the unified UI style of a portion of the screen.
Global default builders #
If optional builders are omitted, and no default builder are given. The ResultBuilder widget would uses something called global default builder to render the UI.
Which can be setup via
DefaultPendingResultBuilder.globalBuilderDefaultBusyResultBuilder.globalBuilderDefaultFailedResultBuilder.globalBuilder
It also can be configured in batch via DefaultResultBuilder.setGlobalBuilder
Bloc Integration #
Library provided the classes to integrate the [MultiStateResult] to Bloc
This library uses Cubit instead of Bloc, which is a simplified and easier-to-use Bloc.
ActionCubit: ACubitholdsAsyncActionResult, it also provides protected methods to update its value from different kinds ofFutureQueryCubit<T>: ACubitholdsAsyncQueryResult<T>, it also provides protected methods to update its value from different kinds ofFuture
Both ActionCubit and QueryCubit can be provided into widget tree via BlocProvider
Bloc Builder and Bloc Consumer #
Like BlocBuilder and BlocConsumer provided by Bloc_Flutter library, the following types are provided:
ActionBlocBuilder:BlocBuilderthat consumesActionCubitviaActionResultBuilderActionBlocConsumer:BlocConsumerthat consumesActionCubitviaActionResultBuilderQueryBlocBuilder:BlocBuilderthat consumesQueryCubitviaQueryResultBuilderQueryBlocConsumer:BlocConsumerthat consumesQueryCubitviaQueryResultBuilder
ValueNotifier Integration #
Besides of Bloc, this library also provides the integration to ValueNotifier and ListenableBuilder.
ActionNotifier: AValueNotifierholdsAsyncActionResult, it also provides protected methods to update its value from different kinds ofFutureQueryNotifier<T>: AValueNotifierholdsAsyncQueryResult<T>, it also provides protected methods to update its value from different kinds ofFuture
Listenable Builder #
Like `ListenableBuilder, the following classes are provided:
ActionListenableBuilder:ListenableBuilderthat consumesActionNotifierviaActionResultBuilderQueryListenableBuilder:ListenableBuilderthat consumesQueryNotifierviaQueryResultBuilder