How to merge results in angular fire from array from references

Viewed 176

I have a array of references retrieved from angularfire

this.userIds$ = this.users$.switchMap(email =>
  db.list('/USERS/', ref => {
    let temp = email ? ref.orderByChild('EMAIL').startAt(email).endAt(email + "\uf8ff") : ref
    console.log('carrot');
    return temp;
  }
  ).snapshotChanges()
);

I am trying to return this data as one observable, but although I can see the path populating the correct database references, when is all said and done my configs array just contains a couple of thousand 'undefined' entries what am I doing wrong? I have tried various things but the result is always the same, so ive condensed the problem down into the below and hoping for some help

//Subscribe to the output of user ids, when we get a hit (delivered as an array of Observable DataSnapshot) loop through and subscribe to all the children of this location
    this.userConfigs$ = this.userIds$.pipe(
      switchMap(itemIds => {
        let configs = itemIds.map(itemId => {
          let pathOrRef = '/AIS/USERSAVEDCONFIGS/' + itemId.key;
          console.log('tomato');
          db.list(pathOrRef).snapshotChanges(['child_added']);
        });
        return configs;
      })
    );

and I kick the whole thing off with

this.userConfigs$.subscribe();
1 Answers

The function you pass to switchMap should return an Observable, you are returning an array. I would think TypeScript compiler should warn you about that.

If I understand correctly, you want to take an array of itemIds, make a database call for each item, and return an array of the pathOrRef.

If so, something like this should work:

  1. use from() to emit your userIds one at a time
  2. use map() to transform the item to a pathOrRef
  3. use switchMap() to make your database call
  4. use mapTo() to return the pathOrRef
  5. use toArray() to put emissions into an array
this.userConfigs$ = this.userIds$.pipe(
  switchMap(itemIds => from(itemIds).pipe(
    map(itemId => `/AIS/USERSAVEDCONFIGS/${itemId}`),
    switchMap(pathOrRef => fakeDatabaseCall(pathOrRef).pipe(mapTo(pathOrRef)))
  )),
  toArray()
);

Here's a sample on StackBlitz

Related