2
votes

I want to handle action in effect and based on the latest state and perform some logic. There are some examples but I have issue with receiving data in MergeMap correctly.

@ngrx/store 8.1.

@Injectable()
export class SitesEffects {

    constructor(
        private sitesService: SitesService,
        private actions$: Actions, 
        private store: Store<AppState>) {
    }


    getDataForSites$: Observable<Action> = createEffect(() =>
        this.actions$.pipe(
            ofType(LoadSites),
            map(action => action.siteIds), //siteIds is string[]
            withLatestFrom(siteIds => this.store.select(selectSites, new SiteIds(siteIds))), // items return from selector are Site[]
            mergeMap(([a,b]) => {
                // do some logic based on current state
                console.log(a);
                console.log(b);
                return of(SitesLoaded(new Sites([])));
            })

        )
    );
}

I expect that 'a' is siteIds from first map function (array of strings) and b is array of Site (Site[] from withLatestFrom) but b has an error in Visual Studio Code

Type 'Observable' must have a 'Symbol.iterator' method that returns an iterator.ts(2488)

and in console (dev tools) there is ERROR TypeError: undefined is not a function (for line mergeMap(([a,b]) =>

How all these functions should be aligned to achieve what I expect to receive in mergeMap operator?

1
withLatestFrom doesn't expect a function but just an observableWandrille
Try replace withLatestFrom with pairwiseSergey

1 Answers

1
votes

use switch / merge map instead of withLatestFrom

  switchMap(siteIds =>   this.store.select(selectSites, new SiteIds(siteIds))).pipe(first(), map(sites => [siteIds, sites])))

you will get the actual state and ids. with the first operator you complete the inner observable with the first emission(last value on your store)