0

I have a controller (call it "A") where I get a value from the webserver. When I get this value, I store it in a Service.

In another controller (call it "B") I have to get this value from the service everytime it is stored in the service. And this value must appear in the view (updated).

My usual solution is: I emit an event everytime I store the value in the service. then in the controller B I listen to this event and then i get the value from the service.

I know there are other solutions, like the scope.$watch/apply but I don't know which is better.

Can you suggest me which way is better?

2 Answers 2

1

Push Values from a Service with RxJS

One alterantive to $rootScope.broadcast is to build a service with RxJS Extensions for Angular:

<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);

app.factory("DataService", function(rx) {
  var subject = new rx.Subject(); 
  var data = "Initial";
  
  return {
      set: function set(d){
        data = d;
        subject.onNext(d);
      },
      get: function get() {
        return data;
      },
      subscribe: function (o) {
         return subject.subscribe(o);
      }
  };
});

Then simply subscribe to the changes.

app.controller('displayCtrl', function(DataService) {
  var $ctrl = this;

  $ctrl.data = DataService.get();
  var subscription = DataService.subscribe(function onNext(d) {
      $ctrl.data = d;
  });

  this.$onDestroy = function() {
      subscription.dispose();
  };
});

Clients can subscribe to changes with DataService.subscribe and producers can push changes with DataService.set.

The DEMO on PLNKR.

Sign up to request clarification or add additional context in comments.

Comments

0

Watchers are called everytime a $digest or an $apply cycle is done. It has more impact on your application than a local event like you are doing.

If you can use services to control communication between directives and/or controllers, it's better.

As far as i know, there's 4 ways to handle communication between controller and/or directives:

  • Using a service (like you do)
  • Rely on the $apply cycle with $watch
  • Use the angular event system (with scope.$emit or scope.$broadcast)
  • Be very dirty and use a global variable

Using a service is the best way. Especially if you handle a "one-to-one" communication.

5 Comments

So the way I'm using (event + service) is the best way to pass and update data between controllers?
The difference between the first and the third is that the third pass the data inside the event?
Some tutorials use the service in combination of the $watch, but why they don't mention events with services?
Because service are just object. They don't have a scope and they can't use the angular event system.
But is right to store value in the service, then launch the event "valueStored", then catch the event in the other controller and get the value from the service?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.