[IONIC 4] Scroll to bottom on chat page

can you upload full code snippet?

Sure, HTML first and then TS file. Some text are French but don’t mind it :wink:

<ion-header>
  <ion-toolbar mode="ios">
    <ion-buttons slot="start">
      <ion-back-button [routerLink]="'/tabs/ma-messagerie'" defaultHref="ma-messagerie"></ion-back-button>
    </ion-buttons>
    <ion-title *ngIf="contact">{{contact.prenom}} {{contact.nom}}</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content #scrollElement padding [scrollEvents]="true">
  <div class="messages-container" *ngIf="connectedUser">
    <ol class="messages">
      <li *ngFor="let msg of messages" [class.mine]="connectedUser.id === msg.userFrom.id">
        <span class="msg-content">{{msg.content}}</span>
      </li>
    </ol>
  </div>
</ion-content>
<ion-footer>
  <ion-item>
    <ion-textarea
            rows="1"
            placeholder="Envoyer un message"
            maxlength="500"
            autocapitalize="on"
            autosize
            [(ngModel)]="newMessage"
    >
    </ion-textarea>
    <ion-buttons slot="end">
      <ion-button slot="icon-only" (click)="sendMessage()">
        <ion-icon name="send"></ion-icon>
      </ion-button>
    </ion-buttons>
  </ion-item>
</ion-footer>

