1

my function didnt wait to complete earlier function execution and it is completing.

I have my code is that i am doing some thing wrong:

$scope.abc1 = function(){
 var arrayJson = [{'name':'max','age':'12'},{'name':'tax','age':'16'}]
 for(var i=0; i<arratJson.length;i++){
  var getAddress = $scope.xyz(arratJson[i].name);
    }
  $scope.createBody();

 };
 $scope.createBody = function(){
 //some more code here
 };
 $scope.xyz = function(name){
    $http({
            method: 'GET',
            url: 'rest/address',
            type:'json',
            headers:{'action':'single','name':name},  
            }).success(function(response){
             return response;
            }).error(function(response){

            });
   };

so in this it is not waiting to get address instead of it moving down so how to wait finishing for loop and then call different function. createBody function called before the $scope.xyz() function returns the value how to wait until loop finishes

Mayur
  • 1,123
  • 3
  • 22
  • 38
  • Possible duplicate of [Call An Asynchronous Javascript Function Synchronously](http://stackoverflow.com/questions/9121902/call-an-asynchronous-javascript-function-synchronously) – Aprillion Jan 30 '16 at 10:44
  • here you are calling one function only. Are you calling second function after this? – Deepak Dholiyan Jan 30 '16 at 10:45

5 Answers5

2

This is expected due to asynchronous nature of execution. You should use callbacks to avoid this problem.

Nijeesh
  • 848
  • 7
  • 11
1

You should use the $q service.
first store all $http calls in an array and with $q.all(array) you create a promise that is resolved after all $http promises have resolved.

e.g:

$scope.abc1 = function(){
  var arrayJson = [{'name':'max','age':'12'},{'name':'tax','age':'16'}]
  var promises = [];
  for(var i=0; i<arratJson.length;i++){
    promises.push($scope.xyz(arratJson[i].name));
  }

  $q.all(promises).then($scope.createBody);

};

And on the resolve of this new promise you can call your createBody function.

For this to work You should also change success callback on the $scope.xyz to a then callback and return the promise.

e.g:

$scope.xyz = function(name){
  return $http({
    method: 'GET',
    url: 'rest/address',
    type:'json',
    headers:{'action':'single','name':name},  
  }).then(function(response){
    return response;
  })["catch"](function(response){

  });
};

UPDATE

If you don't care if all calls succeed, replace:

$q.all(promises).then($scope.createBody);

With:

$q.all(promises)["finally"]($scope.createBody);

PS: Keep in mind that in the finally callback you don't get the return values of every call, whereas in the then an array will be passed as argument in the callback function which holds in every position a return value of each $http call.

koox00
  • 2,691
  • 2
  • 15
  • 25
0

There are two way to achieve this

1)Use async:false

2)Need to use callback

choose your way and enjoy!

Deepak Dholiyan
  • 1,774
  • 1
  • 20
  • 35
0

You should how promises works in javascript.

$http is an asynchronous function. You must return $http result in $scope.xyz function and use then, success, error function callbacks.

Example:

function xyz() {
   return $http(...);
}

xyz().then(function(data) {
    address = data.data.address; // in your json dto format
})

more info https://docs.angularjs.org/api/ng/service/$http

hope this helps! regards

0

You can use Angular promises.

Include promise status to self created object with deferred value, that has valueOf and toString methods. Last two methods allow to use arithmetic, string and comparison operators.

Object with deferred value:

 var DeferredValue = function(initial){
    var self = this;
    self._value = initial; 
    var deferred = $q.defer();
    self.$promise = deferred.promise;
    self.$resolved = false;
    self.$resolve = function(value){
      deferred.resolve(value);
    }
    self.$promise.then(function(v){
      self._value = v;
      deferred = null;
      self.$resolved = true;
      delete self.$resolve;
      return self.$promise;
    });
  }

  DeferredValue.prototype = {
    constructor: DeferredValue,
    valueOf: function(){
      return this._value
    },
    toString: function(){
      return this._value.toString()
    }
  }

Return this object in your ASYNC function, and resolve them after retrieving data:

var getValue = function(){
  var value = new DeferredValue();
  $timeout(function(){
    value.$resolve(Math.floor(Math.random() * 10))
  },1500);
  return value;
}

Plunker example

Enver Dzhaparoff
  • 4,341
  • 3
  • 19
  • 21