Reputation: 1236
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
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 $watch
es for data that changed, some of them are used by directives like ng-repeat
to update DOM.
Upvotes: 1