2

I have an angular service set up like -

function updateViewService($http, $interval) {
var change = true;
var grabTimeStamp = function(){
    $http.get('someapi').then(function success(response){
        //some logic to change var change according to the response
}
$interval(grabTimeStamp, 10000);
return { refresh: function(){
        return change;
    }};
}

Now what I need to do is return change in controller and also update the controller variable as soon as service change changes.

What I suspect is in the controller, the service return function returns the value only once. So I tried $interval in my controller while calling the service, that did not update the controller variable either.

I have a lot of controllers, that is why I made one service that should update all the controllers.

Then I tried $rootScope.$broadcast whenever change variable changes. Tried to listen to broadcasts in controller with $scope.$on but did not work.

if(change === true){
    $rootScope.$broadcast('dataChanged',change);
    change = false;
}

What should be the ideal way to do this?

Basically what I want to do is-

  1. Create a service that makes a request every ten seconds and update the change variable (Done)

  2. Pass this variable to the controller and update the view (basically make a request to the back-end and get the new data {stuck})

Thanks.

2
  • what error are you getting when you fire the event? Commented Jul 20, 2016 at 8:16
  • There are no errors Commented Jul 20, 2016 at 8:17

3 Answers 3

2

So you want to know when change variable inside your service changes value?

You can use $scope.$watch for this.

angular.module('app', []);

angular.module('app').service('someService', function ($interval, $q) {
  var change = 0;
  
  $interval(function () {
    $q.resolve(Math.random()) //some promise, maybe from $http, but for sake of simplicity I will use $q.resolve
      .then(function (result) {
        change = result; //setting change to random value
      });
  }, 1000); //changes every second
  
  return {
    getChange: function () {
      return change;
    }
  };
});

angular.module('app').controller('Example', function ($scope, someService) {
  $scope.$watch(someService.getChange, function (change) { ///adding watcher on someService.getChange, it will fire when change changes value
    this.change = change; //setting change to controller here you can put some extra logic
  }.bind(this));
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script>
<div ng-app="app" ng-controller="Example as Ex">
  {{Ex.change}}
</div>

Although event should also work, care to share some example of your code in action (jsfiddle, snippet or anything like that)?

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

2 Comments

iirc $scope.$watch take a expression string as first args and the expression should be a property of $scope, just curious is this even work ?
@HarryLim it can take string, but functions are also accepted. And yes it works, it is fired every time when result of this function changes. Ofc this function is called a lot during $digest cycle, so it should be fairy simple. At best some getter, no heavy logic.
0

What you can do is to create a simple polling service. It would make a request with specified interval. Here how I would do it:

function updateViewService($http, $timeout) {
  var grabTimeStamp = function(callback) {
    return $http.get('someapi').then(function success(response) {
      //some logic to change var change according to the response
      return response.data;
    });
  }

  var poll = function(action, interval) {
    return $timeout(function() {
      grabTimeStamp()
        .then(action)
        .then(poll.bind(null, action, interval))
    }, interval);
  };

  return {
    grabTimeStamp: grabTimeStamp,
    poll: poll
  }
}

app.factory('dataService', updateViewService);

Then you would use it in controller like this:

dataService.poll(function(data) {
  $scope.data.push(data);
}, 1000);

Demo: http://plnkr.co/edit/MWBlhJzJUh7UJSCJdfPg?p=info

Comments

0

The solution you provided with the event should work but the service must be injected in the controller infact The service must be instantiated by Angular before the controller.

.service(function updateViewService($http, $interval, someService) {
var change = true;
var grabTimeStamp = function(){
$http.get('someapi').then(function success(response){
  //some logic to change var change according to the response
  if(change === true){
    $rootScope.$broadcast('dataChanged',change);
    change = false;
  }
}
$interval(grabTimeStamp, 10000);

})

.controller(function($rootScope, updateViewService){
  $rootScope.$on('dataChanged', function(){
    //do something
  });
})

Comments

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.