butter library

A thin application framework for flutter making use of async_redux.

Butter allows you to structure your app into modules and submodules where each module is composed of pages, states, models and actions as already introduced by redux.

Most common classes used to structure the app are: BaseAction, BaseModule, BasePageState, BaseStatefulPageView, and BaseStatelessPageView

References:

Classes

ActionObserver<St>
ActionStatus
AppPersistor
AppState
Stores the application's state
BaseAction
A ReduxAction wrapper for Action objects and provides all necessary utilities needed to interact with the Store and the Navigator.
BaseDispatcher<St>
A base interface for dispatching actions to the Store
BaseModel<St>
Don't use, this is deprecated. Please, use the recommended Vm class. This should only be used for IMMUTABLE classes. Lets you implement equals/hashcode without having to override these methods.
BaseModule
The base Module. It handles the internal routing of the module.
BaseNavigator
The base interface for navigation
BasePageConnector<PageState extends BasePageState<BaseUIModel>, PageView extends BasePageView>
Pairs the Page to its State
BasePageSpecs
The base class for page specifications
BasePageState<Model extends BaseUIModel>
A BaseModel wrapper for State objects and provides all necessary utilities needed to interact with the Store and the Navigator.
BasePageTransition
The base class for page transitions
BasePageView
The base class for butter pages
BaseRoutes
This is the base definition of a route class
BaseStatefulPageView
An implementation of the BasePageView using a StatefulWidget
BaseStatelessPageView
An implementation of the BasePageView using a StatelessWidget
BaseUIModel<T>
The base definition of UI Models
Butter
Provider of first class butter library objects and settings
ConnectorTester<St, Model>
Helps testing the StoreConnectors methods, such as onInit, onDispose and onWillChange.
ConsoleActionObserver<St>
This action-observer will print all actions to the console, with color, like so:
DefaultModelObserver<Model>
This model observer prints the StoreConnector's ViewModel to the console.
DevelopmentErrorObserver<St>
During development, use this error observer if you want all errors to be shown to the user in a dialog, not only UserExceptions. In more detail: This will wrap all errors into UserExceptions, and put them all into the error queue. Note that errors which are NOT originally UserExceptions will still be thrown, while UserExceptions will still be swallowed.
ErrorObserver<St>
This will be given all errors, including those of type UserException. Return true to throw the error. False to swallow it.
Event<T>
The Event class can be used as a Redux state with flutter_redux , usually to change the internal state of a stateful widget. When creating the ViewModel with the StoreConnector, the event is "consumed" only once, and is then automatically considered "spent".
EventMultiple<T>
An Event from multiple sub-events. When consuming this event, if the first sub-event is not spent, it will be consumed, and the second will not. If the first sub-event is spent, the second one will be consumed.
EvtState<T>
The EventState can be used with stateful widgets to generate a "pulse" that you can use to change something.
ExceptionCode
GlobalWrapError<St>
This wrapper will be given all errors thrown in your actions (including those of type UserException). Then:
Log<St>
Connects a Logger to the Redux Store. Every action that is dispatched will be logged to the Logger, along with the new State that was created as a result of the action reaching your Store's reducer.
MappedEvent<V, T>
A MappedEvent is useful when your event value must be transformed by some function that, usually, needs the store state. You must provide the event and a map-function. The map-function must be able to deal with the spent state (null or false, accordingly).
MockAction<St>
MockStore<St>
Creates a Redux store that lets you mock actions/reducers.
ModelObserver<Model>
This will be given all errors, including those of type UserException. Return true to throw the error. False to swallow it. Note:
Available constructors: NavigateAction.push(), NavigateAction.pop(), NavigateAction.popAndPushNamed(), NavigateAction.pushNamed(), NavigateAction.pushReplacement(), NavigateAction.pushAndRemoveUntil(), NavigateAction.replace(), NavigateAction.replaceRouteBelow(), NavigateAction.pushReplacementNamed(), NavigateAction.pushNamedAndRemoveUntil(), NavigateAction.pushNamedAndRemoveAll(), NavigateAction.popUntil(), NavigateAction.removeRoute(), NavigateAction.removeRouteBelow(), NavigateAction.popUntilRouteName(), NavigateAction.popUntilRoute(),
PageArguments<PageTransition extends BasePageTransition>
The page arguments to be passed to a route
PersistAction<St>
Persistor<St>
Use it like this:
PersistorDummy<T>
A dummy persistor.
PersistorPrinterDecorator<St>
A decorator to print persistor information to the console. Use it like this:
ReduxAction<St>
Actions must extend this class.
StateObserver<St>
One or more StateObservers can be set during the Store creation. Those observers are called for all dispatched actions, right after the reducer returns. That happens before the after() method is called, and before the action's wrapError() and the global wrapError() methods are called.
Store<St>
Creates a Redux store that holds the app state.
StoreConnector<St, Model>
Build a widget based on the state of the Store.
StoreConnectorInterface<St, Model>
StoreProvider<St>
Provides a Redux Store to all ancestors of this Widget. This should generally be a root widget in your App. Connect to the Store provided by this Widget using a StoreConnector.
StoreTester<St>
Helps testing the store, actions, and sync/async reducers.
SwallowErrorObserver<St>
Swallows all errors (not recommended). Passe it to the store like this:
TestErrorObserver<St>
During tests, use this error observer if you want all errors to be thrown, and not swallowed, including UserExceptions. You should probably use this in all tests that you don't expect to throw any errors, including UserExceptions.
TestInfo<St>
TestInfoList<St>
List of test information, before or after some actions are dispatched.
UserExceptionAction<St>
If you want the UserExceptionDialog to display some UserException, you must throw the exception from inside an action's before or reduce methods.
UserExceptionDialog<St>
Use it like this:
Vm
Vm is a base class for your view-models.
VmEquals<T>
Each state passed in the Vm.equals parameter in the in view-model will be compared by equality (==), unless it is of type VmEquals, when it will be compared by the VmEquals.vmEquals method, which by default is a comparison by identity (but can be overridden).
VmFactory<St, T extends Widget?, Model extends Vm>
Factory that creates a view-model of type Vm, for the StoreConnector:
Wait
Immutable object to keep track of boolean flags that indicate if some process is in progress (the user is "waiting").
WaitAction<St>
WaitAction and Wait work together to help you create boolean flags that indicate some process is currently running. For this to work your store state must have a Wait field named wait, and then:
WrapError<St>
WrapError is deprecated in favor of GlobalWrapError.
WrapReduce<St>
You may globally wrap the reducer to allow for some pre or post-processing. Note: if the action also have a ReduxAction.wrapReduce method, this global wrapper will be called AFTER (it will wrap the action's wrapper which wraps the action's reducer).

