2

As the title says, I want to send $http.get requests to the server until the returned results meets a condition.

This is what I tried:

    var searchComplete = false;
    var sendGetReq = true;

    while(!searchComplete) // #2 and then jumps here
    {
       if(sendGetReq)
       {
         sendGetReq = false;  // #1 execution reaches here
         $http.get('/user/getCondition', {params: {condition: $scope.condition}).
        success(function (condition, status, headers, config) {
         ...
         ...
         if(condition)
         { searchComplete = true; }
         else
         { sendGetReq = true; }
    }
}

However, the $http.get request never goes. That statement is never reached. When I debugged, I saw that execution will come to sendGetReq=false and then jump to while(!searchComplete). The GET request is never sent.

Would someone please explain:

  1. Why the execution never reaches GET request and jumps back
  2. What is the recommended way to to do this continuous GET request

Thank you.

1
  • 2
    Use .then, not .success, and you should make this a recursive function. Don't expect perfect behavior using a while and a promise together. Make youself a function that calls itself once the promise has returned. Commented Aug 30, 2016 at 14:55

5 Answers 5

3

Why not put it all together inside a function and call itself if condition is meet? Like this and you should use .then and not .success:

$scope.load = function(){
  $http.get('/user/getCondition', {params: {condition: $scope.condition}).
    then(function (condition, status, headers, config) {

    if (condition){
       $scope.load();
    }

  });
}

Hope it helps =)

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

Comments

2

Do not use while (true), especially in JS.

JS works in one thread. $http.get will never run because your main thread stalled in you infinite loop and do not gave a chance for other threads to run.

Update

function getHttpPromise() {
    return $http.get('/user/getCondition', {params: {condition: $scope.condition}).
        success(function (condition, status, headers, config) {
         ...
         ...
         if(condition)
             return true;//or any result you want to resolve
         else
             return getHttpPromise();
    }
}

getHttpPromise function returns promise, which will be resolved on your condition, in other case it will continues waiting with followed get request.

To use it, run the following code.

getHttpPromise().then(function (result) {
    // Will be called only when condition will be successful
});

Comments

2

$http.get is asynchronous call and it will hit the success or error (both are deprecated, use then) function on response from server. When the function reaches this line

sendGetReq = false;  // #1 execution reaches here

it makes the $http.get call (which is async) and then it moves the control to next iteration. That is the main purpose of async call.

If you want to make continuous calls you can write the $http.get call in a function and call that function using interval service of Angular JS.

$interval

$scope.func = function(){
   if(condition)
   {
      $http.get....
   }      
}

$interval($scope.func, 1000)

where 1000 is the time interval in milliseconds after which the function is called

2 Comments

with $timeout you call the function just one time. Maybe you need $interval but anyway is not a good solution. You should use the then (success) for call recursively your function
@gianlucatursi Edited my answer for $interval
1

Try this inject $interval in your controller

var startInterval = $interval(function(){
  var searchComplete = false;
  var sendGetReq = true;

        sendGetReq = false;  // #1 execution reaches here
        $http.get('/user/getCondition', {params: {condition: $scope.condition}).
        success(function (condition, status, headers, config) {
         if(condition)
         {   searchComplete = true;
            $scope.stopInterval();
         }
         else
         { sendGetReq = true; }
        })

},1000)

$scope.stopInterval = function(){
   $interval.cancel(startInterval)
}

Comments

1

As Andrew said it should be recursive and in your case use .then. To make it recursive encapsulate your $http service inside a function

.controller('YourController', function($http) {
this.sendGetReq= function(data) {
    $http.get('/user/getCondition', {params: {condition: data.condition}).
    .then(function(res) {
        if (res.condition) {
        //finish your search
        } else {
        //set newdata somehow   
          this.sendGetReq(newdata);
        }
    }
};

});

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.