DISPATCHED
, SUCCESSFUL
, ERRORED
, CANCELED
, think of it as a finite state machine.ActionContext
, that has 2 properties:DISPATCHED
status and invokes the appropriate handlers for this action. After all processing for the action has completed it generates a new ActionContext
with the following status
value:dispatch
method is then triggered after the action is handled "successfully" and, in response to this observable, you are able to do the actions you wanted to do on completion of the action.GetNovels
handler throws an error, for example:ActionContext
will be created:CANCELED
status? Only asynchronous actions can be canceled, this means that the new action was dispatched before the previous action handler finished doing some asynchronous job. Canceling actions can be achieved by providing options to the @Action
decorator:GetNovels
action on click:switchMap
. If we didn't use NGXS - the code would look as follows:GetNovels
and GetDetectives
actions separately like this:GetNovels
would be dispatched before GetDetectives
. This is true due to the synchronous nature of the dispatch, but their action handlers are asynchronous so you can't be sure which HTTP response would return first. In this example we dispatch the GetNovels
action before GetDetectives
, but if the call to fetch novels takes longer then the novels
property will be set after detectives
. The store.dispatch
function returns an observable that can be used to respond to the completion of each of these actions.store.dispatch
function that will fire only when both actions have completed. The below diagram demonstrates how asynchronous actions are handled under the hood:onError
observable callback and neither the onNext
or onComplete
callbacks would be called.Observable
or Promise
from your @Action
method that represents that asynchronous work (and completion). The completion of the action will then be bound to the completion of the asynchronous work. If you use the async/await
javascript syntax then NGXS will know about the completion because an async
method returns the Promise
for you. If you return an Observable
NGXS will subscribe to the observable for you and bind the action's completion lifecycle event to the completion of the Observable
.@Action
method. Note that in the case of an Observable
you would have to .subscribe(...)
or call .toPromise()
to ensure that your observable runs.Observable
version:Promise
version:GetNovels
action to wait for the detectives to load then we would have the following code:GetDetectives
action would be dispatched just before the GetNovels
action completes. The GetDetectives
action is just a "fire and forget" as far as the GetNovels
action is concerned. To be clear, NGXS will wait for a response from the getNovels
service call, then it will populate a new state with the returned novels, then it will dispatch the new GetDetectives
action (which kicks off another asynchronous request), and then GetNovels
would move into its' success state (without waiting for the completion of the GetDetectives
action):GetNovels
action to wait for the GetDetectives
action to complete, you will have to use mergeMap
operator (or any operator that maps to the inner Observable
, like concatMap
, switchMap
, exhaustMap
) so that the Observable
returned by the @Action
method has bound its completion to the inner action's completion:async/await
syntax. The same method would be as follows:await
keyword here would cause this to be "fire and forget" again.DISPATCHED
. Next, NGXS looks for handlers that listen to this action, if there are any — NGXS invokes them and processes the return value and errors. If the handler has done some work and has not thrown an error, the status of the action changes to SUCCESSFUL
. If something went wrong while processing the action (for example, if the server returned an error) then the status of the action changes to ERRORED
. And if an action handler is marked as cancelUncompleted
and a new action has arrived before the old one was processed then NGXS interrupts the processing of the first action and sets the action status to CANCELED
.