Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when to use $q.defer() in Angularjs

I am new to Angularjs and I m following this tutorial :http://mherman.org/blog/2015/07/02/handling-user-authentication-with-the-mean-stack/#.WE70iubhCM8 . However i dont understand when to use $q.defer(). For example in the folllowing Angularjs code why use $q.defer() :

function login(username, password) {

      // create a new instance of deferred
      var deferred = $q.defer();

      // send a post request to the server
      $http.post('/user/login',
        {username: username, password: password})
        // handle success
        .success(function (data, status) {
          if(status === 200 && data.status){
            user = true;
            deferred.resolve();
          } else {
            user = false;
            deferred.reject();
          }
        })
        // handle error
        .error(function (data) {
          user = false;
          deferred.reject();
        });

The server side code is :

router.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) {
      return next(err);
    }
    if (!user) {
      return res.status(401).json({
        err: info
      });
    }
    req.logIn(user, function(err) {
      if (err) {
        return res.status(500).json({
          err: 'Could not log in user'
        });
      }
      res.status(200).json({
        status: 'Login successful!'
      });
    });
  })(req, res, next);
});

And why not use it in the following Angularjs code :

 function getUserStatus() {
      return $http.get('/user/status')
      // handle success
      .success(function (data) {
        if(data.status){
          user = true;
        } else {
          user = false;
        }
      })
      // handle error
      .error(function (data) {
        user = false;
      });
    }

Server side code is :

router.get('/status', function(req, res) {
  if (!req.isAuthenticated()) {
    return res.status(200).json({
      status: false
    });
  }
  res.status(200).json({
    status: true
  });
});
like image 324
juliana Morales Avatar asked Dec 01 '22 15:12

juliana Morales


1 Answers

Simply put you can use $q.defer() to create a Promise. A Promise is a function that returns a single value or error in the future. So whenever you have some asynchronous process that should return a value or an error, you can use $q.defer() to create a new Promise.

In most cases though, Angular has already done this for you and you can simply use the Promise that is returned, for instance by the $http service. Your example shows a good example of when you'd want to create your own.

You see, normally the $http service returns the value from the server, or an error when the http call fails. In your example however you also want to return an error from the Promise (= reject it) when the http call itself success, but has a not-true value for the success property.

To do this, the example creates a new Promise whose return value (or error) can then be manually controlled. In this example by calling the resolve() (= return the value) function only when the http call is successful and has data.success == true. In all other cases (when the http call fails or doesn't have the correct data.status value) the newly created Promise is rejected (= return error).

like image 118
Robba Avatar answered Jan 01 '23 08:01

Robba