5

I've followed the examples but apparently something is wrong when adding a custom method to the resource's prototype.

app.factory('Product',function ($resource,$cacheFactory) {
        var Product = $resource('/the/url/:id', {id: '@id'}),
            cache = $cacheFactory('Product'),
            products;
        Product.prototype.all = function(){
            products = cache.get('all');
            if(typeof products == 'undefined'){
                products = Product.query();
                cache.put('all',products);
            }
            return products;
        };
        return Product;
    })

In the controller I do $scope.products = Product.all(); but I get

TypeError: Object function Resource(value) {
    copy(value || {}, this);
} has no method 'all'
1
  • Can you provide the link for the example of adding to the $resource's prototype? I don't remember ever seeing that. Commented Mar 4, 2013 at 14:55

2 Answers 2

12

Product.prototype.all defines an instance method.

You should define it as static method Product.all = function(){...].

Only then you can call it with $scope.products = Product.all();.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I dont know why at this point I make that kind of mistake XD
Understandable. These simple bugs often slip through easily in complex projects, or on long days.
3

I think it's because you don't actually have an instance yet. You would need to do this:

$scope.products = new Product();
// now you can run the all function
$scope.products.all()

Your other option would be to define the all() method on the service level. Instead of adding to the prototype, which is only available after new Product(), you could modify like:

app.factory('Product',function ($resource,$cacheFactory) {
    var Product = $resource('/the/url/:id', {id: '@id'}),
        cache = $cacheFactory('Product'),
        products;
    Product.all = function(){
        products = cache.get('all');
        if(typeof products == 'undefined'){
            products = Product.query();
            cache.put('all',products);
        }
        return products;
    };
    Product.prototype.$all = function () {
        Product.all.call(this);
    }
    return Product;
})

This way you will have Product.all() on the resource and product.$all() on instances.

2 Comments

When the resource is injected isn't it an instance of the defined service? How can I do this without instantiating the service?
When it's injected, you get an instance of the service, yes, but not an instance of a resource. Updating answer to include how you could call a service-level all() method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.