Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Trying to .save() a resource will also (effectively) .get() it #311

Closed
arantius opened this issue Mar 21, 2011 · 3 comments
Closed

Trying to .save() a resource will also (effectively) .get() it #311

arantius opened this issue Mar 21, 2011 · 3 comments

Comments

@arantius
Copy link
Contributor

First, here's a reproduced test case and a bit of explanation what's going on:
https://gist.github.com/880088
(Run those 3 files as an app engine app for an easy way to host it that will allow POSTing to the .json file.)

Create a $resource class, then .get() it. Use that data bound to the page to create a little form. In that form, a button that will call .save() on the same resource. However: in the callback passed to .get() I'm accessing a property of the resource, also an object, storing a reference to it, and modifying it.

This modification is an oversimplification of what I'm doing in my real app. There, I am fetching two separate $resources: questions and answers. I cross-reference them together in the constructor (e.g. this.question[i].answer = this.answers[j] -- but this also a bit oversimplified). Then when rendering the page I can access this.question and this.question.answer, both to know what sort of field to render, and what value to pre-populate in it.

So what I'm seeing is that my view is bound to a question, the question has a reference to the answer, but after I .save() the answers, those objects are thrown away and the resource now contains a brand new set of answer objects, constructed from the response of the save call.

So early on, I had my server simply echo back the object that was just saved, and things appeared to work. It was only later that I discovered the whole cross-reference-breaking behavior which surfaces subtle bugs in our system.

Via the test case linked at the top, this is revealed in that the "obj.value" is 42 in the resource, set to -1 in the controller and otherwise not touched -- but .save()ing the resource re-loads that data from the server and overwrites the -1 value.

I don't want save() to load data from the server, I want it write data to the server. I want it to read the model, not write to it. Doing this breaks my app.

@arantius
Copy link
Contributor Author

Proposed patch:
arantius/angular.js@master...resource-mutate

You can debate the particulars of this implementation, but I can confirm that this change resolves the behavior described above. A .save() does not mutate the existing resource instance, and thus does not break the test case as described, and my real app too.

@arantius
Copy link
Contributor Author

I think this might be a better patch:

arantius/angular.js@master...resource-mutateB

@IgorMinar
Copy link
Contributor

angular.js: master Anthony Lieuallen * 94514a9 (2 files in 2 dirs): Don't mutate resource if server responded with no body ... - http://bit.ly/eKsnlO

I decided not to do the merge right now. our merge() fn implementation is quite iffy so I didn't want to use it.

I'll have to fix merge in a separate CL. If you need the merge feature now, please open a new RFE so that I know about it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants