EDUCAÇÃO E TECNOLOGIA

SAPUI5 : How to create form with OData (deep insert)


Purpose

The main goal of this blog is to show how to create a form based on OData service with two different entities. A general case would be a form with global informat such as personal data and address data. How to combine those two kind of data with low code.

Prerequisite

I’will suppose that you have a well level of UI5 development and you know well OData modeling. I will be theoritic with some concret example.

Context

Let’s say we have an OData service V2 generated by the SEGW transaction, in ABAP On-Premise environement. This service has two entities : PersonalDataSet and AddressSet. An association between those to entities with a relation 1 to n. We will create an application UI5 based on this service.

The application will have an simple form which will be mapped to the service like this:

Context%20UI5

Context UI5

The submit button will generate the data structure to create an entry into the backend.

The UI5 application

To achieve this, you do not need another JSON model, you only need the OData model.

First, to make the model available for data typing, you have to set it as a two way binding in the manifest.json.

"sap.ui5": { (...) "models": { "": { "dataSource": "mainService", "preload": true, "settings": {"defaultBindingMode": "TwoWay"} } }
}

Then you have to create new context binding for each entity.

onInit: function() { this.getOwnerComponent().getModel().metadataLoaded().then((event) => { // Create a new entry in the OData model let oContextPersonal = this.getOwnerComponent().getModel().createEntry("/PersonalDataSet"); // Bind the new entry to the form Personal this.getView().byId("idFormPersonal").bindElement(oContextPersonal.getPath()); this._tContextElement.push(oContextPersonal); // Create a new entry in the OData model let oContextAddress = this.getOwnerComponent().getModel().createEntry("/AddressSet"); // Bind the new entry to the form Address this.getView().byId("idFormAddress").bindElement(oContextAddress.getPath()); this._tContextElement.push(oContextAddress); });
},

Behind the submitButton you have to create the deep structure before send it to the backend.

onSubmitData: function() { var oData = { d: this._tContextElement[0].getObject() }; oData.d.toAddress = { results: [this._tContextElement[1].getObject()] }; // Clean up the oData from __metadata attribute delete oData.d.__metadata; delete oData.d.toAddress.results[0].__metadata; // Call backend this.getView().getModel().create("/PersonalDataSet", oData);
}

In that manner, you can use the OData model easily. Keep in mind the deep insert structure :

{ "d" : { principal EntityType "associationName" : { child EntityType }, "associationName" : { "results" : [ { child EntityType }, { child EntityType } ] } }
}

Here is the exemple after submitting.

Conclusion

In some case, it is easier to use only one OData model to simplify your application. As I have show, few code permit to do a deep insertion.