2

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();
Dazza
  • 145
  • 1
  • 10
  • `configs` variable is declared iside the `switchMap` body. That's why `configs` in `return configs` may be undefined – kasptom Aug 17 '20 at 19:41
  • Where should I declare it? if I remove the `let configs = ` statement and instead replace it with return the result is the same. – Dazza Aug 17 '20 at 20:03
  • @Dazza move `return configs;` inside `switchMap` – Kamran Khatti Aug 17 '20 at 20:40
  • @Kamran Khatti I think it is already inside the switchmap? (excuse the terrible code formatting, I have updated it) Or, is there something painfully obvious i'm missing from your comment? – Dazza Aug 17 '20 at 20:53
  • @Dazza did you try `console.log(configs)` before `return` to make sure it has the values? – Kamran Khatti Aug 17 '20 at 20:54
  • @Dazza from what I seen in your code configs never has any value, you are iterating `itemIds.map...` where inside that map not returning anything so ultimately configs wont have anything thats why it has undefine. – Kamran Khatti Aug 17 '20 at 20:57
  • @Kamran Khatti not specifically ```console.log(configs)``` but I put a breakpoint and the array is empty, I output to console jic and its also empty. So, what should I be returning, ```db.list(pathOrRef).snapshotChanges(['child_added']);``` right? In which case there is data returned in the array!!! But its not the dataSnapshots, but a lot of Observables – Dazza Aug 17 '20 at 21:13
  • “I’ve condensed the problem down” -> `console.log(‘tomato’)` LOL – BizzyBob Aug 18 '20 at 01:53
  • I frequently choose a random selection of words to aid expected flow, this week its fruit! :-) – Dazza Aug 18 '20 at 08:41

1 Answers1

0

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

BizzyBob
  • 12,309
  • 4
  • 27
  • 51
  • Thank you, I have seen the example on stackblitz, made the modifications to my code, but I get no output. the db call appears to be at fault, if I log the preceding steps I can see the pathOrRef is populated with the path etc. I have changed the switchmap line to: ```switchMap(pathOrRef => db.list(pathOrRef).snapshotChanges(['child_added']).pipe(mapTo(pathOrRef)))``` If I subscribe to this location, i.e. ```...changes(['child_added']).subscribe()``` and log the output I get data out but then appear unable to pipe the data further because pipe doesn't exist on the subscription object. – Dazza Aug 18 '20 at 08:23
  • and just to be clear, yes, I want to take an array of itemIds and make a db call for each item to a firebase location, e.g. /AIS/USERSAVEDCONFIGS/123456/ which may contain 0...n children. I want all the children from these various locations to be returned! – Dazza Aug 18 '20 at 08:26