Enums

CompareBy
LogLevel
Butter log levels
WaitOperation

Functions

cache1state<Result, State1>(Result Function() f(State1)) → Result Function() Function(State1)
Cache for 1 immutable state, and no parameters.
cache1state_0params_x<Result, State1, Extra>(Result Function() f(State1, Extra)) → Result Function() Function(State1, Extra)
Cache for 1 immutable state, no parameters, and some extra information. This is the same as cache1state but with an extra information. Note: The extra information is not used in any way to decide whether the cache should be used/recalculated/evicted. It's just passed down to the f function to be used during the result calculation.
cache1state_1param<Result, State1, Param1>(Result Function(Param1) f(State1)) → Result Function(Param1) Function(State1)
Cache for 1 immutable state, and 1 parameter.
cache1state_2params<Result, State1, Param1, Param2>(Result Function(Param1, Param2) f(State1)) → Result Function(Param1, Param2) Function(State1)
Cache for 1 immutable state, and 2 parameters.
cache2states<Result, State1, State2>(Result Function() f(State1, State2)) → Result Function() Function(State1, State2)
Cache for 2 immutable states, and no parameters.
cache2states_0params_x<Result, State1, State2, Extra>(Result Function() f(State1, State2, Extra)) → Result Function() Function(State1, State2, Extra)
Cache for 2 immutable states, no parameters, and some extra information. This is the same as cache1state but with an extra information. Note: The extra information is not used in any way to decide whether the cache should be used/recalculated/evicted. It's just passed down to the f function to be used during the result calculation.
cache2states_1param<Result, State1, State2, Param1>(Result Function(Param1) f(State1, State2)) → Result Function(Param1) Function(State1, State2)
Cache for 2 immutable states, and 1 parameter.
cache2states_2params<Result, State1, State2, Param1, Param2>(Result Function(Param1, Param2) f(State1, State2)) → Result Function(Param1, Param2) Function(State1, State2)
Cache for 2 immutable states, and 2 parameters.
cache2states_3params<Result, State1, State2, Param1, Param2, Param3>(Result Function(Param1, Param2, Param3) f(State1, State2)) → Result Function(Param1, Param2, Param3) Function(State1, State2)
Cache for 2 immutable states, and 3 parameters.
cache3states<Result, State1, State2, State3>(Result Function() f(State1, State2, State3)) → Result Function() Function(State1, State2, State3)
Cache for 3 immutable states, and no parameters. Example:
cache3states_0params_x<Result, State1, State2, State3, Extra>(Result Function() f(State1, State2, State3, Extra)) → Result Function() Function(State1, State2, State3, Extra)
Cache for 3 immutable states, no parameters, and some extra information.This is the same as cache1state but with an extra information. Note: The extra information is not used in any way to decide whether the cache should be used/recalculated/evicted. It's just passed down to the f function to be used during the result calculation.
internalsBaseModelInject<St>(BaseModel baseModel, St state, Store store) → void
For internal use only. Please don't use this.
internalsVmFactoryFromStore(VmFactory vmFactory) Vm?
For internal use only. Please don't use this.
internalsVmFactoryInject<St>(VmFactory<St, dynamic, dynamic> vmFactory, St state, Store store) → void
For internal use only. Please don't use this.

