Bind value between Service and Controller/Directive

Many AngularJs developers know about Angularjs services, controllers and directives. As you know, Angularjs service is used to have global actions or variables.In general services used as global actions,because Angularjs already has Value feature.

Now let's talk a little about configuration and architecture of services and controllers. Imagine you have a service which represents a person.It has all getters and setters methods.We have another service as a data manager. It gets data from anywhere every 1 minute. We have some controllers and some directives, and we want to bind given data inside them. Just a simple example. We have three controllers and two directives. Some of them need to bind data, and they have to use our services.Remember we have a service called Person and a service called DataManager.

What can we do to solve our problem? Let's see what we have got.

angular.module('myModule')
    .service('Person', function() {
         var name = 'Default';
         var listCount = 0;

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

         this.getListCount = function() {
             return listCount;
         };
         this.setListCount = function(ListCount) {
             listCount = ListCount;
         };
    })
angular.module('myModule')
    .service('DataManager', function($interval, $http, Person) {
       $interval(function(){
          $http.get([url])
              .then(function(data){
                  Person.setName(data.name);
                  Person.setListCount(data.count);
              });   // getting the data every 1 minute
          }, 60000);
    })

The following services provide data inside any controller or directive. Now let's see how we can bind that data, for example, inside the controller. Here is our controller.

angular.module('myModule')
    .controller("MyController",function($scope, Person){
       $scope.user = null;
        // here we need live data for person
    })

As you see, if we wanted to print having data, we will have a problem, because we can not set the listener on any value to bind the data (we take the data from service). But how to do that? How to have live data inside our controller?

Here are the solutions for that problem.

Solution 1

This solution is good,if we will use the live data only in 1 controller/directive.The solution is: We can set interval inside our controller/directive and we will have a variable inside our scope,which holds the data from server.We can print that value in our view and AngularJs automatically will do that.We can even set listeners on it.It's just a very simple.Then we do not need the DataManager service.Here is an example:

angular.module('myModule')
    .controller("MyController",function($scope, Person, $interval){
       $scope.user = null;
        $interval(function(){
          $http.get([url])
              .then(function(data){
                  $scope.user.name = data.name;
                  $scope.user.count = data.count;
              });   // getting the data every 1 minute
          }, 60000);
    })

Maybe you think, why do we need Person service?. In general, you are right, but we can use it in our controller to update Person service data (for another component).

Solution 2

The Second solution is good, if we have many components and we need to use the service (have live data) inside many components (controller/directive).The solution is: AngularJs Events.

We can set the listener on any event, and when service gets a new live data from the server, it sends a signal, to say that it has new data. We can use that event wherever we want. Let's see how we can do that.

angular.module('myModule')
    .service('DataManager', function($interval, $http, Person, $rootScope) {
       $interval(function(){
          $http.get([url])
             .then(function(data){
                 Person.setName(data.name);
                 Person.setListCount(data.count);
                  
                 // here we have to send signal that we have a new live data from the server
                 // we use Root Scope, because we don't know what scope architecture do we have
                 $rootScope.$broadcast("newPersonData");
             });   // getting the data every 1 minute
          }, 60000);
    })

As you see we can use this event wherever we want. We can set listener to this event, and when service has new data, we can call Person's methods to update it. You can even send the data to 'eventName'. We have another great solution. If you are interested in it, write us in Google+, Facebook and Twitter.


Do you find this helpful?

Related articles