General Electric
General Electric

Reputation: 1236

ng-repeat not updating when pushing new item

I'm trying to update a view with ng-repeat after pushing a new item to the list, however ng-repeat still keeps the old reference. Here is my code (function () { "use strict";

angular.module('messages', [])

.component('messages', {
    template: '<ng-outlet></ng-outlet>',
    $routeConfig: [
      { path: '/', name: 'MessageList', component: 'messageList', useAsDefault: true },
      { path: '/:id', name: 'MessageDetail', component: 'messageDetail' },
    ]
})

.component('messageList', {
    templateUrl: '/angular/spa/profile/components/messages/template/message-listing.template.html',
    controllerAs: "model",
    controller: ["$http", messageListController],
})

.component('messageDetail', {
    templateUrl: '/angular/spa/profile/components/messages/template/message-detail.template.html',
    controllerAs: "model",
    bindings: { $router: '<' },
    controller: ["$http", messageDetailController],
})

.component('messageBubble', {
    templateUrl: '/angular/spa/profile/components/messages/template/message-bubble.template.html',
    controllerAs: "model",
    controller: ["$http", messageBubbleController],
    bindings: {
        message: '<',
        user: '<'
    },
});

function messageBubbleController($http) {
    var model = this;
    model.$onInit = function () {
        model.currentUserId = $("#loggedInUserIdSignalR").val();
    };
}

function messageDetailController($http) {
    var model = this;
    model.item = null;
    model.user = null;
    model.message = null;
    model.loading = false;
    model.chatHub = $.connection.chatHub;
    model.$onInit = function () {
        model.loading = true;
    };
    model.sendMessage = function () {
        if (model.message.length > 0) {
            console.log(model.messages.length);
            model.chatHub.server.send(model.message, model.user.SubjectId, model.item.ItemId);
        }
    };
    model.chatHub.client.broadcast = function (message, date, recipientId, itemId, senderId, senderNickName, senderPicture) {
        $scope.$apply(function () {
            model.messages.push({
                ConnectionId: "",
                DateSent: "/Date(1468852585430)/",
                Message: message,
                Sender: senderId,
            });
        });
        console.log(model.messages.length);
        console.log('New incoming message: ' + name + " ->" + message)
    };

    this.$routerOnActivate = function (next) {
        var id = next.params.id;
        fetchConversationMessages($http, id).then(function (response) {
            model.loading = false;
            model.uid = response.uid;
            model.item = response.conversation;
            model.user = response.conversation.User;
            model.messages = response.conversation.messages;
        });
    };


    function fetchConversationMessages($http, id) {
        return $http.get("/profile/messages-data/" + id)
                    .then(function (response) {
                        console.log(response);
                        return response.data;
                    });
    }
}

function messageListController($http) {
    var model = this;
    model.conversations = []
    model.loading = false;
    model.$onInit = function () {
        model.loading = true;
        fetchConversations($http).then(function (conversations) {
            model.loading = false;
            model.conversations = conversations.results;
            console.log(model.conversations);
        });
    };

    model.$routerOnActivate = function (next) {
        console.log('messages list comp activated');
    }
    function fetchConversations($http) {
        return $http.get("/profile/conversationsData")
                    .then(function (response) {
                        return response.data;
                    });
    }
}

})();

in this block of code

model.chatHub.client.broadcast = function (message,date,recipientId,itemId,senderId,senderNickName,senderPicture) {
            model.messages.push({
                ConnectionId: "",
                DateSent: "/Date(1468852585430)/",
                Message: message,
                Sender: senderId,
            });

            console.log(model.messages.length);
            console.log('New incoming message: ' + name + " ->" + message)
        };

Is where I get the new message and push it to the messages list, the console logs shows the updated list however I have on my template this

<div class="chat-room">
        <pre>{{model.messages.length}}</pre>
        <message-bubble ng-repeat="msg in model.messages" message="msg" user="model.user"></message-bubble>
    </div>

and this line of code

    <pre>{{model.messages.length}}</pre>

still shows the old list, I read in another post that this is happening because of references but I've tried to solve a lot different ways with no luck.

Upvotes: 0

Views: 770

Answers (1)

csharpfolk
csharpfolk

Reputation: 4290

Everywhere where you push a new message, change:

model.chatHub.client.broadcast = function(...) {
            model.messages.push({
                ConnectionId: "",
                DateSent: "/Date(1468852585430)/",
                Message: message,
                Sender: senderId,
            });
        };

into:

model.chatHub.client.broadcast = function(...) {
       $scope.$apply(function() {
            model.messages.push({
                ConnectionId: "",
                DateSent: "/Date(1468852585430)/",
                Message: message,
                Sender: senderId,
            });
        });
    };

The other solution would be to find angularjs wrapper for your communication library.

What $scope.$apply do is basically it tells AngularJS that data used by your app changed and that it need to run digest loop again. As you probably know digest loop checks what data changed and runs all $watches for data that changed, some of them are used by directives like ng-repeat to update DOM.

Upvotes: 1

Related Questions