import {Component, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {RestApiService} from '../services/rest-api.service';
import {AlertService} from '../services/alert.service';
import {IonContent} from '@ionic/angular';

@Component({
  selector: 'app-chat',
  templateUrl: './chat.page.html',
  styleUrls: ['./chat.page.scss'],
})
export class ChatPage implements OnInit {
  contactId = null;
  contact = null;
  connectedUser = null;
  messages = [];
  newMessage: any = '';
  @ViewChild('scrollElement') content: IonContent;

  constructor(private activatedRoute: ActivatedRoute, private api: RestApiService, private alert: AlertService) {
    this.contactId = this.activatedRoute.snapshot.paramMap.get('contactId');
  }

  ngOnInit() {
    this.getContactInfos();
    this.getUser();
    this.getMessages();
  }

  getContactInfos() {
    this.api.get('user/getInfosUser/' + this.contactId).subscribe(res => {
      this.contact = res;
    }, err => {
      this.alert.present();
    });
  }

  getUser() {
    this.api.get('user/user').subscribe(res => {
      this.connectedUser = res;
    }, err => {
      this.alert.present();
    });
  }

  getMessages() {
    this.api.get('conversation/getMessages/' + this.contactId).subscribe(res => {
      this.messages = res;
      setTimeout(() => {
        this.updateScroll();
      }, 500);

    }, err => {
      this.alert.present();
    });
  }

  sendMessage() {
    const data = {
      contactId: this.contactId,
      content: this.newMessage
    };

    this.api.post('message/create', data).subscribe(res => {
      if (res['result'] === 'success') {
        this.newMessage = '';
        this.messages = [];
        this.ngOnInit();
      } else {
        this.alert.present('Echec lors de l\'envoi de votre message.');
      }
    }, err => {
      this.alert.present('Echec lors de l\'envoi de votre message.');
    });
  }

  updateScroll() {
    console.log('scrollToBottom');
    this.content.scrollToBottom();
  }

}

I also tried to do it in ionViewDidEnter instead of ngOnInit but the result is the same, no scrolling :confused:
I really don’t know what I’m missing, it shouldn’t be that hard after all :face_with_monocle:

EDIT: Even if I call updateScroll() when clicking on a button or when focusing my text input, it gets called (I logged it), but it doesn’t want to scroll to bottom.

Any ideas from anyone ? Struggling on this

I also needed to set programatically the scroll to the bottom in my app, after some trouble I got it working, I’ve seen your code and I’m not really sure what’s wrong/missing, I’ll share everything I’ve done to get it working, mby it could help you

in hml
<ion-content [scrollEvents]=“true”>

getting IonContent with:
import { IonContent } from ‘@ionic/angular’;

in ts
image

creating scroll effect with:
this.content.scrollToBottom(300);

ATTEMPT TO FIX 1 - Try to do it like me, dont ID your content to scrollElement and instead do it with the IonContent

ATTEMPT TO FIX 2 - Yknow, in my app I wanted to scroll to the bottom of the page when the user selected an input field on the login page, the input field happened to be inside an ion-item, and what that lead to was an odd bug, when I clicked on an input for the first time the keyboard opens and the click event isn’t triggered, only on the 2º click it got triggered, so clicking on the input once the keyboard is opened, awkward I know, so I rathered checking for another event, when the keyboard opens, because when he first clicks on the input the keyboard opens, so I managed to get a triggered event pretty much in the same context I needed, what do I mean with all this, maybe you’re not really ever running the scroll event? TL:DR: are you sure the scroll is being executed?

Hi guys !

I tried your fix 1 @SanduCuragau, but unfortunately, it doesn’t scroll.

<ion-content [scrollEvents]="true">
@ViewChild(IonContent) content: IonContent;
updateScroll() {
    console.log('should scroll here');
    this.content.scrollToBottom(300);
}

‘Should scroll here’ is logged, I can see it in the Chrome dev tools, but there’s still no scroll on my page.
Maybe I don’t call it at the right time, but even if I call it from a button click (when my messages are already on my chat page), it doesn’t scroll to the bottom…

For the 2nd attempt to fix, I see hat you’re talking about, but I don’t think this is it here, cause my console.log('should scroll here') is always executed when I need it. Problem is, it doesn’t scroll and I have no errors about it…

Hope we’ll make it !

Hm, try 1 thing, add like random buttons or whatever out of your screen and create a legit need to scroll through the whole page and try to execute updateScroll() cuz I think what’s happening here is that in my case I used it to scroll legit the page itself, I didn’t get to try to understand your code but I think you’re trying to scroll something else, just the chat, the page is never scrolled since there’s no need to scroll it since everything fits tight, if in my login page I have keyboard opened and it creates a need to scroll the page itself, if I execute the scroll it goes to the bottom, but when keyboard isn’t opened and everything on the page fits perfectly, I can execute scroll as much as I want, page won’t move, why would it? yknow what I mean?

I see what you mean but actually, my messages don’t fit my page because there is too much. I have something like 30 messages to test this functionality, so when I get on my chat page, I only see the 10 first messages, and I’d prefer to see the last 10 ones, just like Facebook Messenger or any other chat app.
I’ll try to upload you a video so you can see how my chat page is made :wink:

EDIT: Okaaaaay I may found something with your tip !
I added, like you said, much random buttons at the end of the page, and then it scrolled well. Maybe it’s related to my <ol></ol> and <li></li> elements ? Or the div that contains my messages ?
What do you think ?

Yeah that’s the problem, your page normally fits well and you can’t scroll down on it, you wanna scroll down on the messages, to be honest I have no idea what to do to fix it

1- what if instead of subscribing to the IonContent you would subscribe to the component holding all the messages?

2- when you added all those elements at the bottom and page extended and you could finally scroll, tell me, it scrolled the page down, but did it also affect the messages?

1- I think this solution will work, I just have to search how to do it cause I have no idea :smile:

2- It didn’t affect the messages, they were still there and well shown

EDIT:
1- Not sure if this solution will work after all, because I think scrollToBottom is an IonContent function :thinking:

remember how you used to ID ur ion-content?

image

and the ID went here

try to do the same but with the div, if that doesnt work try the ol and if that doesnt work either try the li xD

this.content.scrollToBottom() is not a function :frowning:

I don’t know how I can do it…

that logs in the console?

Yes !

feels freaking bad, it is just as you said, it’s a content function and you can’t use it for components, try looking for other way to scroll to the bottom, i just found this one

https://stackoverflow.com/questions/18614301/keep-overflow-div-scrolled-to-bottom-unless-user-scrolls-up/44051405#44051405

check the code pen, apparently it works fine and it is applied to a div

Oh god I managed to find the solution. It was CSS related ! :astonished:

Just changed this:

.messages-container {
    height: 100%;
    width: 100%;
    position: relative;
    display: flex;
    overflow: hidden;
    margin: 0 auto;
}

To:

.messages-container {
    min-height: 100%;
    width: 100%;
    position: relative;
    display: flex;
    overflow: hidden;
    margin: 0 auto;
}
1 Like

And you’re using the scroll to bottom on content?

Yes, on the ion-content element !

Now I have a problem with my keyboard which is above the last chat messages (it doesn’t scroll enough), but I’ll check it later I think, unless you already had this problem and know what to do, I won’t bother you more !

Thanks a lot for your help, that really helped me !

1 Like

Hmm I faced something similar IONIC 4 click event bug, I have to double click?

Always man

Thanks, I’ll check it and if I don’t find the solution, it’s ok, I don’t need it right now, I have some time left on this issue

another question, how did you do a refresh on other user’s end? when you send message? as I used this method, and the other user are not getting the page unless they reload the page manually