1

The non-GET instance action $save doesn't work in my example. I always get the Error, that $save is not a function. The problem is, I don't know where I have to define the $scope.example = new Resource();, because in my example I'm using 2 Controllers. One for the table list with objects and the other one for my modal window, where you can take CRUD operations. The CRUD operations are defined in an angular service.

The code is structured as follows:

Servie of Resource:

...
return {
  name: $resource(baseUrl + '/api/name/:Id', {
     Id: '@Id'
  }, {
     'update': {
        method: 'PUT'
     }
  }),
...

Service of CRUD:

...
return {
   create: function (newName) {
      return newName.$save();
   },
...

Ctrl of modal window:

$scope.selected = new resService.name();
$scope.createItem = function (newName) {
   CrudService.create(newName).then(
        function () {
           $scope.dataSuccess = 'Person created.';
           $scope.newName = null;
        },
        function (err) {
           $scope.dataError = err.data.ModelState;
        });
   }
}

$scope.form = [{
                label: 'Firstname',
                fieldType: 'text',
                name: 'Fname',
                id: 'fname-id',
                propertyName: 'fname',
                disabled: false,
                pattern: /^[a-zA-Z]{4}[a-zA-Z]*/,
                required: true,
                errRequired: 'Firstname is required.',
                errPattern: 'Firstname has at least 4 letters.'
            },
...];

The view with form:

<form class="form-horizontal" name="editForm" novalidate>
  <div class="form-group-sm has-feedback" ng-repeat="elem in form" ng-class="{ 'has-error' : hasError(editForm, elem.name), 'has-success' : hasSuccess(editForm, elem.name) }">
     <label class="control-label" for="{{elem.id}}">{{elem.label}}</label>
     <input type="{{elem.fieldType}}"
            class="form-control" 
            placeholder="{{elem.label}}"  
            name="{{elem.name}}" 
            id="{{elem.id}}"
            ng-model="selected[elem.propertyName]" 
            ng-disabled="{{elem.disabled}}"
            ng-pattern="elem.pattern" 
            ng-required="{{elem.required}}"
            />

<p class="help-block" ng-if="elem.errRequired" ng-show="editForm[elem.name].$error.required && editForm[elem.name].$touched">{{elem.errRequired}}</p>
<p class="help-block" ng-if="elem.errPattern" ng-show="editForm[elem.name].$error.pattern">{{elem.errPattern}}</p>

EDIT: I'm getting a new Error. The console tells, that I have to use track by expression. But I was trying to use the form view without generating and then works. But I need the generated form view (the example view above).

Error Message:

Error: ngRepeat:dupes Duplicate Key in Repeater

Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys.

yuro
  • 2,189
  • 6
  • 40
  • 76

1 Answers1

0

If you wan't to create a new object you need the choose the service between the Services choice (factory, service, providers).

The difference between a factory and a service, is about syntax. Just syntax.

.factory(function(){

   //Private variables and functions
   var x = "ez";
   function getX(){
        return x;
   }

   //Public functions (or variables)
   return {
     a : "test",
     getA : function(){
        return a;    
     }
   }

})


//Service example

.service(function(){

   //Handled by Angular: 
   //new() is used to create a new object

  //Private functions and variables
  var x = "test";
  function getX(){
    return x;
  }

  //Public funcitons (and variables)
  this.a = function(){
     "test";
  };

  this.getA = function(){
    return a;
  };

  //Handeled by AngularJS 
  //return this;

});

Everything that is returned in the factory is available.
The service automaticaly creates a new object when calling it, which makes available the object ("this")

Calling a service or a factory remains the same:

var a = service.getA();
var a = factory.getA();

EDIT

Notice also that you can decide if your promise is going to the next error or success call.

Just as an exmaple:

xhr()
.then(success1, error1)
.then(success2, error2)
.then(success3, error3)
...

success and error are all callback functions. By using $q you can go to the next success or error, wathever the callback.

QUESTION CODE

 . factory ( 'YourFacotry' , [ '$resource' , 
       function ( $resource ) {    
          return $resource ( '/api/note/:id' , { id : '@id' }, 
             { 
               markAsDone : 
                 { 
                   url : '/api/note/:id/done' , 
                   method : 'POST' , 
                   isArray : true 
                  } 
             }); 
        }]);


Ctrl of modal window:

$scope.createItem = function () { //Forgot $scope here!
   CrudService.query().then(
        function () {
           $scope.dataSuccess = 'Person created';
           $scope.newName = null;
        },
        function (err) {
           $scope.dataError = err.data.ModelState;
        });
   }
}
gr3g
  • 2,866
  • 5
  • 28
  • 52
  • Thx gr3g but I already know it. I have created a factory. When I define `resService.name.save(newName);` then it saves the data in the DB. But when I'm using `return newName.$save()` then it doesn't work. In the first option I don't know how to send an Succ/Err Message to the view. – yuro Jul 07 '15 at 08:14
  • You are using ngRessource? – gr3g Jul 07 '15 at 08:18
  • I don't know `.$save`, but `.save()` is used with ngRessource – gr3g Jul 07 '15 at 08:21
  • I'm using ngResource that's right. the $save is a non-GET instance action: https://docs.angularjs.org/api/ngResource/service/$resource . It is better practice when you work with large data. Wait a moment I will updated my post – yuro Jul 07 '15 at 08:31
  • I've updated my post above. Please check out :). To your question. `$save` will used from the browser. It saves the object in the DB as well as `.save()` but the $save is better suitable for larger saving data. – yuro Jul 07 '15 at 08:45