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.
Related
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
I am very new to angular and this one is striking in my head a lot. So scenario is : Suppose angular http returns me model containing array of object like:
[{name:"Ankur",lastName:"aggarwal",updation_date:"23-08-2014"},{name:"xyz",lastName:"abc",updation_date:"29-08-2013"}]
Out of this updation_date is not required but coming for some reason. So is it right to update the array with third object without creation date like {name:"def",lastName:"jbc"} . Is it a good practice or array object model should be consistent?
Also what should be the approach? Update the model array first so binding take place instantly, then send it to the server or send it to server and get the updated object? Might be basic one but very new to angular and JMVC.
Is it a good practice or array object model should be consistent?
It depends , if backend expects all array entries to contain updation_date then you have no choice and are forced to add some sensible default value. However, if possible then avoid sending too much unnecessary data from backend since it impacts application performance(like data transfer, adding unnecessary logic to generate sensible default values, etc.)
Update the model array first so binding take place instantly, then
send it to the server or send it to server and get the updated object?
If the nature of your application permits reverting model value when save is unsuccessful then just go ahead with
0.Perform data validation, and make sure valid data is supplied to the backend.
1.Update model.
2.Send data to backend
3.If something bad happens then execute error handling depending on app needs
However if presenting consistent value in the GUI is uttermost importance(e.g. finance applications) then
0.Perform data validation, and make sure valid data is supplied to the backend.
1.Show some message to user like "saving"
2.Perform ajax request
3.If successful, update model, else execute error handling depending on app needs
It depend on your error handling.
As saving on the server-side might be not successful, you should take it into consideration.
My approach is to
Update angular object immediately
Then send AJAX request to server and
Wait for response. If error happen during server save, you shoulde:
revert values,
repeat AJAX
show information to user.
I am trying to develop a Dojo DataGrid that returns a user's documents from the categorized BidsByDriver view and allows them to edit the Priority field in the grid. After getting past the hurdle of using the keys property to filter over the categoryFilter, this was easy to set up using an xe:viewFileItemService read/write service. However the problem with xe:viewFileItemService as a data source is it will display empty lines for each entry in the view after showing the user's documents in the grid.
To get around the blank lines I went down the path of creating an xe:customRestService that returned the jasonData for just the current user's documents. This fixes my blank lines problem but my data source is not in the correct read/write format to support the in-grid editing.
Here is the resulting Json data returned form the xe:customRestService ...
[{"Driver":"ddd","BidID":"123","Priority":"1","Trip":"644"},
{"Driver":"ddd","BidID":"123","Priority":"2","Trip":"444"},
{"Driver":"ddd","BidID":"123","Priority":"4","Trip":"344"},
{"Driver":"ddd","BidID":"123","Priority":"4","Trip":"643"}
]
Here are the Dojo modules I am loading:
<xp:this.resources>
<xp:dojoModule name="dojo.store.JsonRest"></xp:dojoModule>
<xp:dojoModule name="dojo.data.ObjectStore"></xp:dojoModule>
</xp:this.resources>
And here is the script to develop the data store for the grid:
<xp:scriptBlock id="scriptBlock2">
<xp:this.value><![CDATA[
var jsonStore = new dojo.store.JsonRest({target: "InGridCustom.xsp/pathinfo"});
var dataStore = dojo.data.ObjectStore({objectStore: jsonStore});
]]></xp:this.value>
</xp:scriptBlock>
All of this works very nicely except for the bit on providing the in-grid editing support. Any ideas appreciated.
How are you trying to save the changes? With a custom REST service, I would not expect that saving the data store would make any changes to the back-end data, which is why a refresh would revert it to the original value.
I would expect that you'd need to write a doPost method in your custom REST service to process the change on the server side, along with client-side code to call the post method and pass in the updates to process (along with the document ID).
UPDATED ANSWER:
I would try one or both of these approaches to fix your issue.
1) Have a category in your view, and use a categoryFilter and use the hack to make the service only return the correct values. Outlines in this question: XPages Dojo Grid editable cell does not save value when REST Service save() method is called
2) Change the rest service type to viewJsonService in combination with #1. If you get an error, double check the configuration document that Per mentioned. Also heed Per's comments in the linked question relating to configuration and using Firebug to make sure the correct method is used. The update must be a PUT, a POST will not work with the viewJsonService.
Original Answer (for context of comments)
Paul,
I believe that you need to have a button with code to save the changes back. Maybe you do, but you don't mention it and it isn't in your screen shots. The step that Per mentioned is very necessary so it is good that you have it taken care of. The button is necessary, to 'commit' the changes back. The act of inline editing doesn't trigger the PUT call. If you think about it, you wouldn't want an update after each change but one update when the user is finished editing.
If you don't figure out by this evening, I have working code that I can send you, but don't have access to at work.
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.
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.