Why is ngResource modifying saved object to this: g {0: "O", 1: "K", ..} after receiving a response

I have a default ngResource defined like this:

var Posts = $resource('/posts/');

And after I get one blogpost from my nodejs server like this:

$scope.post = Posts.get({_id:query._id});

User makes some changes to it, then I call:

$scope.post.$save();

After server returns response code 200, my $scope.post looks like this:

g {0: "O", 1: "K", $get: function, $save: function, $query: function, $remove: function, $delete: function}

Why? Is there some reason? Should letters "O" and "K" mean that the operation was a success and returned response 200? Would I be able to modify this behaviour without writing my own save method from scratch?

Using the Instance methods for a resource ($get, $save, etc) will update the instance ($scope.post) in this case with whatever came back from the server.

But I think the issue here is a bit bigger than that. Your $resource definition is not going to do anything with the ID property on the .get() method because it's not in the URL configuration. Therefore the server likely returned an array of Posts, since you went to the "/posts" resource. When you do the $save() method, Angular started with an array, and therefore takes the string that came back "OK" and creates items in the $scope.post to match those characters.

Here's what you should change:

var Posts = $resource('/posts/:_id');

Then:

$scope.post = Posts.get({_id: query._id});

Now you can call:

$scope.post.$save();

The only issue with this is that if your server returns "OK" in the body, your $scope.post will now be blown away with the return data. The options to fix this are:

  1. Return only the status code, no body, from the server. I think it would be 204 for RESTful APIs, meaning the client-side version requires no update.

  2. If the client-side version requires update (like a new timestamp generated on the server), return 200 and return the full body of the updated Post object.

  3. If you can't make the above adjustments, use the service-level method rather than the instance method:

    Posts.save({_id: query._id} , post);