Reputation: 2161
Consider the following code:
this.msgService.getUserChatList()
.do( (list) => {
this.unread = false;
console.log(list);
} )
.mergeMap( chats => Observable.from(chats) )
.mergeMap( chat => this.msgService.getLastMessage(chat['id']).map( lastMessage => this.containsUnreadMessages(lastMessage, chat['lastPresence']) ) )
.filter( state => state === true )
.subscribe( (unread) => {
this.unread = true;
console.log('result ', res);
} );
getUserChatList(): - emits an element each time one of the chat changes - an element is a raw array containing all chats meta-data - never completes
getLastMessage(): - is an Observable that never completes
In the second mergeMap I am calling the function getLastMessage(). I need to be observe this observable only until a new item is emitted by the getUserChatList() otherwise I would multiple observations on last message of the same chat.
Illustration :
getUserChatList
emits : [chatMetaA:{}, chatMetaB:{}] getLastMessage
and start to observe lastMessage of chatA and chatBgetUserChatList
containing the new version of the meta-data of the chats: [chatMetaA:{}, chatMetaB:{}]getLastMessage
and start to observe lastMessage of chatA and chatB. So we now observe twice last message of chatA and chatBAnd it will go on and on...
My question is, how could I cancel observation on getLastMessage() once a new item is emitted by getUserChatList()? I tried using switch but couldn't manage to make it work
Upvotes: 1
Views: 1256
Reputation: 2161
Solution was indeed to use switchMap:
this.msgService.getUserChatList()
.do( () => { this.unread = false } )
.switchMap(
chats => Observable.from(chats)
.mergeMap( chat => this.msgService.getLastMessage(chat['id'])
.map( lastMessage => this.containsUnreadMessages(lastMessage, chat['lastPresence']) ) )
)
.filter( state => state === true )
.subscribe( (unread) => {
this.unread = true;
console.log('result ', res);
} );
Upvotes: 2