Search code examples
javascriptangularjsrestangularwordpress-rest-api

creating a service in angularJS, using restangular promises


Ok, this is driving me mad, basically what I am trying to do is create a service to get and evaluate user capabilities, I am using WP REST API. I use restangular to get my JSON data.

At this stage I am testing the function in the controller itself, but no matter where I test it, be it in my custom service using this.method or inside the controller, with or without using $scope the result is always undefined. I know I am missing something either in the way I am returning true or false inside the function, or there is something fundamentally different when it comes to promises in JS. Here is the code:

    var current_user = parseInt(o2_i18n.user_id),
        currentUserCapabilities,
        capability;

    $scope.currentUserCan = function(capability) {
        if(current_user !== '0') {
            wpAPIResource.one('users').get()
            .then(function(allUsers){
                for (var i = 0; i < allUsers.length; i++) {
                    if ( allUsers[i].id === current_user ) {
                        var currentUserCapabilities = allUsers[i].capabilities;
                        for(var prop in currentUserCapabilities){
                            if (capability === prop) {
                                //$log.log( prop );
                                return prop;
                            } else {
                                //$log.log( prop );
                                return false;
                            }
                        }
                    }
                }
            }, function(reason){
                $log.error(reason);
            });
        } else {
            //The user is not logged in, therefor no capabilities
            return false;
        }
    };

    $log.log($scope.currentUserCan('publish_posts'));

    if ( $scope.currentUserCan('publish_posts') ) {
        $log.log( 'Yes I Can!' );
    } else {
        $log.warn('No Can\'t Do!');
    }

Solution

  • Your currentUserCan function doesn't return anything if current_user !== '0'. You should have it return a promise, for example (for the following you'll need to inject the $q service)

    $scope.currentUserCan = function(capability) {
        if(current_user !== '0') {
            // note the "return" here
            return wpAPIResource.one('users').get().then(function(allUsers){
                for (var i = 0; i < allUsers.length; i++) {
                    if ( allUsers[i].id === current_user ) {
                        var currentUserCapabilities = allUsers[i].capabilities;
                        for(var prop in currentUserCapabilities){
                            if (capability === prop) {
                                return prop;
                            }
                        }
                    }
                }
                return false;
            }, function(reason){
                $log.error(reason);
                return $q.reject(reason); // you still want the promise to fail
            });
        } else {
            return $q.resolve(false);
            // this turns the static value into a promise so the API for this
            // function is consistent
        }
    };
    

    then consume the function like this

    $scope.currentUserCan('publish_posts').then(function(can) {
        if (can) {
            $log.log('Yes I Can!');
        } else {
            $log.warn("No Can't Do!");
        }
    });
    

    I also cleaned up your loop a little. In your OP, there was no point in the inner loop and you didn't have a return value if the user was not found in the allUsers array.