21

I have an angular resource that goes something like this

app.factory('User', function ($resource) {
    return $resource(
        '/api/user/:listCtrl:id/:docCtrl/', {
            id: '@id',
            listCtrl: '@listCtrl',
            docCtrl: '@docCtrl'
        }, {
            update: {
                method: 'PUT'
            },
            current: {
                method: 'GET',
                params: {
                    listCtrl: 'current'
                }
            },
            nearby: {
                method: 'GET',
                params: {
                    docCtrl: 'nearby'
                },
                isArray: true
            }
        }
    );
});

now i want to have full name in the view, can i add a method so that when i do this

$scope.user = User().current();

instead of doing the following in html

<p>{{ user.first_name }} {{ user.last_name }}</p>

i do this

<p>{{ user.get_full_name }}</p>

is there a way to add this property to the $resource?

falinsky
  • 7,229
  • 3
  • 32
  • 56
Yousuf Jawwad
  • 3,037
  • 7
  • 33
  • 60

3 Answers3

56

You can add it as a property using transformResponse, but might I suggest just adding a method to every object that returns the combined first and last name:

app.factory('User', function ($resource) {
    var User = $resource(
        '/api/user/:listCtrl:id/:docCtrl/', {
            id: '@id',
            listCtrl: '@listCtrl',
            docCtrl: '@docCtrl'
        }, {
            update: {
                method: 'PUT'
            },
            current: {
                method: 'GET',
                params: {
                    listCtrl: 'current'
                }
            },
            nearby: {
                method: 'GET',
                params: {
                    docCtrl: 'nearby'
                },
                isArray: true
            }
        }
    );
    // add any methods here using prototype
    User.prototype.get_full_name = function() {
        return this.first_name + ' ' + this.last_name;
    };
    return User;
});

Then use:

<p>{{ user.get_full_name() }}</p>

Any functions added using prototype will be added onto every object returned by your Service. It is a great way to add helper methods if you need to do complicated getting or setting of service properties.

Jeremy Zerr
  • 874
  • 7
  • 12
  • Works fine. Just make sure you qualify properties with `this.`, tripped over this... – Tim Büthe Nov 28 '14 at 16:18
  • 1
    Thank you for answering the actual question, instead of providing 'better' alternatives for the specific scenario of the original asker. – RonLugge Dec 03 '15 at 00:56
  • @RonLugge aye aye captain. like Tim said, just make sure you take care of this. – Yousuf Jawwad Dec 29 '16 at 21:45
  • Please, note that if your method is an array one (isArray:true), the resulting object WILL NOT contain your method as AFAIK arrays prototype is read-only. – marco6 Feb 01 '17 at 09:46
  • Why do I have to add the method to the prototype and not the object directly? – gskema Apr 28 '17 at 12:30
5

after playing for a while with angular, I think a customer filter would be a much wiser approach, rather than adding a property on $resource.

here is how to do a filter

app.filter('getFullName', function () {
    return function (input) {
      if (input) {
        return input.first_name + ' ' + input.last_name;
      } else {
        return 'default';
      }
    };
  });
Yousuf Jawwad
  • 3,037
  • 7
  • 33
  • 60
1

I think you should look at transformResponse way.

Btw, what version of angularjs do you use?

falinsky
  • 7,229
  • 3
  • 32
  • 56
  • i am using angular 1.1.5 ... never looked at transformResponse before, let me check it out, thanks for the pointer – Yousuf Jawwad Aug 09 '13 at 00:11
  • you can look at http://stackoverflow.com/questions/17134401/angular-extending-resource-subobject-with-custom-methods – falinsky Aug 09 '13 at 00:11