Executing code after dispatch is completed while using ngrx
Solution 1
Quick answer : You can't.
As you said, dispatch
is asynchronous.
What you should do is use @ngrx/effects. It's nearly the same as using addAuthorAction
except that instead of calling a function, you "catch" the dispatched actions and do something just after they've been applied by the reducers.
So what I do in general, is that I divide my actions in 3, for example :
-
FETCH_USER
-
FETCH_USER_SUCCESS
-
FETCH_USER_ERROR
-
FETCH_USER
is just used to toggle a boolean so I can display a spinner while fetching the user -
I catch this action from an effect and make an http request to fetch the user
-
If the http response is OK and I have the info I'm looking for, I dispatch from the effect
FETCH_USER_SUCCESS
with the response as payload, otherwise I dispatchFETCH_USER_ERROR
and I toggle the boolean to false (so we can try to fetch him again for example).
So in your example, if you want to console.log
something AFTER the FETCH_USER_SUCCESS, just use another effect to catch the FETCH_USER_SUCCESS and do what you want to here.
Solution 2
Tested with
"@ngrx/core": "^1.2.0",
"@ngrx/effects": "^7.4.0",
"@ngrx/router-store": "^7.4.0",
"@ngrx/store": "^7.4.0",
"@ngrx/store-devtools": "^7.4.0",
This will also work:
import { ofType, Actions } from '@ngrx/effects';
// Constructor
constructor(
private _actions$: Actions,
private _store: Store<any>,
) { }
// YOUR METHOD
this._store.dispatch(<ACTION>);
this._actions$.pipe(ofType(<ACTION_NAME>)).subscribe((data: any) => {
console.log(data); // returned state data
})
Solution 3
With ngrx you can listen to actions like this:
constructor(private actionsSubject$: ActionsSubject, private store: Store<AppState>) {}
ngOnInit() {
this.actionsSubject$.pipe(
takeUntil(this.unsubscribe$), // optional
filter((action) => action.type === SimsActionTypes.SimEditedSuccess)
).subscribe(({payload}) => {
console.log(payload)
)
}
When you dispatch FIRST_ACTION use an effect to make the HTTP request. In the effect, when you have the response back, fire off a SECOND_ACTION with the response as the payload. Then just listen for SECOND_ACTION in your controller .ts file
refactor
Areas of my interest --> HTML / CSS / Javascript --> React , Angular --> C# / Node.js --> Oracle , SQL Server --> MongoDB --> Docker , k8s --> aws
Updated on July 22, 2022Comments
-
refactor almost 2 years
In my sample Angular 2 application , I am using ngrx/store and ngrx/effects for state management.
Below is one of the function in a component to add a new item.
addAuthor() { this.store.dispatch(addAuthorAction(this.fg.value)); console.log('2') }
In the above code
this.store.dispatch(addAuthorAction(this.fg.value));
takes care of making an AJAX call to server and adding a new author to database, which is working fine.And because
this.store.dispatch(addAuthorAction(this.fg.value));
is anasync
action ,console.log("2")
statement gets executed even before the AJAX call is completed.My question is , what needs to be modified so that console.log gets executed after store.dispatch is done.
-
Aluan Haddad about 7 yearsI do not know, not having used it, but the source code in github.com/ngrx/store/blob/master/src/store.ts gives me the impression that you need to subscribe to the store itself. Like
this.store.subscribe(() => console.log(2))
, as the dispatch call does not return a value. -
Smaillns almost 3 yearsThe best way to do so is to use the state, add some properties like (isLoading, error, success) and add a selector. if you want I can bring more samples
-
-
Karan Patokar almost 4 yearsYou are totally right in this case. But what If say I want to route to a different component instead of just loving something in console. How do I do that?
-
maxime1992 almost 4 yearsNgrx used to provide actions for the router (go, back, etc). They do not anymore but they've got a recipe where they explain to do it yourself so it's really easy to setup. Look here: github.com/ngrx/platform/blob/… and then you just dispatch a Go action to where you want to navigate :)
-
Karan Patokar almost 4 yearsThanks. That is indeed a great solution.
-
Antti Tanskanen over 2 yearsI don't get why this has got -1.
-
Silvio Langereis over 2 years@AnttiTanskanen In ngrx, dispatch returns void, not an observable, hence you cannot subscribe to it.
-
Antti Tanskanen over 2 years@SilvioLangereis ok, I see. In ngxs it returns observable.