JeffMinsungKim
JeffMinsungKim

Reputation: 2150

RxJS: forkJoin seems not working

I'm currently using combineLatest() method to get all my friends and make it as a list. However, it produces an ordering issue when I try to remove an item from the beginning. (View does not render correctly) Therefore, I'd like to switch from combineLatest() to forkJoin() to get all the friends at once.

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';

friends$: Observable<User[]>;

getMyFriendList() {
  this.friends$ = this.userService.getMyFriendsId().switchMap(friendKeys => {
    return Observable.forkJoin(friendKeys.map(user => this.userService.getFriends(user.key)));
  });
}

But nothing happens when I call forkJoin(). What am I doing wrong here?

getMyFriendsId() {
  let friendRef = this.getFriendRef(this.currentUserId);
  this.friends$ = friendRef.snapshotChanges().map(actions => {
    return actions.map(a => ({ key: a.payload.doc.id, ...a.payload.doc.data()}));
  });
  return this.friends$;
}

getFriends(uid: string) {
  return this.getUsersRef(uid).valueChanges();
}

EDIT

getMyFriendsId() updates a new data when a logged in user remove another user in the friend list.

<ion-list>
    <ion-list-header>Friends <span class="total-friends"></span></ion-list-header>
      <ion-item-sliding *ngFor="let user of friends$ | async">
        <ion-item *ngIf="user" (click)="viewUserProfile(user)">
          <ion-avatar (click)="showOriginalAvatarImage()" item-start>
            <img-loader [src]="user.thumbnailURL" [spinner]="true"></img-loader>
          </ion-avatar>
          <h2>{{user.displayName}}</h2>
          <p>{{user.statusMessage}}</p>
        </ion-item>
             ...
<ion-list>

Lifecycle event

ionViewWillEnter() {
  // Runs when the page is about to enter and become the active page.;
  this.getMyFriendList();
}

Upvotes: 1

Views: 1867

Answers (1)

CozyAzure
CozyAzure

Reputation: 8478

.forkJoin() combines all the observables, and will only emit the values if all observables are COMPLETED. The reason your code doesn't work is because a you are using valueChanges(), and it is a type of event that will never complete -- they are forever listening to the changes of the value!

If you really want to use .forkJoin (or to prove the point), add a take(1) into your valueChanges:

getFriends(uid: string) {
  return this.getUsersRef(uid).valueChanges().take(1);
}

The above code will work because it forcefully completes the observable with take(), but obviously will defeat the purpose because your code will only work once. Conclusion is if you want to keep on observing for a change of a particular value, and combine it with another observable, yes, use combineLatest()

Upvotes: 2

Related Questions