Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a problem with Angularjs (v1.2.14) using $http post, the returned value from the ajax call is not consistent in view. That means the code actually works, but sometimes when I reload the page ( Ctrl + F5), the data doesn't show up ( like an empty obj ), but when I try to reload the page, data will either shows up or not ( like 50-50% chance )

Here's a bit of my code:

myGuitarApp.service('songService', ['$http','$q', function( $http, $q ){

this.list = function(){

    return $http
    .post("getSongs.php") // return all songs from my DB in json
    .success( function( data ){
        console.log("1: ajax done");
        })
    .error( function(){
        console.log("error");
        });
}
}])

myGuitarApp.controller('returnAllSongs', function( $scope, $http, songService){

songService.list().then(
    function( data ){
        console.log( data );
        $scope.songs = data.data;
    }, function( data ){
        console.log("not success");
});
});

I've read up on some articles about using $q or deferred object on situation like this, but still not lucky, the same problem still happens .

UPDATE 1: I did try with $q method but the returned data still shows up randomly ( empty obj or full data ). Checking in the console log, I found out the line "return promise" always appears before the "ajax done". Is this a problem or something ?

this.list2 = function(){
    var defer = $q.defer();

    $http
    .post("getSongs.php")
    .success( function( data ){
        console.log("1: ajax done");
        defer.resolve(data);
        })
    .error( function(){
        console.log("error");
        defer.reject();
        });
    console.log("return promise");
    return defer.promise;
}
share|improve this question
    
@andrbmgi actually I just post the update part to show that I've tried the $q method but still doesn't work. I still keep the current code with return $http.post("getSongs.php") . Thanks –  Duc Hong Apr 3 at 3:21
    
return promise appears before ajax done because of the asynchronicity of this code. This is expected and correct. The post request is issued and the program just continues performing the return promise output and more, all before the post request is finished. Once the server responded one of the functions you defined in success and error is called. –  andrbmgi Apr 3 at 3:22
    
I transformed my first, now deleted comment into an answer. –  andrbmgi Apr 3 at 3:24
add comment

2 Answers

up vote 1 down vote accepted

The $http service already returns a promise, so if your songService does not handle the data in between there is no need to wrap it inside of another promise. Keep in mind though that the server might send some unexpected message with a non-error http code, in that case the promise would be fulfilled. I added debug output to the console. Check what the server returns.

myGuitarApp.service('songService', ['$http', '$q',
  function($http, $q) {

    this.list = function() {

      return $http.post("getSongs.php");

    }

  }
]);

myGuitarApp.controller('returnAllSongs', ['$scope', '$http', 'songService', function($scope, $http, songService) {

  songService.list().then(
    function(data) {
      console.log("success");
      console.log(data);
      $scope.songs = data.data;
    }, function(data) {
      console.log("not success");
      console.log(data);
    });
}]);

You might want to keep the post request wrapped to perform a check on success. Say the server sometimes returns something unexpected, you could do something like:

myGuitarApp.service('songService', ['$http', '$q',
  function($http, $q) {
    this.list = function() {
      var deferred = $q.defer();

      $http.post("getSongs.php").success( function(response) {
        if ( response.indexOf("loading") > -1 ) { // loading would be the unexpected response, you can turn that around and search for something known in the expected response
          deferred.reject(response);
        } else {
          deferred.resolve(response);
        }
      }).error( function(response) {
        deferred.reject(response);
      });

      return deferred.promise;
    }
  }
]);

Alternatively you could as well perform that test in the controller. The question where it fits best is something you have to consider.

share|improve this answer
    
thanks, one thing I forgot to mention that this happened when I was testing on my local pc, but I when tried it on my laptop or on a hosting it seems like the problem has gone. Tried hitting ctrl + f5 to reload the page like 15-20 times and it always return full data... that's weird –  Duc Hong Apr 3 at 3:45
add comment

in the success function do return the data

 .success( function( data ){
    console.log("1: ajax done");
    return data;
    })

you also need to return a promise

this.get = function(from, to){
        var deferred = $q.defer();
        var url = 'user/activities?from='+from+'&to='+to;
        $http.get(url).success(function(data, status) {
            // Some extra manipulation on data if you want...
            deferred.resolve(data);
        }).error(function(data, status) {
            deferred.reject(data);
        });

        return deferred.promise;
    }

so in your case that would be var deferred = $q.defer();

return $http
.post("getSongs.php") // return all songs from my DB in json
.success( function( data ){
    console.log("1: ajax done");
            deferred.resolve(data);
    })
.error( function(){
    console.log("error");
            deferred.reject();
    });

        return deferred.promise;
    }
share|improve this answer
    
thanks but it still doesn't solve the problem, I've tried it with or without that "return data", the data still shows up randomly –  Duc Hong Apr 2 at 19:01
    
edited the answer –  HarishR Apr 2 at 19:06
    
I've tried your method of using deferred, but the same problem still happens :( –  Duc Hong Apr 2 at 19:17
    
Console log data on http success.check if that's always coming, else it might be a server issue. But you would need q service hence don't remove that code –  HarishR Apr 3 at 2:27
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.