1

I have this function that aggregates some user data from Firebase in order to build a "friend request" view. On page load, the correct number of requests show up. When I click an "Accept" button, the correct connection request gets updated which then signals to run this function again, since the user is subscribed to it. The only problem is that once all of the friend requests are accepted, the last remaining user stays in the list and won't go away, even though they have already been accepted.

Here is the function I'm using to get the requests:

getConnectionRequests(userId) {

    return this._af.database
      .object(`/social/user_connection_requests/${userId}`)

      // Switch to the joined observable
      .switchMap((connections) => {

        // Delete the properties that will throw errors when requesting
        // the convo keys
        delete connections['$key'];
        delete connections['$exists'];

        // Get an array of keys from the object returned from Firebase
        let connectionKeys = Object.keys(connections);

        // Iterate through the connection keys and remove
        // any that have already been accepted

        connectionKeys = connectionKeys.filter(connectionKey => {

          if(!connections[connectionKey].accepted) {
            return connectionKey;
          }
        })

        return Observable.combineLatest(
          connectionKeys.map((connectionKey => {

              return this._af.database.object(`/social/users/${connectionKey}`)
            }))
        );
      });
  }

And here is the relevant code in my Angular 2 view (using Ionic 2):

ionViewDidLoad() {

    // Get current user (via local storage) and get their pending requests
    this.storage.get('user').then(user => {
      this._connections.getConnectionRequests(user.id).subscribe(requests => {

        this.requests = requests;
      })

    })
  }

I feel I'm doing something wrong with my observable and that's why this issue is happening. Can anyone shed some light on this perhaps? Thanks in advance!

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Stevie Star
  • 2,331
  • 2
  • 28
  • 54
  • Have you verified that with `this.requests = requests;` an empty array is eventually received and assigned? – cartant Jan 17 '17 at 00:03
  • Actually, it's weird. I'm looking at the database and that "accepted" field will be true, but whatever the last element in the array is, it just stays there. It doesn't look like the subscribe is emitting when the map function has no keys to iterate over – Stevie Star Jan 17 '17 at 00:07

1 Answers1

2

I think you nailed it in your comment. If connectionKeys is an empty array calling Observable.combineLatest is not appropriate:

import 'rxjs/add/observable/of';

if (connectionKeys.length === 0) {
  return Observable.of([]);
}
return connectionKeyObservable.combineLatest(
  connectionKeys.map(connectionKey =>
    this._af.database.object(`/social/users/${connectionKey}`)
  )
);
cartant
  • 57,105
  • 17
  • 163
  • 197
  • I think this answer should be correct, now. I think I should finish this coffee, too. – cartant Jan 17 '17 at 00:17
  • Oh my goodness, this did the trick! What's insane is I was actually trying something similar to this, but I hadn't added that import statement haha :P But now it works like a charm with that! Thankyou so much, I've been hitting my head against a mental wall for hours <3 – Stevie Star Jan 17 '17 at 00:17