Manuel RODRIGUEZ
Manuel RODRIGUEZ

Reputation: 2161

Use of rxjs withLatestFrom function

Trying to execute the following code that is supposed to :

Additional functions

getLastMessagesForChats(chats: any): Observable<any[]> {
    let lastMessages$ = [];
    for (let chat of chats) {
      let obs = this.msgService.getLastMessage(chat.id)
        .map( last => ({chat: chat.id, last: last}) );
      lastMessages$[chat.id] = obs;
    }
    return Observable.from(lastMessages$).merge().toArray();
  }

  getRecipientsForChats(chats: any): Observable<any[]> {
    let recipients$ = [];
    for (let chat of chats) {
      let obs = this.userService.getUserPublicInfo(chat.recipient)
        .map( recipient => ({chat: chat.id, recipient: recipient}) );
      recipients$[chat.id] = obs;
    }
    return Observable.from(recipients$).merge().toArray();
  }

I am getting the following error

Uncaught (in promise): TypeError: Cannot read property 'subscribe' of undefined
    TypeError: Cannot read property 'subscribe' of undefined

I cannot find what is going wrong... I tried to reproduce in the following JSBIN

Any idea?

Upvotes: 4

Views: 5216

Answers (1)

martin
martin

Reputation: 96891

The chain is constructed bottom up. This means that the order is subscribe() -> withLatestFrom -> switchMap -> do.

So at the point where withLatestFrom tries to subscribe to getLastMessages$ and getRecipients$ they are undefined because they are assigned only after the first value is propagated from the source Observable which happens in do().

Edit:

// Execution
getLastMessages$ = Rx.Observable.of(1);
getRecipients$ = Rx.Observable.of(2);
chats = [];

getUserChatList('uC')
  .do( (chats) => {
    getLastMessages$ = getLastMessagesForChats(chats);
    getRecipients$ = getRecipientsForChats(chats);
  } )
  .switchMap( chats => Rx.Observable.from(chats) )
  .withLatestFrom(
    getLastMessages$,
    getRecipients$,
    (chat, lastMessages, recipients) => ({
        chat: chat,
        last: lastMessages[chat['id']],
        recipient: recipients[chat['id']]
      }))
  .subscribe( c => {
    console.log('chats ', c);
    chats.push(c);
  });

http://jsbin.com/sulatar/3/edit?js,console

Upvotes: 3

Related Questions