angularjsangularjs-scopeangularjs-apply

Scope variable not getting data object after http service returns


I'm trying to read list of files on a on a server. The HTTP GET method service returns the list of files, but scope variable in controller is not getting updated with the return value. Can you please help me find what is going wrong ?

app.controller('RdaController', ['$scope', ', 'RdaService', function($scope, RdaService) {
  $scope.listOfFilesOnCTP = "";
	
	$scope.GetListOfFilesonCTP = function(path){
		$scope.$apply(function(){
			$scope.listOfFilesOnCTP = RdaService.getListOfFilesonCTP(encodeURIComponent(path)); 
		});
		//path = path.replace(/\//g, '_');
		console.log($scope.listOfFilesOnCTP);  //--> This scope variable does not get updated.
		return $scope.listOfFilesOnCTP;
	}
}]);

app.service('RdaService', ['$http', function($http) { 
  this.getListOfFilesonCTP = function(path){	  
	  return $http ({
	  method: "GET",
		url: "../api/CTP/getFilesonCTP/"+ path,
		headers: { 'Content-Type': 'application/json' }
  }).success(function(data){
	 return data;    //---> contains the expected value
  }).error(function(data){
	  return data;
  });
};
}]);
	<div class="col-md-3" id="CTP Jobs">
		<h3>JOBS</h3>
		<table class="table table-striped"
			ng-init="GetListOfFilesonCTP('/home/topas/rda_app/JOBS')"
			ng-model="listOfFilesOnCTP">   <!-- This variable is not updated-->
			<div ng-repeat="file in listOfFilesOnCTP">
				<span><tr>{{file}}
					</tr></span>
			</div>
		</table>
	</div>


Solution

  • You had mistaken several thing in your code.

    1. Do return only promise returned by $http.get method from service. Because as you are trying to return a data from .success & .error callback of $http method. It will not return data back.
    2. Do use .then function over service method call, on success which will call first function with data returned by $http.
    3. You were expecting to get console.log($scope.listOfFilesOnCTP); to print data returned by service. But this will not return it. Async call are not work in this way. They will return out a data in special manner like promise resolution OR callback manner.
    4. No need to use $scope.$apply here, as digest cycle has been already taken care by $http service.
    5. Try to minimize the use of ng-init, you can do call that method on controller initialization itself.

    Sevice

    app.service('RdaService', ['$http', function($http) { 
      var self = this;
      self.getListOfFilesonCTP = function(path) {     
          return $http ({
          method: "GET",
            url: "../api/CTP/getFilesonCTP/"+ path,
            headers: { 'Content-Type': 'application/json' }
        });
      };
    }]);
    

    Then do use that promise while retrieving data inside controller.

    app.controller('RdaController', ['$scope', 'RdaService', function($scope, RdaService) {
        $scope.listOfFilesOnCTP = "";
    
        $scope.GetListOfFilesonCTP = function(path) {
            $scope.listOfFilesOnCTP = RdaService.getListOfFilesonCTP(encodeURIComponent(path)).then(function() {
                console.log($scope.listOfFilesOnCTP);
            });
        };
    }]);