Reputation: 1830
I am creating a chat application. On changing a chat window, I want the scrollbar to navigate to the bottom in order to view the most recent messages immediately. My code to do this:
ngAfterViewInit(): void {
this.updateMessageExchange.subscribe((interlocutor: MessageExchange) => {
this.activeChatExchange = interlocutor; // this triggers a view change in the html
setTimeout(() => {
console.log('sleep');
this.scrollToBottom();
}, 100);
});
}
private scrollToBottom(): void {
this.chatBoard.nativeElement.scrollTop = this.chatBoard.nativeElement.scrollHeight;
}
corresponding relevant html:
<ng-container *ngFor="let message of activeChatExchange.messages">
This works, but I had to introduce a sleep to make it work. Without the sleep, the update of scrollTop
happens too quick and the window on the next page will not be updated to scroll to the bottom. This has nothing to do with the value of scrollHeight
either. If I set a really high static number like 999999 it will still not scroll to the bottom.
So the issue is that this solution is not very good. A too high number for the sleep puts an artificial delay in my application, making it appear sluggish and too low a number may cause slow browsers to not be scrolled down after loading.
I would like to subscribe to when the DOM event change is finished, but only for a change in activeChatExchange
. How should I approach this?
Upvotes: 1
Views: 1567
Reputation: 1830
I think I found the solution, with help from Angular - Wait for ngFor to update DOM
I'm not entirely sure if this qualifies as a proper solution, but setting the sleep to 0 apparently works because the function timeout starts counting after rendering, which is what I want.
So my code becomes
this.updateMessageExchange.subscribe((interlocutor: MessageExchange) => {
this.activeChatExchange = interlocutor;
setTimeout(() => {
this.scrollToBottom();
}, 0);
});
Upvotes: 4