Side Effects
#
Architecture overviewWhen a RjObject is consumed an action observable Observable<EffectAction>
is created this rapresent the stream of effect actions dispatched from effect action creators.
The original action observable are passed into effectPipeline
which return the same contract of effect actions stream.
From action observable a dispatch observable is created according to takeEffect
and addSideEffect
options.
The actions emitted from dispatch observable are dispatched on reducer.
#
Take effectTake effect abstraction describe how your effect actions stream is handled by RocketJump.
You can configured them using the takeEffect
property in rj constructor.
You can write your own take effect function using rxjs or you can use
the standard take effects provided by RocketJump passing it a string.
Standard take effects are designed to works with standard effect action types:
'RUN'
: created byrun(...params)
trigger the effect function usingparams
as input.'CANCEL'
: created bycancel()
stop onging effect.'CELAN'
: created byclean()
also stop onging effect.
Standard take effects are:
'latest'
: (the default one) take only the last effect you run, cancel all previous pending effect.'every'
: take all effects you run, the dispatched FAILURE / SUCCESS follow the completation order of your effect (don't use the if order matter). If a CANCEL or CLEAN are emitted ALL ongoing effects are canceled.'exhaust'
: execute one run at time if an effect is pending and you emit a run it's ignored.'concatLatest'
: execute one run at time if an effect is pending and you emit a run the LAST run is buffered and then executed. This useful in "auto save" scenarios you spawn run very often but you want to avoid concurrent save but, on the other hand, you want your data update with last version.
Some standard take effects have a "group by" version, in other words the description above is true but you can decuple it into different "channels". To provide group by standard take effect you have to provide a fixed lenght list with this signature:
The first argument is the take effect name, the second is a function that extracts the key for each effect action.
Standard take effects group by are:
'groupBy'
: the group by version oflatest
.'groupByExhaust'
: the group by version oflatest
.'groupByConcatLatest'
: the group by version ofconcatLatest
.
#
Write custom take effectsAs mentioned before you can write custom take effects. To write custom take effect you should have a basic understening of how rxjs works. As expiration you can checkout how standard take effects are implemented here.
The take effect handler has this signature:
One important note to understand is that (in order to make RockeJump works) at first instance you need to FILTER which effect actions you want to handle. This because multiple effects can live in a single RjObject so you have to handle only your part.
Ok try to write a real example. Take the counter RjObject from the previous example and transform the increment / decrement action to effect action so we can execute theme after a given amount of time.
#
Add side effectsWhen using takeEffect
option the default take effect is replaced.
If instead you want to add another side effect and keep the take effect working
use addSideEffect
option, the signature and the behavior are identical to
a custom take effect.
actionMap
helper#
The In order to make your life easier RocketJump provide you a useful helper to emit standard RocketJump actions (PENDING, FAILURE, SUCCESS) from a RUN.
This function is used inside standard RocketJump take effects.
You can use this function to implement a custom take effects with the same contract of standard ones.
The actionMap
helper has this signature:
This helper call the effect using the effect caller and emit standard actions with given prefix.
For example if we want to implement a take effect that use the concatMap
operator
we can write:
#
Effect pipelineSometimes you need to apply a transfromation to effect action streams before
it is consume from take effects.
To do this you can use the effectPipeline
option on rj constructor.
For example you need to debounce your effect before execute them: