AngularJS – creating a service object

All we need is an easy explanation of the problem, so here it is.

Instead of posting in Angular mailing list, I think this may be more of javascript question. Hope the SO community can also give faster response.

I am trying to encapsulate the data in a service and injecting into controller.

angular.module('myApp.services', ['ngResource']).
    factory('Player', function($resource){
        var Player ;
        Player = {
            resource: $resource('/api/Player/:_id', {} )
        };
        return Player
});


function PlayerDetailCtrl(Player, $routeParams, $scope) {
    $scope.resource = Player.resource.get({_id:$routeParams._id});
}
PlayerDetailCtrl.$inject = ['Player', '$routeParams', '$scope'];

It throws an exception

TypeError: Object #<Object> has no method 'query'

$scope.resource = Player.Player.resource.get({_id:$routeParams._id}); also throws error

TypeError: Object #<Object> has no method 'query'

the below works.

angular.module('myApp.services', ['ngResource']).
    factory('Player', function($resource){
        var Player ;
        Player= $resource('/api/Player/:_id', {} )
        return Player
});


function PlayerDetailCtrl(Player, $routeParams, $scope) {
    $scope.resource = Player.Player.get({_id:$routeParams._id});
}
PlayerDetailCtrl.$inject = ['Player', '$routeParams', '$scope'];

my intention is to add more data and method to Player. So how can I make the first (object form) works!

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You are creating a factory, this is the atypical way of doing. You don’t want to be returning an instance. Angular will give you an instance in your controller.

 factory('Player', function ($resource) { 
    return $resource('/api/Player/:_id', { });
 })

Here is a service I wrote to interact with a cakephp REST service. I wrote it a while back so just take it as an illustration, I may refactor.

 factory('CommentSvc', function ($resource) {
    return $resource('/cakephp/demo_comments/:action/:id/:page/:limit:format', { id:'@id', 'page' : '@page', 'limit': '@limit' }, {
      'initialize' : { method: 'GET', params: { action : 'initialize', format: '.json' }, isArray : true },
      'save': { method: 'POST', params: { action: 'create', format: '.json' } },
      'query' : { method: 'GET', params: { action : 'read', format: '.json' } , isArray : true },
      'update': { method: 'PUT', params: { action: 'update', format: '.json' } },
    });

}).

Method 2

Looks like the JS is complaining about some code for Player. I guess Player= $resource('/api/Player/:_id', {} ) makes Player have a property call query. The form you changed to does not make Player have that property.

Method 3

Ok, after few tries the following worked.

Player = {
            resource: function() {
                     return $resource('/api/Player/:_id', {} )
            }
        };

In this I explicitly return resource object. But cannot explain how it differ from

resource: $resource('/api/Player/:_id', {} )

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply