In my angular 10 application, I am having below NgRx effect:
loadValues$ = createEffect(() =>
this.actions$.pipe(
ofType(myActions.myActionTypes.LoadData),
map((action: myActions.loadData) => action.payload),
withLatestFrom(this._store.pipe(select(fromOtherState.getBioData))),
switchMap(([action, profile]) => {
return this.service
.getDataValues(action["candidateID"], action["hasEnrolled"], profile)
.pipe(
map((data) => new myActions.LoadSuccess(data)),
catchError((err) => of(new myActions.LoadFailed(err)))
);
})
)
);
Here, I want to get value from "fromOtherState.getBioData
" where initially it will have null value but later stage another action will fire and will populate this state. So, basically, I want to wait until it has other than a null value, and once it has desired value I want to go ahead and fire success action.
Please note that "fromOtherState.getBioData
" has an associated action that will fire parallel when I am firing the above action, as of now it always gives me the profile as null.
Please note that I tried using filter
as below: but with no luck:
loadValues$ = createEffect(() =>
this.actions$.pipe(
ofType(myActions.myActionTypes.LoadData),
map((action: myActions.loadData) => action.payload),
withLatestFrom(this._store.pipe(select(fromOtherState.getBioData))),
filter(([action, profile]) => {
return profile != null; // here I want to wait until it has value other than null
}),
switchMap(([action, profile]) => {
return this.service
.getDataValues(action["candidateID"], action["hasEnrolled"], profile)
.pipe(
map((data) => new myActions.LoadSuccess(data)),
catchError((err) => of(new myActions.LoadFailed(err)))
);
})
)
);
Try to move your selector from withLatestFrom
call to the concatMap
and try filter it there. This way the rest of the effect should wait until the getBioData
has some value. That's the sad part about the withLatestFrom
operator, it doesn't care, it just provides.
loadValues$ = createEffect(() =>
this.actions$.pipe(
ofType(myActions.myActionTypes.LoadData),
map((action: myActions.loadData) => action.payload),
concatMap((action) =>
this_store.select(fromOtherState.getBioData).pipe(
filter(profile => !!profile),
map((profile) => ({action, profile}))
)
)
switchMap(({action, profile}) => {
return this.service
.getDataValues(action["candidateID"], action["hasEnrolled"], profile)
.pipe(
map((data) => new myActions.LoadSuccess(data)),
catchError((err) => of(new myActions.LoadFailed(err)))
);
})
)
);
It's bit difficult for me to test it, but I have a feeling this approach might work.