Typedefs

Dispatch<St> = FutureOr<ActionStatus> Function(ReduxAction<St> action, {bool notify})
DispatchAndWait<St> = Future<ActionStatus> Function(ReduxAction<St> action, {bool notify})
DispatchAsync<St> = Future<ActionStatus> Function(ReduxAction<St> action, {bool notify})
DispatchSync<St> = ActionStatus Function(ReduxAction<St> action, {bool notify})
Evt<T> = Event<T>
When the Event class was created, Flutter did not have any class named Event. Now there is. For this reason, this typedef allows you to use Evt instead. You can hide one of them, by importing AsyncRedux like this: import 'package:async_redux/async_redux.dart' hide Event; or import 'package:async_redux/async_redux.dart' hide Evt;
MessageFormatter<St> = String Function(St? state, ReduxAction<St> action, bool ini, int dispatchCount, DateTime timestamp)
A function that formats the message that will be logged:
OnDidChangeCallback<St, Model> = void Function(BuildContext? context, Store<St> store, Model viewModel)
A function that will be run on State change, after the build method.
OnDisposeCallback<St> = void Function(Store<St> store)
A function that will be run when the StoreConnector is removed from the Widget Tree. It is run in the State.dispose method. This can be useful for dispatching actions that remove stale data from your State tree.
OnInitCallback<St> = void Function(Store<St> store)
A function that will be run when the StoreConnector is initialized (using the State.initState method). This can be useful for dispatching actions that fetch data for your Widget when it is first displayed.
OnInitialBuildCallback<St, Model> = void Function(BuildContext? context, Store<St> store, Model viewModel)
A function that will be run after the Widget is built the first time. This function is passed the store and the initial Model created by the vm or the converter function. This can be useful for starting certain animations, such as showing Snackbars, after the Widget is built the first time.
OnWillChangeCallback<St, Model> = void Function(BuildContext? context, Store<St> store, Model previousVm, Model newVm)
A function that will be run on state change, before the build method. This function is passed the Model, and if distinct is true, it will only be called if the Model changes. This is useful for making calls to other classes, such as a Navigator or TabController, in response to state changes. It can also be used to trigger an action based on the previous state.
Reducer<St> = FutureOr<St?> Function()
ShouldUpdateModel<St> = bool Function(St state)
A test of whether or not your converter or vm function should run in response to a State change. For advanced use only. Some changes to the State of your application will mean your converter or vm function can't produce a useful Model. In these cases, such as when performing exit animations on data that has been removed from your Store, it can be best to ignore the State change while your animation completes. To ignore a change, provide a function that returns true or false. If the returned value is false, the change will be ignored. If you ignore a change, and the framework needs to rebuild the Widget, the builder function will be called with the latest Model produced by your converter or vm functions.
ShowUserExceptionDialog = void Function(BuildContext context, UserException userException, bool useLocalContext)
StateCondition<St> = bool Function(TestInfo<St> info)
Predicate used in StoreTester.waitCondition. Return true to stop waiting, and get the last state.
StoreConverter<St, Model> = Model Function(Store<St> store)
Convert the entire Store into a Model. The Model will be used to build a Widget using the ViewModelBuilder.
TestInfoPrinter = void Function(TestInfo)
ViewModelBuilder<Model> = Widget Function(BuildContext context, Model vm)
Build a Widget using the BuildContext and Model. The Model is derived from the Store using a StoreConverter.
WaitReducer<St> = St? Function(St? state, WaitOperation operation, Object? flag, Object? ref)

Exceptions / Errors

PersistException
StoreConnectorError
StoreException
General internal exception for AsyncRedux.
StoreExceptionTimeout
UserException
Represents an error the user could fix, like wrong typed text, or missing internet connection. Methods dialogTitle and dialogContent return Strings you can show in an error dialog.