mgonto / restangular

AngularJS service to handle Rest API Restful Resources properly and easily
MIT License
7.88k stars 843 forks source link

Update in place #409

Closed Rodeoclash closed 10 years ago

Rodeoclash commented 10 years ago

I'm really sorry to post a support type message rather then a bug request here but I've got a question about updating elements from a collection in place.

In AngularJS resource object, you're able to call element.$get() which will trigger a GET request to the server and update the object itself.

Is their something analogous to this in Restangular? The closest I've come to is:

element.get().then(function(response) {
  element.name = response.name;
  ..
});

It feels somewhat inelegant and if the attributes on the object changed or get updated, you have to remember all the places you have used it. I suppose I could create a method in a service which takes an element + response object and combines them. This feels clumsy as well.

Am I missing something in the documentation about updating or resetting elements in place?

mgonto commented 10 years ago

Hey,

Basically I don't really like how $resource handles thing. As you say, the $get modifies stuff inline, with some "dark magic" (Keeps a reference to the object).

Restangular uses only promises, so the idea is to use the then as you're showing. AngularJS used to support unwrapping of promises automatic but it doesn't anymore, so you have to call the then.

However, the idea isn't just to update one field (the name), but the whole object, so in the then, you should be doing something like $scope.element = response and just replace the whole thing. That's what $resource is doing inside actually, just changing your fields.

Hope this helps, if it doesn't please ask more, I don't mind! Otherwise, close the issue please

Rodeoclash commented 10 years ago

Hmm. Let me describe my workflow as I'd love your feedback.

Essentially what I'm doing is a form that edits the model. If the user cancels the form editing, I want to reset the object back to the pristine state, by calling it again (GET) from the server.

The editing itself takes place in a modal window. The user selects the model from one of many in an array (usual ng:repeat over the Restanuglar array, yadda yadda). The modal controller (UIBootstrap) takes the model object and displays it in a form. If the user submits the form, I call the save method, .patch(), and assume the client model and server model are in sync. But if the user cancels the form, I want to restore the object, which I can do but I manually need to assign the attributes in the promise callback. This is not as easy as just replacing the object in the view, the object may be referenced in many places. E.g. inside an ng:repeat, inside some breadcrumbs at the top of the page etc.

The problems I have with this approach:

Expanding out from this, everywhere in the system where you might call an update/save or restore on a model object, you need to have that callback which manually replaces the attributes. On one hand, I do like this control, on the other, it's a lot of boilerplate!

My initial thought was to just replace the object wholesale in the callback:

myModel.patch().then( function(response) {
  myModel = response;
});

But the problem with this was that you lost the JavaScript object reference, clearly causing problems with the 2-way binding.

mgonto commented 10 years ago

Hey,

Now you have something similar in Restangular as well.

Check out: https://github.com/mgonto/restangular#using-values-directly-in-templates

Rodeoclash commented 10 years ago

Yeah I saw that show up today, good work! It's been interesting actually, I've been trying to determine the best workflow for managing models in Angular projects, experimenting with. All implementations have been wrapped in a service, so either:

vs

I love the flexibility of Angular but sometimes I feel that theirs a couple if good ways to do something and four ways to hang yourself ;)

mgonto commented 10 years ago

I think that having a lot of choices is great :), though "With a great power comes a great responsibility". That's what Spiderman's uncle said :P, which is completely right.

I like promises flexibility given the fact that you can do whatever you want with them. For example I saw once an implementation for $q promise where you could set a promise value twice. Once with cached value, and then update with server value, that way, you can actually return cached and then the updated value slower.