Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the $q service with angular

I still can't understand the role of using the $q service, (what exactly will it add) if you want to create a service that need to call only one API via http , in this situation I don't know why shouldn't I just do the following (without using $q) :

this.getMovie = function(movie) {
  return $http.get('/api/v1/movies/' + movie)
    .then(
    function(response) {
      return {
        title: response.data.title,
        cost: response.data.price
      });
    },
    function(httpError) {
      // translate the error
      throw httpError.status + " : " +
        httpError.data;
    });
};
like image 406
Abdel Rahman Karim Avatar asked Apr 01 '16 20:04

Abdel Rahman Karim


People also ask

What does $q do in angular?

$q is integrated with the $rootScope. Scope Scope model observation mechanism in AngularJS, which means faster propagation of resolution or rejection into your models and avoiding unnecessary browser repaints, which would result in flickering UI.

What is Q defer () in AngularJS?

$q. defer() allows you to create a promise object which you might want to return to the function that called your login function.

How pass data from controller controller to AngularJS?

Approach: To share data between the controllers in AngularJS we have two main cases: Share data between parent and child: Here, the sharing of data can be done simply by using controller inheritance as the scope of a child controller inherits from the scope of the parent controller.

What is promises in AngularJS?

Promises in AngularJS are provided by the built-in $q service. They provide a way to execute asynchronous functions in series by registering them with a promise object. {info} Promises have made their way into native JavaScript as part of the ES6 specification.


1 Answers

Very good question and one very few people appreciate the answer to.

Consider this:

this.getMovie = function(movie) {
  return $http.get('/api/v1/movies/' + movie);
};

Great code but these rules apply:

$http will resolve for 2xx responses and will otherwise reject. sometimes we don't want this. we want to reject on resolution and resolve on rejection. This makes sense when you consider a HEAD request to check the existence of something.

A HEAD request to /book/fred returning 200 shows book fred exists. But if my function is testing whether book fred is unique, it is not and so we want to reject on a 200. this is where $q comes in. Now I can do this:

var defer = $q.defer();
$http.head('/book/fred').then(function(response) {
    // 2xx response so reject because its not unique
    defer.reject(response);
}).catch(function(failResponse) {
    defer.resolve(failResponse);
});
return defer.promise;

$q gives me total control of when I reject AND when I resolve.

Also, $q allows me to reject or resolve with any value. So if I am only interested in some of the response I can resolve with just the bit I am interested in.

Finally, I can use $q to turn non-promise based code into a promise.

var a = 5;
var b = 10;
var defer = $q.defer();
var resolve(a+b);
return defer.promise;

Bosh, if I need a promise as my return value then I've got one.

This is also great when mocking for unit tests.

like image 181
danday74 Avatar answered Oct 12 '22 23:10

danday74