Backbone doing POST request instead of PUT request - javascript

I am trying to set a model's attribute to be something different. When I save the model, Backbone issues a POST request instead of a PUT request.
I read on another Stackoverflow post that Backbone uses a model's id to determine if a model is new or not. When I console.log(model), the model has an id attribute. When I console.log(model.id), it prints out undefined. How come when I do a console.log(model), the model has a id attribute, yet when I do console.log(model.id), I get back undefined?
Which way does Backbone use to determine if a model is new or not? And, how can I fix the problem? I am using backbone-tastypie.

How did you create the model in the first place? The model's id needs to be specified in the model's data. Usually this would be returned in the server response the first time you save a new object. Once the id is set Backbone will save it with PUT instead of POST.

Related

Loopback - see data before overwriting in "after save" hook

I've seen this question: Strongloop : Compare old model with the new instance in operation hook 'before save'
Is there any way to get the data in the DB before the overwriting is done in the before save hook? Basically, I want to be able to pass one element to update in a put request rather than pass all required fields during the request.
It seems like you are looking for upsertWithWhere or upsert which does a PATCH rather then a PUT. If you do that and the right row can be identified (you send along the primary ID or identify the row) only the passed along data will be updated/overwritten and the rest will be kept.
That's the easy way, if you want to do something more advanced (like doing modifies on DB before a save) then you just have to access the Model in the before save hook and modify. Remember you can do anything before a save as long as you postpone the "next()" call.

Get edited data of OData Binding

Does anyone know the best approach of getting the changed data of an odata model property after binding it to a form / set of input controls via bindElement?
Currently I am doing something like this.getView().bindElement('/SomeEntitySet(0815)');. But I struggle with getting back the edited data from my view. The only methods the binding is offering to me is getting back the odata model itself, which contains the original, non edited data.
Does anybody know what I'm doing wrong?
In the odataModel there's an Property called refreshAfterChange this should be set to true by default.
Are you sure your changes applies to your backend data? The oDataModel from sapui5 should update the binding by itself(checkout: mParameters.refreshAfterChange).
If the Change method work debug your oData service and check if the change method trigger a GET request to your backend(The odatamodel should trigger a get request if the data has been changed => see refreshAfterChange in link above, the refresh of the model will do a GET request like it does if you bind data to an element). If not theres something wrong with your model confoiguration.
Could you add the code where and how you initiate the model?

How to know when model has changed on front side with Backbone?

I probably don't understand some of the Backbone logic and so hope you can explain it to me.
When I create a model, pass it an ID and then fetch it, Backbone marks the model as changed (a call to changedAttributes() returns all the object attributes).
When you modify an object attribute on front side, it also marks the model as changed with only this attribute being returned by changedAttributes().
So how do you make a difference between changes made on front-side (and so, not persisted) and changes which comes from the server ? (Is there any specific events ?)
The reason for why I'm asking this is that I'd like to save my model, times to times, if there are some front side changes or if the user quits.
[edit]
My scenario is (I work with Angular):
The URL of my page is of the form: object/#/:id
My page is an editor for the object (some inputs).
When the ID in the URL changes, I fetch the corresponding object from the server. But if there were already something (like if the user manually changes the ID), I need to save whatever has been done on the object first.
There is no real tracking of model/collection changes in Backbone, that tells you what or if something changed. You have to do this by yourself.
You can of course check the changes of the current change loop. So in an event handler you use like model.on("change", () => ...). You might want to implement a handler function, that tracks the change, and maybe reset it, after you saved it on the server

In Backbone.js, after I 'create' a model under a collection, how do I update that model?

Posts.create({'body':post_body});
When I call that, Backbone will hit my sever with an AJAX post request, creating that post. My server will then return a JSON with the "full" post.
Perfect! But now, I want the newly created model to to have the full data. In other words, I don't want it to only have the body attribute. (all my other models have other data).
My question is:
will backbone automatically update the model with the "full" data because my server returned that full JSON?
if not, how can I get Backbone to update that model so its data is full?
Edit: I did this, and it seems like Backbone automatically uses the data returned as the new model. Can someone confirm?
success:function(post){
console.log(post.toJSON()); //Yay! latest version.
},
Yes, the model will be updated with any additional info your server returns.
This is because under the model's create method, there is a call to save, which intern calls model.set within it, in order to update the model with any amended (or new attributes).
As the source code comment for this method states:
If the server returns an attributes hash that differs, the model's state will be set again.

BackboneJS, create and destroy, but no update method?

I noticed that in BacbkoneJS there is a method in the Collection object that allows you to add a new model to that collection, while at the same time pushing the new model to the Server. This is convenient because it will only add the new model to the collection if the ajax request is successful. It will also update the ID on the model with the one returned from the server.
There is also a similar method on the Model object called destroy, this will only destroy the model if the ajax request returns 200.
How can I achieve something similar to this with Update, where when I set data on my model, it will attempt to save the model to the server, ensure a 200 status, and then fire the "change" event?
The problem is If I set the model data (I have to do this in order to call save()), then the change event fires.
Thanks
The Backbone.Model.save() method allows you to specify the properties you want to change. Looking at the annotated source code, it looks like the "model.set()" happens on a successful response from the server.
So, instead of doing
myModel.set({this:"that"});
myModel.save();
Do
myModel.save({this:"that"});
and the change event should fire after a successful save.
Note: I have not tested this - this is just from reading the source.

Categories

Resources