Benjamin Such Benjamin Such - 1 month ago 5
AngularJS Question

How to get async html attribut

I have a list of items retreived by an async call and the list is shown with the help of

. Since the div container of that list has a fixed height (400px) I want the scrollbar to be at the bottom. And for doing so I need the
. But the
is not the final height but the initial height.



<!-- Height of "chatroom" is "400px" -->
<div class="chatroom">
<!-- Height of "messages" after all messages have been loaded is "4468px" -->
<div class="messages" ng-repeat="message in chat.messages">
<chat-message data="message"></chat-message>


// [...]
compile: function(element) {

return function(scope, element, attrs, PpChatController) {
var messagesDiv;
// My idea was to wait until the messages have been loaded...
PpChatController.messages.$loaded(function() {
// ...and then recompile the messages div container
messagesDiv = $compile(element.children()[0])(scope);
// Unfortunately this doesn't work. "messagesDiv[0].scrollHeight" still has its initial height of "400px"

Can someone explain what I missed here?

As required here is a plunk of it


You can get the scrollHeight of the div after the DOM is updated by doing it in the following way.

The below directive sets up a watch on the array i.e. a collection, and uses the $timeout service to wait for the DOM to be updated and then it scrolls to the bottom of the div.

chatDirective.$inject = ['$timeout'];

function chatDirective($timeout) {
  return {
    require: 'chat',
    scope: {
      messages: '='
    templateUrl: 'partials/chat.tpl.html',
    bindToController: true,
    controllerAs: 'chat',
    controller: ChatController,
    link: function(scope, element, attrs, ChatController) {
      scope.$watchCollection(function () {
      }, function (newValue, oldValue) {
        if (newValue.length) {
          $timeout(function () {
            var chatBox = document.getElementsByClassName('chat')[0];
            console.log(element.children(), chatBox.scrollHeight);
            chatBox.scrollTop = chatBox.scrollHeight;

The updated plunker is here.

Also in your Controller you have written as,

  var Controller = this;

  this.messages = [];

It's better to write in this way, here vm stands for ViewModel

AppController.$inject = ['$timeout'];

function AppController($timeout) {
  var vm = this;

  vm.messages = [];

    function() {
      for (var i = 0; i < 100; i++) {
          message: getRandomString(),
          created: new Date()