Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular $q.reject().success(), does that make sense?

I'm reading a book called MEAN Machine, and as I'm getting to the late chapters, I've got stuck at one of the sample applications, that doesn't seem to work.

The problem seems to occur because my mainController calls authService's Auth.getUser() method, which may return either a $http.get() or a $q.reject(). As I'm not logged in, it returns $q.reject(), and fails to chain the .success() promise.

It throws following exception:

TypeError: undefined is not a function at mainCtrl.js:13

My code is as follows.


CONTROLLER
mainController

angular.module('mainCtrl', [])
    .controller('mainController', function($rootScope, $location, Auth) {
        var vm = this;

        // check to see if a user is logged in on every request
        $rootScope.$on('$routeChangeStart', function () {
            vm.loggedIn = Auth.isLoggedIn();

            // get user information on route change
            Auth.getUser()

                /* ========= PROBLEM HERE ========= */
                .success(function (data) {
                    vm.user = data;
                });
        });

        // ... other stuff
    });

SERVICE
authService

angular.module('authService', [])

    // ===================================================
    // auth factory to login and get information
    // inject $http for communicating with the API
    // inject $q to return promise objects
    // inject AuthToken to manage tokens
    // ===================================================
    .factory('Auth', function ($http, $q, AuthToken) {

        var authFactory = {};

        // get the user info

        /* ========= PROBLEM LEADS HERE ========= */

        authFactory.getUser = function () {
            if (AuthToken.getToken())
                return $http.get('/api/me', { cache: true });
            else {
                return $q.reject({ message: 'User has no token.' });
            }
        }

What am I missing?

like image 746
Charles Avatar asked Mar 14 '15 14:03

Charles


People also ask

Is there an equivalent of $Q reject in AngularJS?

In AngularJS, the $q services has a top-level method, $q.reject (), which will create a promise that is immediately rejected with the given value. Ever since I saw this method, I have always wondered where the "resolve" equivalent was?

How to reject a promise immediately in AngularJS?

In AngularJS, the $q services has a top-level method, $q.reject(), which will create a promise that is immediately rejected with the given value.

How does $Digest work in AngularJS?

If you create a promise with $q, AngularJS will automatically trigger a $digest whenever the promise is exercised, either with reject, resolve, or notify. If, however, you get a promise from a non-AngularJS source, then you don't have that digest-integration.

Is there a $Q resolve () method in AngularJS?

In AngularJS, the $q services has a top-level method, $q.reject (), which will create a promise that is immediately rejected with the given value. Ever since I saw this method, I have always wondered where the "resolve" equivalent was? If there's a $q.reject (), why not a $q.resolve ()? Well, it turns out there is.


1 Answers

Replace your call to the service with:

Solution A: .then(successCallback, errorCallback):

Auth.getUser().then(
    function (response) { ... },                // success handler
    function (response) {                       // error handler
        // case where user is not logged in
        // or http request fails
});

or

Solution B: .then(successCallback).catch(errorCallback):

Auth.getUser()
    .then(function (response) { ... })         // success handler
    .catch(function (response) {               // error handler
        // case where user is not logged in
        // or http request fails
    });

Explanation :

Your getUser method is defined as follows :

authFactory.getUser = function () {
    if (AuthToken.getToken())
        return $http.get('/api/me', { cache: true });
    else {
        return $q.reject({ message: 'User has no token.' });
    }
} 

But the success and the error shorthand methods are specific to $http. They doesn't exist in angular's promise $q API. Therefore, when the user is not logged in, because you are returning a $q promise, you got an undefined is not a function.

The methods you can call on a $q promise object are (link to documentation) :

  • then(successCallback, errorCallback, notifyCallback)
  • catch(errorCallback) which is a shorthand for promise.then(null, errorCallback)
  • finally(callback, notifyCallback)
like image 83
Michael P. Bazos Avatar answered Oct 15 '22 22:10

Michael P. Bazos