Kyle
Kyle

Reputation: 1173

Update scope value when service data changes

I am trying to update the scope value on a view when the service data changes.

The problem is that, (a) if I update the data in a different controller, then (b) the value doesn't update on the view.

main.html

<!-- breadcrumb row -->
<div ng-controller="mainController">
    <span ng-if="memberCompany !== null">{{ memberCompany }}</span>
</div>
<!-- / breadcrumb -->

main.js

// breadcrumb service
app.service('breadcrumb', function() {

    // variables
    var memberCompany = null;

    return {
        // get compnay
        getCompany: function() {
            return memberCompany;
        },
        // set company
        setCompany: function(value) {
            memberCompany = value;
        }
    }
});

// main controller
app.controller('MainController', ['$scope', 'breadcrumb', function($scope, breadcrumb) {

        // get company to display in view
        $scope.memberCompany = breadcrumb.getCompany();
    }
]);

If I update the service value in a different controller, I would like to be able to display that updated value back on the index view so it's viable across the app

other controller

app.controller('otherController', ['$scope', 'breadcrumb', function($scope, breadcrumb) {

    // update company
    breadcrumb.setCompany('StackExchange');

    // update the scope data in the view?   

}]);

How can I display the updated value on the index view once it's changed?

Upvotes: 1

Views: 4856

Answers (2)

Mike Quinlan
Mike Quinlan

Reputation: 2882

If this is a site-wide necessity, I would definitely stay far, far away from adding a bunch of watches everywhere as they can be costly for development time as well as computer resources. I would first write the service accordingly:

angular.module('myModule').service('Breadcrumb', function() {
  return {
    company: null,
    setCompany: function(company) {
      this.company = company;
    },
    getCompany: function() {
      return this.company;
    }
  };
});

Although in my opinion, the getters and setters are definitely very unnecessary ( you could just set by Breadcrumb.company = company and get by Breadcrumb.company). Moving on, you should assign the breadcrumb service to the root scope:

angular.module('myModule').run(function($rootScope, Breadcrumb) {
  return $rootScope.breadcrumb = Breadcrumb;
});

Then at this point you can either inject this service into your controllers/directives and call upon it within any view in the application like so:

<span class="my-company-name" ng-bind="$root.breadcrumb.company.name" />

This saves you from having to call watchers on everything and allows for you to only inject the Breadcrumb service when you actually need it in the application logic. However, like I said at first, it really depends on how widely used this service is as you do not want to muddy up your $rootScope with arbitrary values. If you don't want to assign it to the $rootScope you could assign it in your controllers and directives:

angular.module('myModule').controller('ApplicationCtrl', function($scope, Breadcrumb) {
  $scope.breadcrumb = Breadcrumb;
});

and access it from templates like this:

<span ng-bind="breadcrumb.company.whatever" />

Hope that helps!

Upvotes: 1

tymeJV
tymeJV

Reputation: 104795

You can use a $watch in your controller on that service:

$scope.$watch(function() {
    return breadcrumb.getCompany()
}, function(newValue, oldValue) {
    $scope.memberCompany = newValue;
});

Upvotes: 2

Related Questions