Reputation: 426
Though I have spent a lot of time in the AngularJS world and a bit in the Angular world, I'm fairly new to RXJS and NGRX and have been running into some issues. My NGRX setup is similar to the way the NGRX team recommends setting it up in their example project (https://stackblitz.com/run).
The Situation
I have an entity called 'site' which I have stored in my NGRX store. When I get to a specific screen I am trying to get the 'Id' of 'Site' from my store and then dispatch a new NGRX action using the Site Id as the parameter. To do this, I am trying to subscribe to a site$ observable and dispatch the action within that subscription.
import { Component, OnInit } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';
import * as fromSite from '../../site/store/reducers/site.reducer';
import * as SiteActions from '../../site/store/actions/site.actions';
import { Site } from '../../site/site';
@Component({
selector: 'app-category-grouping',
templateUrl: './category-grouping.component.html',
styleUrls: ['./category-grouping.component.scss']
})
export class CategoryGroupingComponent implements OnInit {
site$: Observable<any>;
site: Site;
constructor(private store: Store<fromSite.State>) {
this.site$ = this.store.pipe(select(fromSite.getSite));
this.site$.subscribe(data => {
if (data && data.site) {
this.store.dispatch(new SiteActions.GetGroupsAndCategories(data.site.id));
this.site = data.site;
}
});
}
ngOnInit() {}
}
The Problem
Dispatching the action within the subscription (once I have the site Id) breaks everything! The browser completely freezes and has to be force quit. I don't receive any console errors, but I must be doing something very wrong.
The Question
What is the correct way of doing this? Should I not be doing it within a subscribe? Is there a better way to get a value from the store and then use that value to dispatch another action?
Upvotes: 0
Views: 2047
Reputation: 3649
Look like you have recursion: dispatch GetGroupsAndCategories
action change output of select(fromSite.getSite)
, site$
emit new value.
If you want to get some data before navigate to screen - use resolver
@Injectable()
export class SomethingResolver implements Resolve<Action> {
constructor (
private store: Store<State>,
private action$: Actions
) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Action> {
this.store.dispatch({ type: Actions.FETCH_SOMETHING });
const responseOK = this.action$.ofType(Actions.RESPONSE_OK);
const responseError = this.action$.ofType(Actions.RESPONSE_ERROR)
.do(() => this.router.navigate(['']);
return Observable.race(responseOk, responseError).take(1);
}
}
Upvotes: 3