Skip to main content

Action features

You can add features to your actions to handle common tasks. For example, instead of writing:

class LoadText extends Action { ...

You can add checkInternet to check for internet connectivity:

class LoadText extends Action {
checkInternet = { dialog: true };
...

Or even combine multiple features:

class LoadText extends Action {
checkInternet = { dialog: true };
nonReentrant = true;
retry = { on: true };
...

Most features are turned on by setting a property in your action, like the ones above. The optimistic features and the paged loading are different: your action extends a Kiss base class (like OptimisticCommand or LoadPages) instead of your own base action.

All available features​

FeaturePurposeHow to add
checkInternetChecks internet before the action; fails, with or without a dialog, if offlinecheckInternet = { dialog: true } or { dialog: false }
checkInternet (abort)Checks internet before the action; aborts silently if offlinecheckInternet = { abort: true }
unlimitedRetryCheckInternetCombines internet check + unlimited retry + non-reentrantunlimitedRetryCheckInternet = true
nonReentrantAborts if the same action is already runningnonReentrant = true
retryRetries the action on error with exponential backoffretry = { on: true }
throttleLimits action execution to at most once per throttle periodthrottle = 5000
debounceDelays execution until after a period of inactivitydebounce = 300
ignoreOldIgnores and cancels the older actions, when a newer one is dispatchedignoreOld = true
freshSkips the action if its data is still fresh (not stale)fresh = 5000
pollingAdds periodic polling to any actionpoll and createPollingAction()
sequentialRuns actions one at a time, in the order they were dispatchedsequential = true
OptimisticCommandApplies state changes optimistically, rolls back on errorExtend OptimisticCommand
OptimisticSyncOptimistic updates with coalescing; merges rapid dispatches into one syncExtend OptimisticSync
OptimisticSyncWithPushLike OptimisticSync, but with revision tracking for server pushesExtend OptimisticSyncWithPush
ServerPushHandles server-pushed updates for OptimisticSyncWithPushExtend ServerPush
LoadPagesLoads a list page by page: the next, previous or first page, or all againExtend LoadPages

Compatibility matrix​

Not all features can be combined. Kiss throws a StoreException when you dispatch an action with incompatible features. If you use the Kiss linter, its incompatible-action-features rule also reports them in your editor, before you run the code.

check
Internet
non
Reentrant
retryunlimited
Retry
Check
Internet
throttledebounceignore
Old
freshOptimistic
Command
Optimistic
Sync
Optimistic
Sync
WithPush
Server
Push
Load
Pages
pollingsequential
checkInternet—✅✅❌✅✅✅✅✅✅✅❌✅⚠️✅
nonReentrant✅—✅❌❌✅❌❌❌❌❌❌❌⚠️✅
retry✅✅—❌✅❌✅✅⚠️❌❌❌✅❌✅
unlimitedRetryCheckInternet❌❌❌—❌❌❌❌❌❌❌❌⚠️❌❌
throttle✅❌✅❌—✅✅❌❌❌❌❌⚠️⚠️✅
debounce✅✅❌❌✅—✅✅❌❌❌❌✅❌❌
ignoreOld✅❌✅❌✅✅—✅❌❌❌❌❌✅❌
fresh✅❌✅❌❌✅✅—❌❌❌❌⚠️⚠️✅
OptimisticCommand✅❌⚠️❌❌❌❌❌—❌❌❌❌❌✅
OptimisticSync✅❌❌❌❌❌❌❌❌—❌❌❌❌❌
OptimisticSyncWithPush✅❌❌❌❌❌❌❌❌❌—❌❌❌❌
ServerPush❌❌❌❌❌❌❌❌❌❌❌—❌❌❌
LoadPages✅❌✅⚠️⚠️✅❌⚠️❌❌❌❌—⚠️✅
polling⚠️⚠️❌❌⚠️❌✅⚠️❌❌❌❌⚠️—⚠️
sequential✅✅✅❌✅❌❌✅✅❌❌❌✅⚠️—

✅ Compatible (can be combined)​

❌ Incompatible (cannot be combined)​

⚠️ Can be combined, but read the caveat in the feature page​

Note checkInternet = { dialog: ... } and checkInternet = { abort: true } are two ways of using the same property, so they can't be used together.

Some features also have other requirements:

  • retry and unlimitedRetryCheckInternet need an async reducer. With a sync reducer, the dispatch fails with a StoreException.
  • Actions with debounce or sequential are always async, so they can't be dispatched with dispatchSync.

Clearing the features on logout​

The store keeps some information for these features: the fresh keys, the throttle and debounce locks, the ignoreOld keys, the polling timers, the sequential queues, the actions waiting to retry, the OptimisticSync and OptimisticSyncWithPush keys, and the revisions kept by OptimisticSyncWithPush and ServerPush.

On logout, call store.clearInternalActionProps(), so that the actions of the previous user stop, and don't affect the next user. For example, without it, loading the data of the new user could be aborted because the data of the previous user is still "fresh".

class Logout extends Action {
reduce() {
this.store.clearInternalActionProps();
return State.initialState();
}
}

It does the following:

  • Removes the fresh keys and the throttle locks.
  • Makes the debounced actions that are still waiting finish, without running their reducer.
  • Forgets the ignoreOld keys. The actions dispatched after it don't make the ones dispatched before it old.
  • Stops all polling.
  • Discards the actions waiting in sequential queues, so they don't run after the logout.
  • Stops the actions that retry (with retry or unlimitedRetryCheckInternet), so they don't keep retrying for the previous user. They are aborted, so they don't fail, and don't show errors.
  • Releases the OptimisticSync and OptimisticSyncWithPush keys. An action whose request is in flight stops when the request finishes, without sending follow-up requests.
  • Removes the revisions kept by OptimisticSyncWithPush and ServerPush. The server revisions you saved in the state are kept, and still used.

Actions that are already running still finish, and may still change the state. The nonReentrant keys are not cleared directly, since they belong to the actions that are running, but stopping a retrying action releases its key.

It's also called when the store is shut down with store.setShutDown(true).

Note it doesn't touch the app's own timers and listeners, kept in the store props. To dispose those on logout, use store.logOut({ disposeProps: true }). To end the store, when the app finishes or at the end of each test, call store.dispose(), which clears the internal action props and disposes the store props.


All features are explained in detail in the following pages: