Arlo Feirman
Arlo Feirman

Reputation: 95

ember.js scroll to bottom of chat box after route refresh

I'm building an ember app with email like messaging.

When a user is sending a message the container should scroll to the bottom to show the new message. Here's the action that creates the new message

  createMessage(messageParams) {
    this.get('store').createRecord('message', messageParams).save()
    .then(() => {
      return this.refresh()
    })
    .then(() => {
        let objDiv = document.getElementById("message-container");
        objDiv.scrollTop = objDiv.scrollHeight;
    })
    .catch(() => {
      this.get('flashMessages')
        .danger('There was a problem. Please try again.');
    });

As of now the chat box does not scroll to the bottom when the new message appears in the container. It works when I wrap the code in the second .then in a set timeout.

Should I put the code that scrolls the container to the bottom somewhere else in route file? I tried putting it in the afterModel hook. I also tried putting it in a .then after the model hook. When I did that, I got a blank white page when navigating to the route in the app.

model(params) {
    return Ember.RSVP.hash({
      messages: this.get('store').query('message', {
        id: params.conversation_id
      }),
      conversation: this.get('store').find('conversation', params.conversation_id)
    }).then(() => {
      let objDiv = document.getElementById("message-container");
      objDiv.scrollTop = objDiv.scrollHeight;
    });
  }

Upvotes: 1

Views: 863

Answers (1)

Ember Freak
Ember Freak

Reputation: 12872

In didTransition hook, you can run DOM code in run loop afterRender queue.

didTransition() {
  Ember.run.later('afterRender', () => {
    let objDiv = document.getElementById("message-container");
    objDiv.scrollTop = objDiv.scrollHeight;
  }, 100);
  return true;
},

DOM manipulation code should go in Component, I prefer you to write component for showing the message and make use of the component lifecycle hook methods(i.e, in your case didRender would be best fit)

Upvotes: 2

Related Questions