javascriptangularjsangularjs-resource

How to create an empty $resource when using the factory pattern


I am using angular $resource in a factory pattern, where it is injected, so I only have to create the templates once and in one place. This works.

I can not seem to find any documentation on how to create a new resource object. This creates conditional branching when it is time to save, as I do not have an object to call $save() on.

For example: imagine I have this resource:

myService.factory('myWidget', [ '$resource',
  function($resource){
    return $resource('/my/widget/:id', {
  [...]

So my controller can easily get access to myWidget thusly:

function( $scope, ... myWidget ) {

    $scope.widget = myWidget.get({id: 'myId'});
    $scope.save = function() {
        $scope.widget.$save(); // plus progress dialog error handling etc
    };
}

Which is very clean and awesome and as it should be. However, if I want to create a new one, I need conditional code both on create and save.

function( $scope, ... myWidget, mode ) {

    if (mode === 'create') {
        $scope.widget = {
            id: 'myNewId',
            property: <lots and lots of properties>
        };
    }
    else {        
        $scope.widget = myWidget.get({id: 'myId'});
    }

    $scope.save = function() {
        $scope.widget.$save(); // Not a $resource; $save() does not exist
    };
}

Obviously, I can put conditional code in save(), or I can pass the widget as a parameter, as myWidget.save($scope.widget), but that seems lame. Is there no easy way to simply create a new $resource from the factory? IE:

    if (mode === 'create') {
        $scope.widget = myWidget.new({
            id: 'myNewId',
            property: <lots and lots of properties>
        });
    }

This would be functionally equivalent to :

    if (mode === 'create') {
        $scope.widget = $resource('/my/widget/:id');

But obviously without duplicating the resource code in the factory.

Surely there is some easy syntax for doing this. Yes?

I am using AngularJS 1.3. I really hope this is a stupid question as it seems like something that is an obvious use case. Even Backbone has a way to create a new REST-backed object with default values. :) Thanks much.

(Maybe the question should be "how do I create an object using the angularjs factory, as if I were the injector?")


Solution

  • You need to be creating a new widget:

    if (mode === 'create') {
        $scope.widget = new myWidget();
        $scope.widget = {
            id: 'myNewId',
            property: <lots and lots of properties>
        };
    }