states_rebuilder
a simple yet powerful state management technique for Flutter
6.4.0
15K downloads/mo
#2512 most downloaded on pub.dev
GIfatahTH/states_rebuilder
What this package is like to depend on
Last release 7 days ago
16 Aug 2026
Ships unpredictably
gaps range from 2 weeks to 2.5 years
Rarely documented
notes for 14 of 57 stable releases
Nothing withdrawn
no release was ever pulled
7 years old
90 releases · first in 2019
1 release in the last 12 months
see the full history below
Release timeline
90 releases · Mar 2019 to Aug 2026Releases
latest 60 of 90-
7.0.0-dev216 Aug 2026 pre-releaseNothing published for this version
-
7.0.0-dev119 Feb 2024 pre-releaseNothing published for this version
-
6.4.020 Feb 2024 -
6.3.1-dev127 May 2023 pre-releaseRelease notes
Open source →- Add
ReactiveModel.isStateInitializedgetter to check if the state has already initialized or not yet.
- Add
-
6.3.012 May 2023 -
6.2.025 Dec 2022Release notes
Open source →- remove double debug print messages (issue #275).
- Add dialogs and scaffold related navigation to
InjectedNavigation. - Close drawer and bottomSheet programmatically. (Issue #274)
- Moving the navigation functionality to its own independent packages: navigation_builder. Now
states_rebuilderuse thenavigation_builderpackage without any breaking change. - Make
stateAsynccoherent withsetToWaiting. - Refactor examples docs. Thanks to @montanajava.
- Prevent injected state from disposing of if autoDisposeWhenNotUsed is set to false (Issue #278). Thanks to @KKranjcevic
- Refactor internal code.
-
6.2.0-dev-424 Dec 2022 pre-releaseNothing published for this version
-
6.2.0-dev-309 Dec 2022 pre-releaseNothing published for this version
-
6.2.0-dev-203 Dec 2022 pre-releaseNothing published for this version
-
6.2.0-beta-113 Jun 2022 pre-releaseNothing published for this version
-
6.1.1-dev-203 Dec 2022 pre-releaseNothing published for this version
-
6.1.1-dev-129 Oct 2022 pre-releaseNothing published for this version
-
6.1.009 May 2022Nothing published for this version
-
6.1.0+113 May 2022 -
6.0.028 Feb 2022Release notes
Open source →- Remove deprecated API
- Refactor internal code
- Add
OnBuilder.createFutureandOnBuilder.createStreamwidgets. - Add
OnBackNavigationScopewidget - Add more examples
- Fix issues #260 #259 #256
- Remove deprecated API
-
6.0.0-dev119 Feb 2024 pre-releaseNothing published for this version
-
6.0.0-dev-327 Feb 2022 pre-releaseNothing published for this version
-
6.0.0-dev-227 Feb 2022 pre-releaseNothing published for this version
-
6.0.0-dev-127 Feb 2022 pre-releaseNothing published for this version
-
5.3.0-dev-111 Feb 2022 pre-releaseNothing published for this version
-
5.2.005 Jan 2022Release notes
Open source →- Add Navigator 2 support.
- Add
statesInterceptortosetStatemethod. - Add
setToIsIdle,setToIsWaiting,setToHasData,setToHasErrormethods. - Add
OnBuilder.createlistener. - Fix issues #241 #248
- Improve internal logic
Breaking changes
ReactiveStatelessWidget.didMountWidgettakesBuildContextas parameter.
- Add
- Add Navigator 2 support.
-
5.2.0-dev-305 Jan 2022 pre-releaseNothing published for this version
-
5.2.0-dev-219 Dec 2021 pre-releaseNothing published for this version
-
5.2.0-dev-117 Dec 2021 pre-releaseNothing published for this version
-
5.2.0-dev11 Dec 2021 pre-releaseNothing published for this version
-
5.0.013 Oct 2021Release notes
Open source →New features
- Add
RM.injectFormFieldandOnFormFiledFielderto injected input fields other thanTextFiled(See issue #219). - Add
refreshTokenmethod toIAuthinterface. It is used to refresh token (See issue #228). - Add
isEnabledandisReadOnlyto toInjectedTextEditing, andOnFormBuilder(See issue #229). - Add
TopStatelessWidgetto replaceTopAppWidget(See issue #232). - Add
InjectedTabPageViewto work with tabs and pages (See issue #233).
Breaking changes
onSetState,onData,onError,onAfterStateare all deprecated in favor tosideEffectsparameter which takes aSideEffectsobject.(See issue #222).- Deprecate
validatorparameter inRM.injectTextEditing.validatorsis used instead. - Deprecate
middleSnapStatein favor tostateInterceptor - Deprecate
onCRUD(inRM.injectedCRUD) in favor toOnCRUDSideEffects
See the detailed change log Here
- Add
-
5.0.0-dev-713 Oct 2021 pre-releaseNothing published for this version
-
5.0.0-dev-603 Oct 2021 pre-releaseNothing published for this version
-
5.0.0-dev-503 Oct 2021 pre-releaseNothing published for this version
-
5.0.0-dev-403 Oct 2021 pre-releaseNothing published for this version
-
5.0.0-dev-322 Sep 2021 pre-releaseNothing published for this version
-
5.0.0-dev-211 Sep 2021 pre-releaseNothing published for this version
-
5.0.0-dev24 Aug 2021 pre-releaseNothing published for this version
-
4.4.004 Sep 2021Release notes
Open source →- Add
OnReactivewidget for implicit subscription:
final counter = 0.inj(); // inWidget tree OnReactive( () => Text(counter.state.toString()); // will rebuild if the state of counter changes )- Add
ReactiveStatelessWidgetabstract widget for implicit subscription:
///All states consumed in a descendant widget of this widget will be listened to. class MyWidget extends ReactiveStatelessWidget{ @override Widget build(BuildContext context) { return Builder( builder: (context){ return Text(counter.state.toString()); } ); } }-
Add
OnBuilder,OnAuthBuilder,OnCRUDBuilder,OnAnimationBuilder,OnScrollBuilder,OnFormBuilder,OnFormSubscriptionBuilder,OnTabBuilderwidget and their method equivalent:myState.rebuild,myState.rebuild.onAuth,myState.rebuild.onCRUD,myState.rebuild.onAnimation,myState.rebuild.onScroll,myState.rebuild.onForm,myState.rebuild.onFormSubscription,myState.rebuild.onTab, -
myState.rebuilder,myState.whenRebuilder,myState.whenRebuilderOrare deprecated in favor tomyState.rebuild,myState.rebuild.onAll,myState.rebuild.onOr, -
Add
InjectedPageTabto easily deal with page and tab views.
- Add
-
4.4.0-dev-223 Aug 2021 pre-releaseNothing published for this version
-
4.4.0-dev-113 Aug 2021 pre-releaseNothing published for this version
-
4.4.0-dev03 Jul 2021 pre-releaseNothing published for this version
-
4.3.013 Jun 2021Release notes
Open source →- Add
InjectedAnimation.resetAnimationmethod reset the global duration, curve and repeats of the animation. - Add restart parameter to
InjectedAnimation.triggerAnimationto force animation to restart from the lower bound.
- Add
-
4.3.0-beta07 Jun 2021 pre-releaseNothing published for this version
-
4.3.0-beta+109 Jun 2021 pre-releaseNothing published for this version
-
4.2.027 May 2021Release notes
Open source →- Add
shouldAutoStartparameter toRM.injectedAnimation(See issue #186). - Add
setCurveandsetReverseCurveto theInjectedAnimation. Useful for staggered animation (See issue #186). InjectedAnimation.refreshandInjectedAnimation.triggerAnimationreturn a future that resolves when the started animation ends.- Add
PersistState.shouldRecreateTheState(see issue #192). - Internal refactor to improve performance.
- Increase test coverage
- Fix typo (fromTween)
- Add
-
4.1.008 May 2021Release notes
Open source →- Solve #183 and #184 issues. (state can be nullable)
- For
InjectedCRUDandInjectedAuth,getRepoAsis now sync. - First release of
InjectedAnimationInjectedScrolling,InjectedTextEditingandInjectedForm. - Deprecate
TopAppWidget.waitForin favor ofTopAppWidget.ensureInitialization. - Refactor internal code.
Test:
- In tests, global mock must be put inside
setUpmethod.
-
4.1.0+118 May 2021Nothing published for this version
-
4.1.0+218 May 2021 -
4.0.011 Mar 2021Nothing published for this version
-
4.0.0+113 Mar 2021Release notes
Open source →Breaking change :
- Remove RMKey classes.
RM.injectComputedis removed- Change Injector.en to RM.env.
New features :
- Add On and OnCombined.
- All
onErrorcallbacks inOnandOnCombinedexpose a refresher to retry the last async function that causes the exception. - middleSnapState
- Add RM.injectCRUD, RM.injectAuth, RM.injectTheme, andRM.injectI18N.
- Add page route transition animation.
- Add
fullscreenDialogandmaintainStateparameters to thenavigator - Add dynamic segment and nested routing
- Refactor the internal logic.
- Refactor to null safety.
See the detailed change log Here
-
4.0.0-nullsafety.103 Mar 2021 pre-releaseNothing published for this version
-
4.0.0-nullsafety.017 Feb 2021 pre-releaseNothing published for this version
-
4.0.0-nullsafety.0+117 Feb 2021 pre-releaseNothing published for this version
-
3.2.027 Oct 2020Release notes
Open source →Injected.persistis a function instead of a simple object- add
persistStateProvider,catchPersistErroranddebugPrintOperationstoPersistStateclass. - Persist read works with async
```dart final model = RM.inject<Model>( () => 0, persist:()=> PersistState( key: '__model_Key__', toJson: (state) => json.encode(state), fromJson: (json) => json.decode(json), onError: (err, stack){ //If the persistance fails, the error is captured here, and the state is undone to the //last valid state } //For this state the default persistance provider is overridden. persistStateProvider: MyAnOtherPersistanceProvider() //Print an informative message on the Read, Write, Delete operations debugPrintOperations: true, //Catch read, delete Exceptions catchPersistError: true, ), );-
Since errors are not created to be caught, states_rebuilder will not catch errors unless the parameter [StatesRebuilderConfig.shouldCatchError] is true. Instead, Exceptions are intended to be caught. Your costume error/exception classes must implement
ExceptionnotError. As this may leads the app to break, to fix just search for allextends Error {and replace withimplements Exception { -
Introduction of
Injected.inheritandInject.reInheritmethods for widget-wise injection. Similar toInheritedWidget. -
Experimental with
Injected.listenas possible substitution ofInjected.rebuilder,Injected.whenRebuilderandInjected.whenRebuilderOr.
3.1.0 (2020-09-07)
- Add
RM.navigatefor simple navigation. Now, we use:
MaterialApp( navigatorKey : RM.navigate.navigatorKey, // ) //to navigate: * RM.navigator.to(Page1()); * RM.navigator.toNamed('/page1'); * RM.navigator.toReplacement(Page1()); * RM.navigator.toReplacementNamed('/page1'); * RM.navigator.toAndRemoveUntil(Page1(), '/page2'); * RM.navigator.pushNamedAndRemoveUntil('/page1', '/page2'); * RM.navigator.back(); * RM.navigator.backUntil('/page2'); * RM.navigator.backAndToNamed('/page2'); //To show dialogs, menu and bottom sheets * RM.navigator.toDialog => showDialog * RM.navigator.toCupertinoDialog => showCupertinoDialog * RM.navigator.toBottomSheet => showModalBottomSheet * RM.navigator.toCupertinoModalPopup => showCupertinoModalPopup //To show Scaffold related snackBars, bottom sheets and drawers * RM.scaffoldShow.bottomSheet => Scaffold.of(context).showBottomSheet, * RM.scaffoldShow.snackBar => Scaffold.of(context).showSnackBar, * RM.scaffoldShow.openDrawer => Scaffold.of(context).openDrawer, * RM.scaffoldShow.openEndDrawer => Scaffold.of(context).openEndDrawer,- Deprecate
RM.navigator,RM.ScaffoldandRM.show. - Add state persistance feature.
- Refactor internal logic to improve performance.
3.0.0 (2020-09-04)
Non breaking change :
- Refactor internal logic.
New features :
- Add global functional injection feature.
- Add undo / redo state feature.
Breaking change :
- Add
shouldRebuildparameter toStateBuilderand other widgets. NowStateBuilderwill build only if the exposed model hasData (For performance reason). This make cause some unexpected behavior. To all the widget to rebuild on other state (onWaiting, onError), you can:- Use
WhenRebuilderOrwidget. Or, - return true in
shouldRebuildparameter
StateBuilder( observe: ()=>MyReactiveModel(), shouldRebuild: (rm)=> true, builder: (context, rm){ //-- } ) - Use
- The API of
StateWithMixinBuilderhas changed and named constructors have been added.
2.3.1 (2020-07-19)
- Refactor internal logic.
2.3.0 (2020-07-16)
- Add context subscription (#108)
Injector( inject: [Inject(() => Model())], builder: (context) { //Get the injected ReactiveModel and subscribe this ContextBuilder to it. final rm = RM.get<Model>(context: context); return rm.whenConnectionState( onIdle: () => Text('idle'), onWaiting: () => Text('waiting'), onError: (e) => Text('${e.message}'), onData: (d) => Text(d.counter.toString()), ); }, );-
Add possibility to skip onWaiting while calling setState. (#109)
-
Add two static flags
debugErroranddebugErrorWithStackTraceto console log states__rebuilder related errors. -
Improve logics and docs.
2.2.0 (2020-06-02)
- Add the ability to do side effects without context (navigation, show dialogs ...). See more
- add
refreshmethod to theReactiveModelobject. See more - add
notifymethod to theReactiveModelobject. - Refactor the logic of
futureandstreammethods.
2.1.0 (2020-05-24)
- add
debounceDelayandthrottleDelaytosetStatemethod. - Refactor RMKey logic.
- Add
RMKey.getmethod. - Async dependency feature can work with flavors (Inject.interface).
- fix bug #98.
- Refactor docs.
2.0.0 (2020-05-13) see more details
Breaking change :
- Remove context subscription possibly.
before :
final rm = RM.get<T>(context: context);After: one have to use one of the four observer widgets
StateBuilder( observe : ()=> RM.get<T>(), builder : (context, rm ){ //... } )As consequence
Injector.reinjectis removed- Remove
setValue,value,getFuture,getStreamandgetSetState. All the functionalities of the removed API are done withsetState,future,streammethods.see more details - Remove the models parameter from the
SateBuilder,WhenRebuild,WhenRebuilderOr, andOnSEtStateListener.
Non Breaking change :
- Add the possibility to listen to to a ReactiveModel from a Model Class: (#78)
Theclass ModelA{ } class ModelB { ModelB(){ RM.get<ModelA>().listenToRM((ReactiveModel<ModelA> modelARM)){ if(modelARM.hasError){ //.... }else if (modelARM.hasData){ //... } //or you can use whenConnectionState } } }listenToRMreturn a void callBack to be used for unsubscription. - Add
valueAsyncto obtained the state of aReactiveModelas future. - Refactor the code and improve performance.
- Improve docs.
- Resolve issues : #85
1.15.0 (2020-04-29)
- Add
Inject.previous. #47 see more details - Add Shortcuts to get and create model, future, stream
ReactiveModels:
IN.get<T>()//To consume the pure registered instance; RM.get<T>(); //to get the ReactiveModel instance of type T. RM.create<T>(myModel);// to create a local ReactiveModel. RM.future<T>(myFuture);// to create a local future ReactiveModel. RM.stream<T>(myStream);// to create a local stream ReactiveModel. RM.getSetState<T>(fn); // to get the ReactiveModel T and call setState method- Add
ReactiveModel.futureandReactiveModel.stream, to handle state notification of immutable objects.see more details. - Add the concept of ReactiveModel key (RMKey). see more details
- Add
onData(issue #78) andonErrorto the ReactiveModel. - Change the readme to focus on ReactiveModel concept.
- add
RM.printActiveRMto print the ReactiveModel has is sending the notification. - Fix issue #72
1.14.3 (2020-03-10)
- Add
reinjectOnparameters toInjectorwidgets. It takes a list ofReactiveModel, and it re-injects the registered models whenever any of the ReactiveModels in thereinjectOnparameters emits a notification. issue #47.
example of injected stream:
final multiplierRM = ReactiveModel.create(1); Widget builder(BuildContext context){ return Injector( inject: [Inject.stream(() => Stream.periodic(Duration(seconds: 1), (num) => multiplierRM * num))], //Listen to multiplierRM and reinject the stream whenever multiplierRM emits a notification reinjectOn: [multiplierRM], builder: (context) { /// /// }, ); }The stream emits: 1, 2, 3, 4, ... because multiplierRM = 1.
when the value
multiplierRMis set to 2:multiplierRM.setValue(()=>2);The stream subscription is cancelled and an new subscription is established that emits the values : 2, 4, 6, 8 ..... (multiplierRM = 2). Now decedent widgets can subscribe to the stream and rebuild whenever the stream emits a value.
This works for injected streams, futures and vanilla dart classes.
-
Add watch parameter to ReactiveModel.stream constructor. issue 61
-
refactor code to improve performance.
1.14.2 (2020-02-28)
- Add
ReactiveModel<T>.stream(T stream)andReactiveModel<T>.future(T future)to create aReactiveModelfrom a stream or future. - Override the
toStringmethod of theReactiveModelto give an informative debug print. - Refactor the code.
1.14.1 (2020-02-25)
- Add
ReactiveModel<T>()factory constructor. it is equivalent toInjector.getAsReactive(<T>). You will save nine key stroke and it looks more readable.
//You can use the long form final fooRM = Injector.getAsReactive<Foo>(); //Or the new way: final fooRM = ReactiveModel<Foo>();for example instead of :
StateBuilder<Foo>( models:[Injector.getAsReactive<Foo>()], builder:(context, fooRM){ } )you write:
StateBuilder<Foo>( models:[ReactiveModel<Foo>()], builder:(context, fooRM){ } )- Add
shouldOnInitStatetoOnSEtStateListener: UsuallyonSetStateand its equivalentonData,onErrorare invoked only if the observable reactive model emits a notification. This means they are not invoked in theinitStatemethod.shouldOnInitStateis an optional bool parameter and when se to true theonSetStatemethod will be called from theinitStatemethod. - Add
onDatatoWhenRebuilderOr - Fix issue #52 and #55.
- Add tests to examples (Easiness of test, is a sign of good code).
1.14.0 (2020-02-18)
- Add
resetToIdleandresetToHasDatamethods to theReactiveModel. use case examples:
- Use it with
getAsReactiveso that each time the reactive model is obtained, it will be obtained with the desired asynchronous state, whatever its value before.
final fooRM = Injector.getAsReactive<Foo>()..resetToIdle(); //you can combine it with asNew final fooRM = Injector.getAsReactive<Foo>().asNew('mySeed')..resetToIdle();- Use it if the reactive model throws an error, and you want something like clearing the error.
fooRM.setState( (s) => s.someMethod(), onError: (context, error) async { //awaiting the alert dialog await showDialog( context: context, builder: (context){ /// } ); //clearing the error. fooRM.resetToHasData(); }, )- Add
Injector.enableTestModestatic bool field. Set it to true in tests to inject fake dependency. ex: Let's suppose we have the widget.
Import 'my_real_model.dart'; class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Injector( inject: [Inject(() => MyRealModel())], builder: (context) { final myRealModelRM = Injector.getAsReactive<MyRealModel>(); // your widget }, ); } }MyApp widget depends on
MyRealModel.To mock
MyRealModeland test MyApp we setInjector.enableTestModeto true :testWidgets('Test MyApp class', (tester) async { //set enableTestMode to true Injector.enableTestMode = true; await tester.pumpWidget( Injector( //Inject the fake model and register it with the real model type inject: [Inject<MyRealModel>(() => MyFakeModel())], builder: (context) { //In my MyApp, Injector.get or Inject.getAsReactive will return the fake model instance return MyApp(); }, ), ); //My test }); //fake model implement real model class MyFakeModel extends MyRealModel { // fake implementation }See real test of the counter_app_with_error and counter_app_with_refresh_indicator.
- Add
tagandonWaitingparameters toOnSetStateListenerwidget. - Add
tagparameter toWhenRebuildandWhenRebuildOrwidgets - Improve the logic of
setValueandsetState. NowsetValuehas all the functionalities ofsetState.
1.13.0 (2020-02-12)
- Add static variable
Injector.envandInject.interfacenamed constructor so that you can register under different environments.
ex:
//abstract class abstract class ConfigInterface {} // first prod implementation class ProdConfig extends ConfigInterface {} //second dev implementation class DevConfig extends ConfigInterface {} //enum for defined flavor enum Flavor { Prod, Dev } void main() { //Choose yor environment flavor Injector.env = Flavor.Dev; runApp( Injector( inject: [ //Register against an interface with different flavor Inject<ConfigInterface>.interface({ Flavor.Prod: ()=>ProdConfig(), Flavor.Dev:()=>DevConfig(), }), ], builder: (_){ return MyApp( appTitle: Injector.get<ConfigInterface>().appDisplayName; ); }, ) ); }StateBuilder<T>,WhenRebuilder<T>andOnSetStateListener<T>observer widgets can be set to observer many observable reactive models. The exposed model instance depends on the generic parameterT. ex:
//first case : generic model is ModelA StateBuilder<ModelA>( models:[modelA, modelB], builder:(context, exposedModel){ //exposedModel is an instance of ReactiveModel<ModelA>. } ) //second case : generic model is ModelB StateBuilder<ModelB>( models:[modelA, modelB], builder:(context, exposedModel){ //exposedModel is an instance of ReactiveModel<ModelB>. } ) //third case : generic model is dynamic StateBuilder( models:[modelA, modelB], builder:(context, exposedModel){ //exposedModel is dynamic and it will change over time to hold the instance of model that emits a notification. //If modelA emits a notification the exposedModel == ReactiveModel<ModelA>. //Wheres if modelB emits a notification the exposedModel == ReactiveModel<ModelB>. } )- Add
WhenRebuilderOr. It is equivalent toWhenRebuilderbut with optionalonIdle,onWaitingandonErrorparameters and with required defaultbuilder.
1.12.1 (2020-02-.3)
- Add Continuous Integration and code coverage support.
- Improve test coverage.
1.12.0 (2020-01-30)
- Add
ReactiveModel<T>.create(T value)to create aReactiveModelfrom a primitive value. The createdReactiveModelhas the full power the other reactive models created usingInjectorhave. ex: This is a simple counter app:
class App extends StatelessWidget { //Create a reactiveModel<int> with initial value and assign it to counterRM filed. final counterRM = ReactiveModel.create(0); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( // Subscribe StateBuilder widget ot counterRM child: StateBuilder( models: [counterRM], builder: (context, _) { return Text('${counterRM.value}'); }, ), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.add), //set the value of the counterRM and notify observers. onPressed: () => counterRM.setValue(() => counterRM.value + 1), ), ), ); } }- Add
WhenRebuilderwidget. It is a shortcut of usingSateBuilderto subscribe to an observable model and useReactiveModel.whenConnectionStatemethod to exhaustively switch over all the possible statuses ofconnectionState.
instead of:
Widget build(BuildContext context) { return StateBuilder<PlugIn1>( models: [Injector.getAsReactive<PlugIn1>()], builder: (_, plugin1RM) { return plugin1RM.whenConnectionState( onIdle: () => Text('onIDle'), onWaiting: () => CircularProgressIndicator(), onError: (error) => Text('plugin one has an error $error'), onData: (plugin1) => Text('plugin one is ready'), ); }, ); }You use :
@override Widget build(BuildContext context) { return WhenRebuilder<PlugIn1>( models: [Injector.getAsReactive<PlugIn1>()], onIdle: () => Text('onIdle'), onWaiting: () => CircularProgressIndicator(), onError: (error) => Text('plugin one has an error $error'), onData: (plugin1) => Text('plugin one is ready'), ); }As a good side effect of using
WhenRebuilder, you can subscribe to many observable models and a combination status is exposed so thatonDatawill not be invoked only after all observable models have data.ex:
final plugin1RM = Injector.getAsReactive<PlugIn1>(); final plugin2RM = Injector.getAsReactive<PlugIn2>(); @override Widget build(BuildContext context) { return WhenRebuilder<PlugIn1>( models: [plugin1RM, plugin2RM], onIdle: () => Text('onIDle'), //onWaiting is called if any models is in the waiting state onWaiting: () => CircularProgressIndicator(), // onError will be called with the thrown error, if any of the observed models throws. onError: (error) => Text('plugin1 or plugin2 has an error $error'), //onData is called when all observable models have data onData: (plugin1) => Text('plugin1 and plugin2 are both ready'), ); }-
Add
OnSetStateListenerwidget to handle side effects. It subscribes to a list of observable models and listen to them and execute the corresponding onData or onError side effects. -
Add
valuegetter andReactiveModel.setValuemethod. They are the counterpart of thestategetter andReactiveModel.setStatemethod respectively. They are more convenient to use with primitive values and immutable objects. -
Add
ReactiveModel.asNew([dynamic seed])to create new reactive instance. -
Replace
setState.joinSingletonWithin with the bool parametersetState.joinSingleton. -
A huge Refactor of the code. I have written the code from the ground using Test Driven Design principles. Now the cod is cleaner, shorter, and more effective.
1.11.2 (2020-01-10)
- Add the static method
StatesRebuilderDebug.printInjectedModel()to debugPrint all registered model in the service locator. - Add the static method
StatesRebuilderDebug.printObservers(observable)to )debugPrint all subscribed observers to the provided observable. - Refactor watch logic to work with asynchronous tasks as well as with List, Map, Set types.
1.11.1 (2020-01-05)
- Add
onData(BuildContext, T)parameter tosetStatemethod. It is a shortcut to:onSetState(context){ if(reactiveModel.hasData){ ..... } }
1.11.0 (2020-01-05)
Inject.getfor injected streams and future will no longer throw, it will return the the current value.- If
whenConnectionStateis defined,catchErroris set true automatically. - Add
watchparameter toStateBuilderwidget and.watchallows to link the rebuild process to the variation of a set of variables.(Experimental feature). - Remove deprecated
getAsModelandhasState. - Update docs and add Dependency Injection section in the readme file.
1.10.0 (2019-12-30)
- Add
whenConnectionStatemethod to theReactiveModel. IT exhaustively switch over all the possible statuses ofconnectionState. Used mostly to return a Widget. (Pul request of ResoCoder).
1.9.0 (2019-12-28)
- Add assertion error helpful messages.
- Add
isIdlegetter to theReactiveModelas a shortcut to :connectionState == ConnectionState.none - Add
isWaitinggetter to theReactiveModelas a shortcut to :connectionState == ConnectionState.waiting - Add
onError(BuildContext, dynamic)parameter tosetStatemethod. - Add
joinSingletonToNewDataparameter tosetStatemethod. - Refactor codes to remove bugs and to use Flutter 1.12 version.
1.8.0 (2019-12-06)
1- Add the following features: (See readme fille).
onSetStateandonRebuildStateparameters to theStateBuilder.- The BuildContext is the default tag of
StateBuilder. JoinSingleton,inheritedInject,initialCustomStateStatusparameters toInjectreinjectandgetAsReactivetoInjector. 2- Remove the following parameters:(Breaking changes)tagIDparameter fromStateBuilder. before
StateBuilder( builder: (BuildContext context, String tagID){ // code } )after
StateBuilder<T>( models: [firstModel, secondModel], builder: (BuildContext context, ReactiveModel<T> model){ /// No more need for the `tagID` because the `context` is used as `tagID`. /// the model is the first instance (firstModel) in the list of the [models] parameter. /// If the parameter [models] is not provided then the model will be a new reactive instance /// See readme file for more information } )- The model parameter of the
Injector.buildermethod. before
Injector( builder: (BuildContext context, T model){ // code } )after
Injector( builder: (BuildContext context){ // no need for model parameter. It has less boilerplate. } )Injector.getAsModel,StateBuilder.viewModelandStatesRebuilder.hasStateare deprecated, and replaced byInjector.getAsReactive,StateBuilder.modelsandStatesRebuilder.hasObserversrespectively.
1.7.0 (2019-11-14)
1- Add
onSetStateparameter to thesetStatemethod to define a callback to be executed after state mutation. The callBack takes the context so you can push/pop routes, show dialogs or snackBar. (see example folder).2- Add
catchErrorparameter to thesetStatemethod to define whether to catch error while mutining the state or not.(see example folder). If an error is thrown,hasErrorgetter is true and the error can be obtained via theerrorgetter (see point 5 below).3- Add the getter
connectionStateto theModelStatesRebuilder<T>to get the asynchronous status of the state. it can beConnectionState.nonebefore executing the Future,ConnectionState.waitingwhile waiting for the Future andConnectionState.doneafter resolving the Future.4- Add the field
stateStatusto theModelStatesRebuilder<T>class. It allows defining a custom status of the state other than those defined by theconnectionStategetter.5- add the getter
hasError,hasDataanderrorto theModelStatesRebuilder<T>class.6- Change the name
blocstomodels.7- Refactor the code and fix bugs.
8- Update docs and examples.
1.6.1 (2019-10-22)
- Add
watchparameter tosetStatemethod andInject.streamconstructor.watchallows to link the rebuild process to the variation of a set of variables. - Update docs
1.6.0+1 (2019-10-18)
- Add
Injector.getAsModelmethod. When called with the context parameter, the calling widget is automatically registered as a listener. - Add
setState(Function(state))to mutate the state and update the dependent the views from the UI. - Model class have not to extend
StatesRebuilderto get reactivity. - Add the named constructor
Inject.futurewhich take a future and update dependents when future completes. - Add the named constructor
Inject.streamwhich take a steam and update dependents when stream emits a value. Injector.getorInjector.getAsModelnow throws if no registered model is found. This can be silent by setting the parametersilentto true- Injected model ara lazily instantiated. To do otherwise set the parameter
isLazyof theInjectwidget to false.
1.5.1 (2019-09-14)
- add
afterInitialBuildandafterRebuildparameters to theStateBuilder,StateWithMixinBuilderandInjectorwidgets.afterInitialBuildandafterRebuild` are callBack to be executed after the widget is mounted and after each rebuild.
1.5.0+1 (2019-09-12)
- Use
ObservableServiceandhasStateinstead ofObservableandhasObserver, because the latters are widely used and can lead to conflict
1.5.0 (2019-09-06)
- Add
hasStatesgetter to check if the StatesRebuilder object has listener. - Add
injectparameter to theInjectorwidget as an alternative to themodelsparameter. Withinjectyou can register models using interface Type. - Add
observableinterface. Any service class can implement it to notify any ViewModel to rebuild its corresponding view. - Refactor the library to make it design patterns wise and hence make it testable.
- Test the library
1.3.2 (2019-06-24)
- Add
appLifeCycleargument to Injector to track the life cycle of the app. - Refactor the code.
1.3.1 (2019-06-13)
- remove
rebuildFromStreams. - Initial release of
Streamingclass - The builder closure of the
Injectortakes (BuildContext context, T model) where T is the generic type. - Fix typos
1.3.0 (2019-06-04)
- Initial release of
rebuildFromStreamsmethod. - Initial release of
Injectorfor Dependency Injection. - deprecate blocs parameter and use viewModels instead
- StateBuilder can have many tags.
1.2.0 (2019-05-23)
- Remove
stateIDand replace it bytagparameter.tagis optional and many widgets can have the same tag. rebuildStates()when called without parameters, it rebuilds all widgets that are wrapped withStateBuilderandStateWithMixinBuilder.- Each
StateBuilderhas an automatically generated cached address. It is stored in the second parameter of thebuilder,initState,dispose, and other closures. You can call it inside the closures to rebuild that particular widget. - add
StateWithMixinBuilderwidget to account for some of the most used mixins. - Optimize the code and improve performance
1.1.0 (2019-05-13)
- Add
withTickerProviderparameter toStateBuilderwidget.
1.0.0 (2019-05-12)
- Add
BlocProviderto provide your BloCs. - You can use enums to name your
StateBuilderwidgets. rebuildStatesnow has only one positioned parameter of List<dynamic>.- If
rebuildStatesis given without parameter, it will rebuild all widgets that havestateID. - improve performance.
0.1.4
- improve performance
0.1.3
- Add getter and setter for the stateMap.
0.1.2
- Remove print statements
0.1.1
- Change readme.md of the example
0.1.0
- Initial version
-
3.1.013 Sep 2020Nothing published for this version
-
3.0.002 Sep 2020Nothing published for this version
-
2.3.119 Jul 2020Nothing published for this version
-
2.3.016 Jul 2020Nothing published for this version
-
2.2.002 Jun 2020Nothing published for this version
-
2.1.024 May 2020Nothing published for this version
-
2.0.016 May 2020Nothing published for this version
-
1.15.029 Apr 2020Nothing published for this version
-
1.14.310 Mar 2020Nothing published for this version
-
1.14.228 Feb 2020Nothing published for this version