Tamy
Tamy

Reputation: 203

Using controllerAs with $resource in AngularJs

I am working on an application and I'd like to use the controllerAs syntax to not rely only on $scope. I am using $resource to get data from the API and the problem I encounter is that in the success/error callbacks I can use only $scope, since this is not defined.

Here is some code to better explain the problem.

This is my main module where among other things I configure the router:

angular
    .module('app', ['ngRoute', 'ngResource', 'LocalStorageModule', 'app.users', 'app.auth'])
    .config(configure)
    .controller('MainController', ['$scope', '$location', MainController]);

function configure($routeProvider, localStorageServiceProvider, $resourceProvider) {
    // configure the router
    $routeProvider
        .when('/', {
            templateUrl: 'app/homepage.html',
            controller: 'MainController',
            controllerAs: 'vm',
            data: { authRequired: true }
        })
        .when('/users', {
            templateUrl: 'app/users/main.html',
            controller: 'UserController',
            controllerAs: 'vmu',
            data: { authRequired: true }
        })
        .otherwise({redirectTo: '/'});
}
// the MainController is not relevant here

In the user module I get some info about the users from the API. Here is a simplified example:

angular
    .module('app.users', ['ngResource'])
    .controller('UserController', ['UserService', UserController])
    .factory('UserService', ['$resource', UserService]);

function UserController(UserService) {
    this.users = UserService.users.list();

    this.getUserInfo = function(userId) {
         this.user = UserService.users.single({ id: userId },
             function(success) {
                 // here I'd like to use 'this' but the following line will trigger an error
                 this.groupRules = UserService.users.rules({ id: success.userGroupId });
                 // I have to use $scope instead but it is not what I want
                 // $scope.groupRules = UserService.users.rules({ id: success.userGroupId });
             } );
    }
}

function UserService($resource) {

    var userResource = {};

    userResource.users = $resource('https://my.api.com/users/:action',
        {},
        {
            list: { method: 'GET', isArray: true, params: { action: 'list' } }
            single: { method: 'GET', params: { action: 'single', id: '@id' } }
            rules: { method: 'GET', params: { action: 'getRules', id: '@id' } }
        });

    return userResource;
}

I'd like to be able to use 'this' in the callback of the $resource, but of course I'll get an error since 'this' is 'undefined' inside the callback. Using $scope solves the problem, but I need to refactor some code and I'd like to avoid using $scope all the time.

Any workaround? Maybe I should use a different approach?

Thanks in advance for your help and explanations!

Upvotes: 1

Views: 129

Answers (1)

jlowcs
jlowcs

Reputation: 1933

You should look into how to use this in javascript and into javascript scopes and closures.

This should work better:

function UserController(UserService) {
    var _this = this;

    this.users = UserService.users.list();

    this.getUserInfo = function(userId) {
         _this.user = UserService.users.single({ id: userId },
             function(success) {
                 // here I'd like to use 'this' but the following line will trigger an error
                 _this.groupRules = UserService.users.rules({ id: success.userGroupId });
             } );
    }
}

Upvotes: 2

Related Questions