1

I working on trying to clean up a complex chain of observables. I am looping through an array of items returned from my akita store and performing actions on each item and then storing them if they have been modified. I currently have a working solution but I was wondering if there was a cleaner or more direct way to handle this chain.

I have tried looking up some examples of looping through an array with observables but haven't found anything complex or trying to do something similar to me.

The example bellow works, it just doesn't seem like its best practice of observables and operators.

    public fetchAdditionalSavedSearchDetails(): Observable<any> {
        return this.savedSearchQuery.selectAll().pipe(
            // Debounce to prevent from calling to frequently
            debounceTime(500),
            switchMap((savedSearches) => {
                return forkJoin(
                    // Loop through saved searches and return observable
                    savedSearches.map((savedSearch) => of(savedSearch).pipe(
                        // default modified to false
                        switchMap((savedSearch) => of([savedSearch, false])),
                        switchMap(([savedSearch, modified]) => {
                            const search: ISavedSearch = savedSearch as ISavedSearch;
                            if (search.searchTotalCount === undefined) {
                                // todo: implement fetching search count
                                return of([{ ...search, searchTotalCount: 0 }, true]);
                            }
                            return of([savedSearch, modified]);
                        }),
                        switchMap(([savedSearch, modified]) => {
                            const search: ISavedSearch = savedSearch as ISavedSearch;
                            if (search.scheduledExports === undefined) {
                                return this.scheduledExportService.fetchAllScheduledExportsForSavedSearch(search).pipe(
                                    mergeMap((scheduledExports) => of([{ ...search, scheduledExports }, true]))
                                );
                            }
                            return of([savedSearch, modified]);
                        })
                    ))
                ).pipe(tap((response) => {
                    // Prevent akita store from triggering changes on each update of entity
                    applyTransaction(() => {
                        response.forEach((searchResp: Array<ISavedSearch | boolean>) => {
                            const search: ISavedSearch = searchResp[0] as ISavedSearch;
                            const modified: boolean = searchResp[1] as boolean;
                            if (modified) {
                                this.savedSearchStore.update(search.id, search);
                            }
                        });
                    });
                }));
            })
        );
    }
Reyco
  • 11
  • 1
  • minor: you have a couple of `switchMap(...=>of([ 1, 2 ]))` (or mergeMap), which is equal to simple `map(x=>[ 1, 2 ])` – kos Mar 29 '19 at 21:20

1 Answers1

0

I haven't read through all the code, but from what you are asking, I think the following change might help you.

You can change this code:

switchMap((savedSearches) => {
    return forkJoin(
        // Loop through saved searches and return observable
        savedSearches.map((savedSearch) => of(savedSearch).pipe(

to this:

switchMap(savedSearches => savedSearches),
// Continue with your next operator here

That should make it so that:

  • Coming in: One event with an array of 5 items.
  • Going out: 5 event with a single value.

In general it is a sign you are doing something wrong when you have to do pipes inside other pipes (There are exceptions to this).

SnorreDan
  • 2,740
  • 1
  • 14
  • 17
  • 1
    `switchMap` kinda has a built in `from`, so `switchMap(x=>x)` should do – kos Mar 29 '19 at 21:17
  • I guess, we're all here to learn. And reading answers given by others helps us discover something new, see things at different perspective (well, you saw that martin's `multicast...` magic, sheesh!) – kos Mar 30 '19 at 20:40