Markus
Markus

Reputation: 2274

Why is the data in the service not updated from the directive?

With the following setup I try to update data that is being held in a service and shared with the controller to assign it to the view.

In the example you can see 2 variables. One containing an array, another just a string.

What I don't understand is why is the array updated and consumed in the view and the string is not?!

JavaScript:

function fooService() {
    var mystring = 'old string';
    var myarray = [];

    var updateArray = function(data) {
        myarray.push(data);
    };

    var updateString = function(data) {
        mystring = data;
    };

    return {
      myarray: myarray,
      mystring: mystring,
      updateString: updateString,
      updateArray: updateArray
    }
}

function MainCtrl($scope, fooService) {
    this.myarray = fooService.myarray;
    this.mystring = fooService.mystring;
}

function fooDirective(fooService) {

    function link(scope) {

      fooService.updateArray(scope.vm.name);
      fooService.updateString('new string');

    }

    return {
        restrict: 'EA',
        replace: true,
        template: '<h2 style="color: {{vm.color}};">{{vm.name}}</h2>',
        scope: {},
        controller: 'MainCtrl',
        controllerAs: 'vm',
        bindToController: {
            name: '@',
            color: '@'
        },
        link: link
    };
}

angular
    .module('app', [])
    .service('fooService', fooService)
    .controller('MainCtrl', MainCtrl)
    .directive('fooDirective', fooDirective);

HTML:

<div ng-app="app">
    <div ng-controller="MainCtrl as vm">
        {{vm.myarray}}
        {{vm.mystring}}
        <foo-directive data-name="Markus" data-color="red"></foo-directive>
        <foo-directive data-name="Nemanja" data-color="green"></foo-directive>
        <foo-directive data-name="Luke" data-color="blue"></foo-directive>
    </div>
</div>

It might just be that I understand it the wrong way but services should hold data that is shared across the app right?

Here is the working example: http://jsfiddle.net/markus_falk/f00y3tL3/6/

Upvotes: 3

Views: 42

Answers (1)

dfsq
dfsq

Reputation: 193261

services should hold data that is shared across the app right?

This is correct, however when you do

return {
  myarray: myarray,
  mystring: mystring,
  // ...
}

you return new object (that will be your service instance) that has reference to myarray and copy of mystring. So since there is reference to myarray (all objects are passed as a reference) it updates in the service just fine. However, it will not for with the string (primitive types are not-mutable, passed as values), because service returns just a copy of it.

Instead of modifying a string (primitive value) use getter/setter approach.

Upvotes: 2

Related Questions