0

This is the example at : http://docs.angularjs.org/api/ngResource/service/$resource all the way at the bottom.

 // First get a note object from the factory
 var note = Notes.get({ id:$routeParams.id });
 $id = note.id;

 // Now call update passing in the ID first then the object you are updating
 Notes.update({ id:$id }, note);

I'm not too sure what this part is doing though. Currently i use get like so:

MyService.get(function(data){//do stuff with data}); and after making my updates I'd like to call MyService.update()

The parts I'm not clear on: What is the object being passed to Notes doing? Why does Notes.update need to have 2 parameters passed to it? I'm currently getting the data fine but I'm getting some errors when trying to PUT. All the examples use these parameters though so I'm just wondering what these parameters are used for.

*Specifically the error is "Method PUT is not allowed by Access-Control-Allow-Methods." even though it is. Strangely, I click on the error in Chrome networks tab and it says 200 OK. I'm guessing the OPTION command went through to check if PUT is allowed but then PUT fails.

 Request Method:OPTIONS
 Status Code:200 OK

 Access-Control-Request-Headers:accept
 Access-Control-Request-Method:PUT

 Access-Control-Allow-Headers:*
 Access-Control-Allow-Methods:*
 Access-Control-Allow-Origin:*
 Access-Control-Max-Age:3600
 Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
 Content-Length:0
 Date:Mon, 17 Mar 2014 21:39:26 GMT
 Server:Apache-Coyote/1.1
user2483724
  • 2,089
  • 5
  • 27
  • 43

2 Answers2

2

You can use your resource in 2 ways for your example, and that is what you are seing...

app.factory('Notes', ['$resource', function($resource) {
    return $resource('/notes/:id', null, { 'update': { method:'PUT' } });
}]);

So the first way to update a note:

Notes.update({ id: 42 }, { Content: "My Note" }); 

As demonstrated on the site, first object is a parameter object, so you will put to "/notes/42", second object is the object you will put, meaning that will be the content for the request.

There is also a second option should also work:

var note = Notes.get({ id: 42 });
note.Content = "Changed the note";
node.$update({ id: 42 });

Finally, if you configure your resource to map properties on the returned entity to parameters, you can avoid providing the ID in the $update call like so:

app.factory('Notes', ['$resource', function($resource) {
    return $resource('/notes/:id', { id:'@ID'}, { 'update': { method:'PUT' } });
}]);

And then:

var note = Notes.get({ id: 42 });
note.Content = "Changed the note";
node.$update();

Provided that the server will return { Content: "My Note", ID: 42 } in the get call.

NOTE: Keep in mind that these are all simplified, the 2 last ones above won't actually work because of the Asynchronous nature of the resource. To fix that directly in the above add a "Success" handler or use the Promise object... So:

var note = Notes.get({ id: 42 }, function() {
  note.Content = "Changed the note";
  node.$update({ id: 42 });
});

And:

var note = Notes.get({ id: 42 }, function() {
  note.Content = "Changed the note";
  node.$update();
});

Respectively... For them to work, but get-update-put in that manner is quite unlikely, instead you would normally have user interaction in over it.

I have honestly never had issues Issuing a PUT request, so why your experiencing errors I can't help with.


To help you debug your situation, I can recommend using e.g. (Or any other tool that allows you to create http requests and modify headers etc) https://chrome.google.com/webstore/detail/dev-http-client/aejoelaoggembcahagimdiliamlcdmfm?hl=en

To test if your sever really doesn't accept puts at that URL. If the server does accept puts (you succeed in doing a PUT with that tool) the next thing would be to ensure that your in fact putting to the correct URL...

We often use this little interceptor to log all Angular requests (so they are separated from normal browser requests, like getting styles, images etc).

myModule.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push(['$q', function ($q) {
        return {
            'request': function (config) {
                var paramsStr = [], prefix = "";
                angular.forEach(config.params, function (val, key) {
                    paramsStr.push(key + "=" + val);
                    prefix = "?";
                });

                console.log(config.method + ": " + config.url + prefix + paramsStr.join('&'));
                return config || $q.when(config);
            }
        };
    }]);
}]);
Jens
  • 3,353
  • 1
  • 23
  • 27
  • Thanks! That cleared up some of the issues I had with the example. Still doesn't help me with the error but it was really useful for narrowing down where to look. – user2483724 Mar 17 '14 at 22:55
  • I have added an edit with some tools and utilities that might help you debug further. – Jens Mar 18 '14 at 08:54
0

If you want to edit some content, which i guess you want, using put.

$scope.currentLocation is my object or array

$scope.edit = function  () {
    var editableLocation = $scope.currentLocation.copy($scope.currentLocation);
    editableLocation.put().then(function() {
        console.log('Location edited');
    });
};

And then in your template you can do like this

<form action="edit()">
    <input type="text" ng-model="currentLocation.name">
    <input type="button" value="Save">
</form>
Erick
  • 250
  • 3
  • 13