Search code examples
javascriptangularjsangularjs-serviceangularjs-controller

Updating directive based on change in service value AngularJS


I have a basic app currently that has a list of names in a sidebar nav populated from a json call to my server. When the user clicks on a name in the sidebar, it updates the nameService to the name clicked on by the user.

When the nameService gets updated, I wanted to name-data view to make another json call the the server for the correct json file based on the name that the user clicked on.

I am having difficulty updating a view based on changes in a value contained in my service. I have two controllers and a service currently in my AngularJS app as follows:

app.js

var app = angular.module("myapp", ['ui.bootstrap']);

app.directive("sideBar",  ['$http', 'nameService', function($http, nameService) {
    return {
        restrict: 'E',
        templateUrl: "views/sidebar.html",
        controller: function($scope) {
            $scope.updateName = function(name) {
                nameService.setName(name);               
            }; 

            $http.get('../data/names.json').
                success(function(data, status, headers, config) {
                    $scope.names = data;
            });         
        }
    };
}]);

app.directive("nameData",  ['$http', 'nameService', function($http, nameService) {
    return {
        restrict: 'E',
        templateUrl: "views/name-data.html",        
        controller: function($scope) {
            $scope.service = nameService;

            var path = "../data/" + $scope.service.name + ".json";

            $http.get(path).success(function(response) {
                $scope.info= response.info;
            });
        }
    };  
}]);

app.service('nameService', ['$http', function($http) {
    this.name = "TestName";

    this.setName = function(name) {
        this.name = name;
    };

    this.getName = function() {
        return this.name;        
    };
}]);

How can I update the nameData view whenever the user clicks on the sidebar nav and updates the nameService.name property?

I tried putting $scope.service.name under a watch but that didn't seem to do anything.

Is there some form of angular magic I can use to dynamically make new json calls when a new user is selected from the name list contained in my side bar?


Solution

  • maybe angular event broadcasts?

    add rootScope to service and broadcast an event on name change:

    app.service('nameService', ['$http','$rootScope', function($http,$rootScope) {
      this.name = "TestName";
    
      this.setName = function(name) {
          this.name = name;
          $rootScope.$broadcast('nameService-nameChanged');
      };
    
      this.getName = function() {
          return this.name;        
      };
    }]);
    

    and then bind to that event on your directive controller scope:

    app.directive("nameData",  ['$http', 'nameService', function($http, nameService) {
        return {
            restrict: 'E',
            templateUrl: "views/name-data.html",        
            controller: function($scope) {
                $scope.service = nameService;
    
                //turned your load mechanism in to a function
                $scope.loadNameData = function(){
                   var path = "../data/" + $scope.service.name + ".json";
    
                   $http.get(path).success(function(response) {
                      $scope.info= response.info;
                   });
               }
               //initial load
               $scope.loadNameData();
    
               //subscribe to broadcast event, this will call $scope.loadNameData when the 'nameService-nameChanged' event is broadcast
               $scope.$on('nameService-nameChanged',$scope.loadNameData); 
    
            }
        };  
    }]);