cancel
Showing results for 
Search instead for 
Did you mean: 

OData V4 Easy way to update Model?

machko
Member
0 Kudos

I am creating a To-Do List App in SAPUI5 and have connected my OData V4 Model from a CAP Project.
The issue I have is that I cannot update my Object status to "done" when it is selected.
I looked up several documentations and posts on Stackoverflow, yet I cannot find a easy solution to update a OData V4 Model. Here is my function and a create function as well to add entries to my current list:


The error I currently receive is: Uncaught Error: The binding must be deferred: Books(6)
I am referring to a stackoverflow post which explains a OData V4 update: https://stackoverflow.com/questions/76344744/update-entity-data-using-odata-v4-and-olistdata
The only solution I could think of was deleting and creating an identical model, but I want to refrain from doing this, due to it changing the sequence of my List entries..
Does anybody know an easier way to simply update my Object to change the status to "Done" ?

Ivelin
Explorer
0 Kudos

Hello machko,

Have you found a fix for your error. I am facing the same issue doing update.

Best,

Ivelin

anne-petteroe
Community Manager
Community Manager
0 Kudos

Hello Ivelin,
I have converted your answer to a comment.

Best regards,
Anne

Accepted Solutions (1)

Accepted Solutions (1)

mathias_uhlmann
Advisor
Advisor

First of all, let me recommend the documentation OData V4 Model.

The setParameter method that is used and which causes the quoted console error is used only if the context binding is used to execute an operation. How this is done is described in detail in the documentation chapter OData Operations. However, this is not what you want to do as you do not want to execute an operation.
Side-remark: "Operations allow the execution of custom logic on parts of a data model. Functions are operations that do not have side effects and may support further composition, for example, with additional filter operations, functions or an action. Actions are operations that allow side effects, such as data modification, and cannot be further composed in order to avoid non-deterministic behavior. Actions and functions are either bound to a type, enabling them to be called as members of an instance of that type, or unbound, in which case they are called as static operations. Action imports and function imports enable unbound actions and functions to be called from the service root." (OData Version 4.0. Part 1: Protocol Plus Errata 03)

What you would rather like to do is to change a property. The documentation chapter Accessing Data in Controller Code starts with an important information "sap.ui.model.odata.v4.Context is central for CRUD operations in the controller code. sap.ui.model.odata.v4.Context provides the following functions:". And then it mentions "setProperty: Sets a new value for the property identified by the given path." in the list that follows. The method that you want to use is sap.ui.model.odata.v4.Context#setProperty.

Let me add some additional things. In your code you are creating a new record and you are trying to change the value of a property. You can create a new binding in these cases but this means that your change is first persisted in the backend and has then to be read into the binding that is used in the UI for binding control and ODataModel. If there is a table in your application and you want to create a new record for that table, it is recommended to use the list binding associated to that table. Similarly, if you want to change a context/entity you should use the bound context of an existing context binding or the list context or ...

How to create a new record that is directly shown in the table is shown in our Sales Orders sample. See method onCreateSalesOrder.

oContext = this.byId("SalesOrderList").getBinding("items").create({
BuyerID : "0100000000",
LifecycleStatus : "N"
}),
Changing the selected record in the list is much simpler than the code you have written.
...
var selectedItem = oEvent.getParameter("listItem");
...
var oContext = selectedItem.getBindingContext();
...
oContext.setProperty("done", vStatus);

Note how I omitted the group Id to be used for the setProperty. Normally, you set a groupId and an updateGroupId globally for the model (in the manifest). The typical usage is to leave the groupId on its default, $auto, and if the application is not using Draft to set the updateGroupId to some deferred group value. This ensures that data is read (groupId) whenever required but persistence to the backend can be controlled, e.g. by using a "Save" button that calls submitBatch for the updateGroup. There is also the possibility to set them as binding parameters, see e.g. bindList but even that should be done with care. Requests in the same group are put into batch requests together (if they exist when a batch request is created). Requests in different groups may be sent in parallel batch requests which may cause issues. For one thing, the response typically carries the new server state to the client. For parallel requests it is not clear which request is executed first by the backend and which response arrives first. Also, if ETags are used, the request to arrive second would simply fail because it carries an outdated ETag.

Answers (0)