Using rxjs withLatestFrom function
Attempting to execute the following code, which should:
- Get a list of all user chats
- get the latest message for all these chats
- Get recipient information for all these chats
-
Concatenate everything together as an array where each item is a combination of chat, last message, and recipient information.
this.msgService.getUserChatList(this.uid).do((chats) => { this.chats = []; if (!(chats.length > 0)) this.loading = false; this.getLastMessages$ = this.getLastMessagesForChats(chats); this.getRecipients$ = this.getRecipientsForChats(chats); }).switchMap( chats => Observable.from(chats) ).withLatestFrom( this.getLastMessages$, this.getRecipients$, (chat, lastMessages, recipients) => ({ chat: chat, last: lastMessages[chat['id']], recipient: recipients[chat['id']] }) ).subscribe( chats => { console.log('chats ', chats); this.chats.push(chats); this.loading = false; });
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 can't find what is going wrong ... I tried to reproduce the following JSBIN
Any idea?
source to share
The chain is built from bottom to top. This means the order is subscribe()
→ withLatestFrom
→ switchMap
→ do
.
So, at the point where it withLatestFrom
tries to subscribe to getLastMessages$
and getRecipients$
, they are undefined
, because they are only assigned after the first value propagates from the Observable that originates 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);
});
source to share