Search code examples
javascriptangularjspromiseangular-promiseangularjs-http

$http timing issues, AngularJS


Have two issues. I am trying to get a value from an $http response and populate a variable with it that should then update a couple DOM objects. Problem is that it seems to be having a timing issue where the function that called the $http service completes and then the variable gets updated but doesn't seem to update everywhere it should. I also tried putting a watch on the variable and it only seems to fire off when the page is initially loaded. I'ved been reading up all this all day and cant seem to find an answer that works.

app.controller('MainCtrl', ['$scope', '$http', 'waciServ', function($scope,      $http, waciServ) {
"use strict";
$scope.currentSource = waciServ.activeSource;

$scope.$watch('waciServ.activeSource', function(newValue, oldValue) {
        $scope.currentSource = newValue;
        console.log('Watcher! ' + newValue);
}/*, true*/);

$scope.getActiveSource = function () {
    $scope.currentSource = waciServ.getStringByName("active_device");
};
}]);

app.service('waciServ', function($http) {
  var self = this;
  this.waciIP = location.host;
  this.activeSource = '';

  this.getStringByName = function (name) {
    $http.post("http://" + self.waciIP + "/rpc/", "method=GetVariableByName&param1=" + name + "&encoding=2")
        .then (function (response) {
            var was_error = self.read(response.data);

            if (was_error == '1') { //active_device is not set
                self.assignVariable(name, "none");
                self.activeSource = "none";
                return self.activeSource;

            } else {
                var varId = parseInt(self.read(response.data));
                $http.post("http://" + self.waciIP + "/rpc/", "method=GetVariableValue&param1=" + varId + "&encoding=2")
                    .then (function (response) {

                        self.activeSource = self.read(response.data);

                        return self.activeSource;      
                });
            }
    }, function (error) {
        console.log("error: " + error.data);
    });
  };
});

i can place a console.log right before the return fires and see that I have what I want, but another console.log placed in the function within the controller shows 'undefined'.

What gives? Thank you in advance.


Solution

  • You don't need to think about to use watcher.

    Basically the problem is you are not returning promise from the service method. You should return promise of $http method calls from your service method .Thereafter use .then over method call to chain promise & put success & error function in it. (this answer is little similar with what you are asking but not exactly)

    Service

    self.getStringByName = function(name) {
      //returned promise from here
      return $http.post("http://" + self.waciIP + "/rpc/", "method=GetVariableByName&param1=" + name + "&encoding=2")
        .then(function(response) {
        var was_error = self.read(response.data);
    
        if (was_error == '1') { //active_device is not set
          self.assignVariable(name, "none");
          self.activeSource = "none";
          return self.activeSource; //returned data here to chain promise
        } else {
          var varId = parseInt(self.read(response.data));
          //returned promise from here
          return $http.post("http://" + self.waciIP + "/rpc/", "method=GetVariableValue&param1=" + varId + "&encoding=2")
            .then(function(response) {
            self.activeSource = self.read(response.data);
            //returned data from here
            return self.activeSource;
          });
        }
      }, function(error) {
        console.log("error: " + error.data);
      });
    };
    

    Controller

    app.controller('MainCtrl', ['$scope', '$http', 'waciServ', function($scope,      $http, waciServ) {
    "use strict";
       $scope.currentSource = waciServ.activeSource;
    
       $scope.getActiveSource = function () {
          waciServ.getStringByName("active_device").then(function(source){
             $scope.currentSource = source;
          });
       };
    }]);