I am using ngrx/store and ngrx/effects in my angular app.
My issue is that selector in reducer returns old as well as new value after api call from feature state. Below is my code:
reducer.ts
case PortfolioActions.PortActionTypes.LOAD_SUCCESS_TRADE_NAV:
return {
...state,
navData: action.payload,
isLoadingNav: false
};
export const getNavData = createSelector(
getPortfolioFeatureState,
state => state.navData
);
In effects.ts
@Effect()
loadNav$: Observable<Action> = this.action$.pipe(
ofType<fromPortfolio.LoadTradeNAV>(fromPortfolio.PortActionTypes.LOAD_TRADE_NAV),
switchMap((action) => this.dashSvc.getNetAssetValue(action.payload.key,action.payload.currency)
.pipe(
map((data) => {
return new fromPortfolio.LoadSuccessTradeNAV(data)
})
)
)
);
In compoenent.ts
reload(){
this.portStore.dispatch(new portfolioActions.LoadTradeNAV(this.searchParam));
this.portStore.pipe(
select(fromPortfolio.getNavData),
filter(f => !!f),
takeWhile(() => this.componentActive))
.subscribe((fmtRes) => {
console.log(fmtRes) //Issue here
this.data = fmtRes;
})
}
In component when I call reload()
method, in subscribe()
I always get the old data and then later on new data after the api call is done.
My question is how can I get the store data only after the api load success is done
You can use withLatestFrom
@Effect()
loadNav$: Observable<Action> = this.action$.pipe(
ofType<fromPortfolio.LoadTradeNAV>(fromPortfolio.PortActionTypes.LOAD_TRADE_NAV),
withLatestFrom(this.store.pipe(select(selector))), // pass in your selector here in select()
switchMap((action) => this.dashSvc.getNetAssetValue(action.payload.key,action.payload.currency)
.pipe(
map((data) => {
return new fromPortfolio.LoadSuccessTradeNAV(data)
})
)
)
);
Update. I would recommend you put this code in ngOnInit() hook
ngOnInit() {
this.portStore.pipe(
select(fromPortfolio.getNavData),
filter(f => !!f),
takeWhile(() => this.componentActive))
.subscribe((fmtRes) => {
console.log(fmtRes) //Issue here
this.data = fmtRes;
})
}