15

It is possible to define an Angular $resource that has always the same default values on creation with new()?

For example if I have the following resource definition:

var Drawer = $resource('/drawer/:drawerId', { drawerId: '@id'});

And the Drawer object needs to have a "socks" property that I want to be always initialized as an empty array [], and maybe some others like 'timesOpened' to 0, or things like that.

The only way to do this would be like:

var newDrawer = new Drawer({ socks: [], timesOpened: 0});

I was thinking about defining in the same service I have for my resource (let's call it drawerService) a default/initialization object like this:

defaultDrawer = { socks: [], timesOpened: 0};

And then when creating the resource:

//New drawer with defaults
var newDrawer = new drawerService.Drawer(drawerService.defaultDrawer);
//New drawer with defaults and some other initialization
var anotherDrawer = new drawerService.Drawer(angular.extend(drawerService.defaultDrawer, {material: 'plastic'});

Is this the only way of doing it?

John Bernardsson
  • 1,751
  • 1
  • 17
  • 19

2 Answers2

13

You are correct, there is no easy way to do this; it is not a supported functionality in Angular. A cleaner way that you might do this is by creating a Drawer factory in your drawerService. It might look something like this:

angular.module('app').factory('drawerService', function() {

    var Drawer = $resource('/drawer/:drawerId', { drawerId: '@id'});

    function drawerFactory(options) {
        var defaults = {
            socks: [],
            timesOpened: 0
        };
        options = angular.extend(defaults, options || {});
        return new Drawer(options);
    }

    return {
        Drawer: Drawer,
        create: drawerFactory
    };
});

This would allow you to create a new Drawer like so:

//New drawer with defaults
var newDrawer = drawerService.create();
//New drawer with defaults and some other initialization
var anotherDrawer = drawerService.create({material: 'plastic'});

It's still not ideal, but it is slightly cleaner and the least evil way I can think of accomplishing what you are trying to accomplish.

kanzelm3
  • 535
  • 3
  • 12
  • Hey @kanzelm3, sorry for not coming here earlier. So your answer is a improved and cleaner version of what I posted :) I like it, but I am going to leave this a little more time just in case some other idea cames in. If not, I'll mark your answer as the correct one! Thank you very much! – John Bernardsson Aug 17 '15 at 11:09
0

I ran into this problem recently, and this was the first post that came up on Google... The answer provided works, however it is pretty messy, and changes the way that you have to interact with your $resource object. There is a much simpler way :)

angular.module('app').factory('drawerService', function() {
  var drawer = $resource('/drawer/:drawerId', { drawerId: '@id'});

  drawer.prototype.socks = [];
  drawer.prototype.timesOpened = 0;

  return drawer;
}

And then you'd simply create a new object with defaults as follows:

var drawer = new drawerService();

And you can also pass in your own params here too...

var drawer = new drawerService({ material: 'plastic' });

Hope this can help someone in the future :D

NightCabbage
  • 469
  • 4
  • 12
  • This does not work as intended. The prototype members will be "static", i.e. shared accross all instances. Should only be used for functions. – Thomas F. Jun 01 '16 at 10:08