Richard
Richard

Reputation: 8935

Javascript Observable infinite loop

I am building a Chat application, and when a new message gets added to a list, I need to update the chat item that contains the message list.

I am using AngularFire2, and have an Observable. This Observable works perfectly to dynamically maintain a list as expected.

I do however, have a conundrum. When the list changes I need to perform an update which in turn causes the list to change, and so on resulting in an infinite loop.

code:

The following is the Observable

findMessages(chatItem: any): Observable<any[]> {
    return this.af.database.list('/message/', {
        query: {
            orderByChild: 'negativtimestamp'
        }
    }).map(items => {
        const filtered = items.filter(
            item => ((item.memberId1 === chatItem.memberId1 && item.memberId2 === chatItem.memberId2)
                || (item.memberId1 === chatItem.memberId2 && item.memberId2 === chatItem.memberId1))
        );
        return filtered;
    });
}

I populate a list with this Observable

findAllMessages(chatItem: any): Promise<any> {
    return this.firebaseDataService.findMessages(chatItem).forEach(firebaseItems => {
        chatItem.lastMsg_text = 'updated value';
        this.firebaseDataService.updateChat(chatItem);
    });
}

As you can see, I update the chatItem

updateChat(chatItem: any): firebase.Promise<void> {
    return this.findChat(chatItem).forEach((chatItems: any[]) => {
        if (chatItems.length > 0) {
            for (let i: number = 0; i < chatItems.length; i++) {
                return this.af.database.object('/chat/' + chatItems[i].$key).update({
                    timestamp: chatItem.timestamp,
                    negativtimestamp: chatItem.negativtimestamp,
                    lastMsg_text: chatItem.lastMsg_text,
                    lastMsg_read1: chatItem.lastMsg_read1,
                    lastMsg_read2: chatItem.lastMsg_read2
                });
            }
        } else {
            this.createChatFromItem(chatItem);
        }
    });
}

Question

My confusion here, is that I am updating the chats and not the messages, so why is the messages Observable being triggered? Is there a way to achieve this avoiding the infinite loop?

Any help appreciated.

Upvotes: 0

Views: 586

Answers (1)

PatrickS
PatrickS

Reputation: 9572

Seems like you could handle all of this in a much simpler way... The way you mixed Promises & Observables feels a bit convoluted.

Have you looked into Subject?

To put it very simply, you could have a Subject "publishing" any changes in your chat application by calling

yourSubject.next(newChatMessage)

From then on, subscribing to that Subject from any parts of your application, you'd be able to make any updates necessary.

Then if you want to dig deeper into the subject of state management, you could have a look at the following:

RxJS powered state management for Angular applications, inspired by Redux

Upvotes: 1

Related Questions