Olli Olli - 2 months ago 7
AngularJS Question

Passing Data from Service to Template via Controller and $stateParams

I have a service with the following code:

.service('ChatService', function() {
return { //Gets Data from controller
sendData: function(data) {
this.chatData = data;
console.log('this.chatData: '+this.chatData);
},
chats: this.chatData,
getChats: function() {
return this.chatData;
},
getChat: function(chatId) {
for(i=0; i<this.chats.length; i++) {
if (this.chats[i].id == chatId) {
return this.chats[i];
}
}
}
}
})


The Important thing here is that sendData retrieves info

[{id: 1, message: "Chat Message 1"},{id: 2, message: "Message 2"}]


from the controller. The getChats in Services is then called
$scope.chats = ChatService.getChats();
by the same controller to show in the template.
When that item is clicked a new page with more info is to show hence the
getChat
and
getChats
function in the service.
The code in the controller for the page to load more details is

$scope.chatId = $stateParams.chatId;
$scope.chat = ChatService.getChat($scope.chatId);


However I'm getting error cannot read property length of undefined. Now if I change the
chats: this.ChatData
in the services to

chats: [{id: 1, message: "Chat Message 1"},{id: 2, message: "Message 2"}]


It works like a charm but I need it to display in real time what is in the controller because I'm downloading and receiving info from the server that will be updated in real time for a chat app.

Answer

Use angular.copy to update the reference:

app.service('ChatService', function() {
    //Gets Data from controller
    this.sendData = function(data) { 
      //this.chatData = data;
      //console.log('this.chatData: '+this.chatData);
      //Use angular.copy
      angular.copy(data, this.chats);
    };
    this.chats = [];
    this.getChats = function() {
      return this.chats;
    };
    this.getChat =  function(chatId) {
      for(i=0; i<this.chats.length; i++) {
        if (this.chats[i].id == chatId) {
          return this.chats[i];
        };
      };
    };
});

By using the angular.copy to update the array reference, controllers that have previously fetched the reference will get updated.

For more information, see AngularJS angular.copy API Reference.