2

I'm having some basic problems with angular at the moment. I just wrote a service that reads the temperature of an external device in an interval of five seconds. The service saves the new temperature into a variable and exposes it via a return statement. This looks kind of this (simplified code):

angular.service("tempService", ["$interval", function ($interval) {

    //revealing module pattern
    var m_temp = 0,
        requestTemp = function() {//some logic here},
        onResponseTemp = function (temp) {
            m_temp = temp;    
        },
        //some other private functions and vars ...
        foo = bar;

    //request new temperture every 5s, calls onResponseTemp after new data got received
    $interval(requestTemp, 5000);

    return {
        getTemp = function(){return m_temp;}
    }
}]);

I use a controller to fetch the data from the service like this:

angular.controller("tempCtrl", ["$scope", "tempService", function ($scope, tempService) {

    $scope.temp = tempService.getTemp();
}]);

In my view I access it like this:

<div ng-controller="tempCtrl">
        <p>{{temp}}</p>
</div>

But I only get 0 and the value never changes. I have tried to implement a custom Pub/Sub pattern so that on a new temperature my service fires an event that my controller is waiting for to update the temperature on the scope. This approach works just fine but I'm not sure if this is the way to go as angular brings data-binding and I thought something this easy had to work by itself ;)

Help is really appreciated.

3 Answers 3

1

Please see here http://jsbin.com/wesucefofuyo/1/edit

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

    app.service("tempService", ["$interval", function ($interval) {

        //revealing module pattern
      var m_temp = {
        temp:0,
        time:null

      };


           var requestTemp = function() {
            m_temp.temp++;
            m_temp.time = new Date();

           };

           var startTemp = function() {
        $interval(requestTemp, 3000);
           };
        return {
          startTemp :startTemp, 
          m_temp:m_temp
        };
    }]);

    app.controller('fCtrl', function($scope,tempService){

      $scope.temp =  tempService;
      $scope.temp.startTemp();


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

2 Comments

Returning an object instead of a primitive did the trick. Thanks!
Just to confirm, so to have the data in the controller update when the service updates you pass the service in completely and then you access the service value or functions within the controller or UI? Can you or would you ever do something like $scope.startTemp = tempService.startTemp and then invoke in the UI or controller invoke the function, like $scope.startTemp() instead of passing the entire service?
1

You are returning a primitive from your service, if you want to update an primative you need to reftech it. You should return an object, as on object is passed by reference, you get the actual values in your controller.

do this in your service:

return m_temp;

And this in your controller:

$scope.temp =  tempService;

and your view will update as soon as the service gets updated.

Does this help you?

1 Comment

Thanks, this helped a lot and if I could accept more than just one answer I would do so with yours. But sss provided an example so I could figure out my mistake easier.
0

i think you should use $interval in controller ot in service

$interval(tempService.getTemp(), 5000);

3 Comments

I tried that before but the downside is that if I'm changing the page by ng-route the controller gets killed. So everytime I reenter the temperture page it starts from the beginning, but the interval should work everytime, even in the background. I can achive this only by putting the interval logic into the service, that runs also in the background.
ohkie, so service thing is working fine and you are upto the best pattern consideration?
Well, the service itself is doing what it should. But I'm not sure whats the best way to expose parameters of the service to the outside for using them in controllers. So yes, it's kind of a question for the best pattern, as the one I'm using in my question obviously doesn't work.

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.