2

I am new in angular $q service.I'm using $http with angular $q service for implementing asynchronous requests. Here in below is my codes which I can't get the result of backend api. (json)

Services.js :

.service('httpService', function($q, $http, $timeout) {

 var asyncRequest = function(url) {
    return $http.get(url)
        .then(function(response) {
            //res is the index of an array in php, which will be encoded.
            return response.res;

        }, function(response) {
            // something went wrong
            return $q.reject(response.res);
        });
 };
 return {
   asyncRequest : asyncRequest 
 };

});

Controller.js :

var result = httpService.test(url)
.then(function(data) {
    // Line below gives me "undefined"
    console.log(data);
}, function(error) {
    alert("Error...!");
});

The mentioned line, gives me undefined. (Of course, I can write console.log(data) in main function, But it's not a good practice, because I want to return result to controller)

About my implementation of $q service, is there any easier way?

Any idea would be greatly appreciated.

Vahid Najafi
  • 4,654
  • 11
  • 43
  • 88
  • 1
    It should be `response.data`, instead of `response.res`. If `res` is an index of the response data object returned by your server then simply return `response.data.res`. – ryeballar Nov 29 '15 at 16:15
  • @ryeballar Yes, the combination of your note and Simon's answer made the right solution. Thank you all. – Vahid Najafi Nov 29 '15 at 16:53

5 Answers5

5

You should not use $q in this instance, as $http already returns a promise. Using to 2 together in inefficient. ($q is of use if you are using a non-angular async function, such as a Geo lookup).

Services.js :

.service('httpService', function($http, $timeout) {

  var asyncRequest = function(url) {
    return $http.get(url)
  };
  return {
   asyncRequest : asyncRequest 
  };

});

Controller.js :

var result = httpService.asyncRequest(url)
.then(function(res) {
    console.log(res.data);
}, function(error) {
    alert("Error...!");
});
Simon H
  • 20,332
  • 14
  • 71
  • 128
  • Thank you so much. And one more question. How can I make it nested? I mean another `$http` depends on the first one's result. – Vahid Najafi Nov 29 '15 at 17:03
1

First thing is that you are using factory style instead of service. service is just a function where methods are defined on this reference .

I think you don't need to use .then in service just return the promise returned by $http

app.service('httpService', function($q, $http, $timeout) {

  this.asyncRequest = function(url) {
    return $http.get(url);
  };
});

And in controller

 var result = httpService.test(url)
  .then(function(res) {
    // Line below gives me "undefined"
    console.log(res.data);
  }, function(error) {
    alert("Error...!");
  });
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60
1

I think you are using the syntax for at factory on your service.

.service('httpService', function($q, $http, $timeout) {
   this.asyncRequest = function(url) {};
});

or

.factory('httpService', function($q, $http, $timeout) {
   return {asyncRequest: function(url) {}};
});
pethel
  • 5,397
  • 12
  • 55
  • 86
0

The response is already rejected in the mentioned line. You don't need to reject anything else. So you don't need to $q.

First you already return a promise. You can handle it in the controller with adding success() and error() delegates of the $http promise. Second, this is async operation. And you can't return a response from the success callback like jQuery.ajax(). This is not synch call, this is asynch call and you have to use callbacks. Your mistake is here. Just return promise and handle it in controller when the response will has been resolved or rejected.

So your controller code can be like this:

httpService.asyncRequest({
    ...
}).success(function(successfulResponse) {
    ...
}).error(function(failedResponse) {
    ...
});
Onur Gazioğlu
  • 501
  • 2
  • 12
  • 4
    **[Deprecation notice for both `success()` and `error()`](https://docs.angularjs.org/api/ng/service/$http#deprecation-notice)** – ryeballar Nov 29 '15 at 16:23
-4
.service('httpService', function($q, $http, $timeout) {

 var asyncRequest = function(url) {
   var defer = $q.defer();
    return $http.get(url)
        .then(function(response) {
            //res is the index of an array in php, which will be encoded.
            defer.resolve(response);

        }, function(response) {
            // something went wrong
            defer.reject(response.res);
        });
     return defer.promise;
 };
 return {
   asyncRequest : asyncRequest 
 };

});

you should return promise from your object like this

Bharat Bhushan
  • 2,077
  • 2
  • 21
  • 34
  • @Bergi BTW I didn't copy your answer. I used the same service like this in many on my project. and one more thing my answer is different as you mentioned in link. there is no any catch block in my code. anyway I respect the community and all respected members like you. so no issues if my answers is down vote from your side. – Bharat Bhushan Nov 30 '15 at 04:04
  • Copy of an answer? No, all I'm saying is that "*you should* not *return promise from the object like this*". Using [`.then(…, …)` instead of `.then(…).catch(…)`](http://stackoverflow.com/q/24662289/1048572) is ok here, but makes no difference, it's still the deferred antipattern. – Bergi Nov 30 '15 at 09:28
  • Btw, I didn't even downvote, it was 5 other people, some of whom seemed to agree with me. – Bergi Nov 30 '15 at 09:29