sapui5 odata crud operations

SAPUI5 OData CRUD Operations

Example on OData service with the four basic functionalities of Create, Read, Update and Delete and its consumption in a SAPUI5 application is known as SAPUI5 Odata CRUD Operations.

Create an OData service with CRUD operations and consume it in a SAPUI5 application. This simple exercise on OData and SAPUI5 application covers CRUD operations as well as explains how to deploy the final SAPUI5 application on SAP Fiori Launchpad.

Creating OData service and implementing CRUD methods

Begin by creating an OData service and redefining the CRUD methods. An OData service is created in the Backend system and it is registered in the Frontend system in a Central Hub Deployment landscape. But do check your organizations’s landscape before start building with OData service as different company may follow a different landscape.

Open SAP Netweaver Gateway service builder using TCode SEGW. Choose Create Project, to create a new OData service project.

SAPUI5 OData CRUD Operations

Fill in the entries as shown below and click Continue.

SAPUI5 OData CRUD Operations

Next we need to create Entity Type and EntitySet. We will use ABAP structure SCARR to create EntityType. Right click Data Model and select Import-> DDIC Structure.

In the Wizard, enter Name and ABAP Structure as shown below. Select Check box Create Default Entity Set and click Next.

SAPUI5 OData CRUD Operations

Select the required fields for the Entity. Once done, click Next.

SAPUI5 OData CRUD Operations

Here we need to select a Key. Its important that Entity must have at least one key. Click Next.

SAPUI5 OData CRUD Operations

We have now created an OData project.

Next, click on generate button to create the MPC, DPC and the service name. Click on Continue to finish the process.

SAPUI5 OData CRUD Operations

The above step will create the Runtime Artifacts. The project structure will be as shown below.

SAPUI5 OData CRUD Operations

Right click on DPC_EXT class and select ABAP Workbench.

SAPUI5 OData CRUD Operations

Under inherited methods we have CRUD operations methods. Right click Get_entityset method to redefine.

SAPUI5 OData CRUD Operations

Inside Entity_set method we write code to fetch multiple records.

SAPUI5 OData CRUD Operations
SELECT * FROM scarr INTO TABLE et_entityset.

Similarly, redefine Get_Entity, Create_entity, Update_Entity, Delete_entity and write code inside the methods.

Code Get_entity

SAPUI5 OData CRUD Operations
* Fetch Single record based on the key in the URI
    DATA : wa_key_tab LIKE LINE OF it_key_tab.
 
* Read the Key from URI
    READ TABLE it_key_tab INTO wa_key_tab WITH KEY name = 'Carrid'.
    IF sy-subrc EQ 0.
      SELECT SINGLE * FROM scarr 
        INTO CORRESPONDING FIELDS OF er_entity 
        WHERE carrid EQ wa_key_tab-value.
    ENDIF.

Code Create_entity

SAPUI5 OData CRUD Operations
* Create a record
    DATA : wa_airline TYPE zcl_zscb_crud_operatio_mpc=>ts_airline.
 
* Read the data from Request body
    io_data_provider->read_entry_data(
      IMPORTING
        es_data                      = wa_airline
    ).
 
    MOVE-CORRESPONDING wa_airline TO er_entity.
    MODIFY scarr FROM wa_airline.

Code Update_entity

SAPUI5 OData CRUD Operations
* Update the record
    DATA : wa_key_tab LIKE LINE OF it_key_tab,
           wa_airline TYPE         zcl_zscb_crud_operatio_mpc=>ts_airline.
 
* Read the Key from URI
    READ TABLE it_key_tab INTO wa_key_tab WITH KEY name = 'Carrid'.
    IF sy-subrc EQ 0.
* Read the data from HTTP Request body
      io_data_provider->read_entry_data(
        IMPORTING
          es_data                      = wa_airline
      ).
 
      MOVE-CORRESPONDING wa_airline TO er_entity.
      UPDATE scarr SET carrname = wa_airline-carrname
                       currcode = wa_airline-currcode
                       url      = wa_airline-url
                 WHERE carrid   = wa_key_tab-value.
    ENDIF.

Code Delete_entity

SAPUI5 OData CRUD Operations
* Delete a record
    DATA : wa_key_tab LIKE LINE OF it_key_tab.
 
* Read the key from URI
    READ TABLE it_key_tab INTO wa_key_tab WITH KEY name = 'Carrid'.
    IF sy-subrc EQ 0.
      DELETE FROM scarr WHERE carrid EQ wa_key_tab-value.
    ENDIF.

Once done, Save Check and Activate the class. Code reference

Register the service in Frontend gateway system.

Execute TCdoe /IWFND/MAINT_SERVICE. Click on Add Service button.

SAPUI5 OData CRUD Operations

Once you complete the Add Service step. you should see the OData service under Service Catalog list.

SAPUI5 OData CRUD Operations

You can test the service by click on SAP Gateway Client button.

This completes the process of creating and registering Odata service with CRUD methods.

Create SAPUI5 Application to consume OData service with CRUD operations

Create a SAPUI5 Application in WebIDE using Project from Template wizard. I have created a project with view as View1.

SAPUI5 OData CRUD Operations

Right click on the project to attach Odata service created above.

SAPUI5 OData CRUD Operations

In the wizard, we need to select Select Catalog, select the Gateway system, search and select the odata service, click Next. Go for default model and finish the wizard.

SAPUI5 OData CRUD Operations

In the Manifest.json file, you can check if the Odata service has been configured correctly.

"": {
	"type": "sap.ui.model.odata.v2.ODataModel",
	"settings": {
	"defaultOperationMode": "Server",
	"defaultBindingMode": "OneWay",
		"defaultCountMode": "Request"
	},
	"dataSource": "ZSCARR_SRV",
	"preload": true
}

Code the View1.view.xml file

<mvc:View 
controllerName="Amarmn.zcrud.controller.View1"
xmlns:mvc="sap.ui.core.mvc" displayBlock="true" 
xmlns="sap.m">
<Shell id="shell">
<App id="app">
<pages>
<Page id="page" title="Airline">
<content>
<Panel id="__panel1">
<content>
<List id="List" 
items="{jsonmodel>/scarrEntitySet}" 
headerText="Employees" 
mode="SingleSelectMaster" 
selectionChange="onPress">
<StandardListItem id="Sli" 
title="{jsonmodel>Carrid}" 
description="{jsonmodel>Carrname}" 
info="{jsonmodel>Currcode}"/>
</List>
</content>
</Panel>
<Panel id="__panel0" headerText="{i18n>addressdetails}">
<content>
<Label text="AirlineID" width="100%" id="__label0"/>
<Input width="100%" id="__input0"/>
<Label text="Airline Name" width="100%" id="__label1"/>
<Input width="100%" id="__input1"/>
<Label text="Currency" width="100%" id="__label2"/>
<Input width="100%" id="__input2"/>
<Button text="{i18n>create}" width="100px" id="__button1" press="onSave"/>
<Button text="{i18n>update}" width="100px" id="__button2" press="onUpdate"/>
<Button text="{i18n>delete}" width="100px" id="__button0" press="onDelete"/>
</content>
</Panel>
</content>
</Page>
</pages>
</App>
</Shell>
</mvc:View>

Code the Controller.js file

sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"sap/ui/model/json/JSONModel",
	"sap/m/MessageToast",
	"sap/ui/model/Filter"
], function (Controller, JSONModel, MessageToast, Filter) {
	"use strict";

return Controller.extend("Amarmn.zcrud.controller.View1", {
onInit: function () {
var oJSONModel = new JSONModel();
this.getView().setModel(oJSONModel, "jsonmodel");
var sUrl = "/sap/opu/odata/sap/ZSCARR_SRV/";
var oModel = new sap.ui.model.odata.ODataModel(sUrl, true);
oModel.read("/scarrEntitySet", {
success: function (data) {
oJSONModel.setData({
scarrEntitySet: data.results
});
}
});
},
onPress: function (oEvent) {
this.getselval1 = oEvent.getSource().getSelectedItem().
getBindingContext("jsonmodel").getObject().Carrid;
this.getView().byId("__input0").setValue(this.getselval1);
this.getselval2 = oEvent.getSource().getSelectedItem().
getBindingContext("jsonmodel").getObject().Carrname;
this.getView().byId("__input1").setValue(this.getselval2);
this.getselval = oEvent.getSource().getSelectedItem().
getBindingContext("jsonmodel").getObject().Currcode;
this.getView().byId("__input2").setValue(this.getselval);
},

onSave: function () {
var oCust1 = this.getView().byId("__input0").getValue();
var oCust2 = this.getView().byId("__input1").getValue();
var oCust3 = this.getView().byId("__input2").getValue();
var postData = {};
postData.Carrid = oCust1;
postData.Carrname = oCust2;
postData.Currcode = oCust3;
this.getOwnerComponent().getModel().
create("/scarrEntitySet", postData, null, function (response) {
MessageToast.show("Address Created Successfully with number  " + oCust1);
var mylocation = location; mylocation.reload();
}, function (Error) {
MessageToast.show("Customer Creation Failed  " + oCust1);
});
},

onDelete: function () {
var oCust1 = this.getView().byId("__input0").getValue();
this.getOwnerComponent().getModel().
remove("/scarrEntitySet('" + oCust1 + "')", {
method: "DELETE",
success: function (data) {
MessageToast.show("Customer deleted Successfully with number  " + oCust1);
},
error: function (e) {
MessageToast.show("Customer deletion Failed  " + oCust1);
}
});
},
onUpdate: function () {
var oCust1 = this.getView().byId("__input0").getValue();
var oCust2 = this.getView().byId("__input1").getValue();
var oCust3 = this.getView().byId("__input2").getValue();
var postData = {};
postData.Adrnr = oCust1;
postData.Name2 = oCust2;
postData.City = oCust3;
this.getOwnerComponent().getModel().
update("/scarrEntitySet('" + oCust1 + "')", 
postData, null, function (response) {
MessageToast.show("Customer update Successfully with number  " + oCust1);
var mylocation = location; mylocation.reload();
}, function (Error) {
MessageToast.show("Customer update Failed  " + oCust1);
});
}
});
});

Code reference https://blogs.sap.com/2019/05/25/perform-crud-operations-on-employee-info-in-sap-web-ide-using-sap-ui5/

Deploy SAPUI5 application on SAP Fiori Launchpad

Deploy SAPUI5 Application to the Gateway server from SAP WebIDE

The above code completes the SAPUI5 application. Next, we will deploy the SAPUI5 application to ABAP Gateway system.

SAPUI5 OData CRUD Operations

Deploy as a new application as it is first time we are deploying the application on ABAP Gateway system.

SAPUI5 OData CRUD Operations

Finish deploying the application to the ABAP Gateway System.

Create Launchpad Role in LPD_CUST

Go to tcode LPD_CUST to create a LPD object. Click New Launchpad button.

SAPUI5 OData CRUD Operations

In the input fields, provide Role, Instance and Description.

SAPUI5 OData CRUD Operations

In the Namespace required popup, select Yes. Next, select New Application.

SAPUI5 OData CRUD Operations

Fill in the required fields as shown in the below image and save.

SAPUI5 OData CRUD Operations

We now have the launchpad instance ready.

Create custom Semantic object

Create a semantic object using tcode /UI2/SEM_OBJ.

SAPUI5 OData CRUD Operations

Launchpad designer configuration

We next need to complete Launchpad Designer configuration to bring the SAPUI5 application on the SAP Fiori Launcpad.

Go to Launchpad Designer and create a Catalog. The launchpad designer URL should be http://<hostname>:<port>/sap/bc/ui5_ui5/sap/arsrvc_upb_admn/main.html replacing <hostname> and <port> with <hostname> and <port> configured in system.

SAPUI5 OData CRUD Operations

Select the Catalog created and select tile to create a new static tile. Fill in the details as shown in below image to create a tile.

SAPUI5 OData CRUD Operations

Now we will create target mapping. Fill in the details.

SAPUI5 OData CRUD Operations

Create custom Role using PFCG tcode

The last thing that would be required is to create role via tcode PFCG in Frontend Gateway system. Enter Role name and click Single Role button. Also add description and save.

SAPUI5 OData CRUD Operations

In the Menu tab, select small drop down on the Transaction button and select Fiori Tile Catalog. Provide the Catalog ID. The Catalog will be added.

SAPUI5 OData CRUD Operations

In the User tab, add the User ID who should get access to this role.

Add Catalog from the Fiori Launchpad

At the Launchpad click on the Edit button.

SAPUI5 OData CRUD Operations

From the catalogs drop down, select the Catalog created by us.

SAPUI5 OData CRUD Operations

We get the Tile created under this catalog. Click the + under tile to add the catalog in the group.

SAPUI5 OData CRUD Operations

The tile will now appear on the Launchpad. Click on edit button exit from edit mode.

SAPUI5 OData CRUD Operations

Click on tile to see the output of the application.

SAPUI5 OData CRUD Operations

Updated SAPUI5 code with no errors

sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"sap/ui/model/json/JSONModel",
	"sap/m/MessageToast",
	"sap/ui/model/Filter"
], function(Controller, JSONModel, MessageToast, Filter) {
	"use strict";
	var that = this;

return Controller.extend("amarmnzcrud.controller.View1", {
	onInit: function() {
	that = this;
	var oJSONModel = new JSONModel();
	that.getView().setModel(oJSONModel, "jsonmodel");
	var sUrl = "/sap/opu/odata/sap/ZSCARR_SRV/";
	var oModel = new sap.ui.model.odata.ODataModel(sUrl, true);
	that.getView().setModel(oModel);
	oModel.read("/scarrSet", {
		success: function(data) {
			oJSONModel.setData({
				scarrEntitySet: data.results
			});
		}
	});
},
onPress: function(oEvent) {
	that.getselval1 = oEvent.getSource().getSelectedItem().
	getBindingContext("jsonmodel").getObject().Carrid;
	that.getView().byId("input0").setValue(that.getselval1);
	that.getselval2 = oEvent.getSource().getSelectedItem().
	getBindingContext("jsonmodel").getObject().Carrname;
	that.getView().byId("input1").setValue(that.getselval2);
	that.getselval = oEvent.getSource().getSelectedItem().
	getBindingContext("jsonmodel").getObject().Currcode;
	that.getView().byId("input2").setValue(that.getselval);
},

onSave: function() {
	var oCust1 = that.getView().byId("input0").getValue();
	var oCust2 = that.getView().byId("input1").getValue();
	var oCust3 = that.getView().byId("input2").getValue();
	var postData = {};
	postData.Carrid = oCust1;
	postData.Carrname = oCust2;
	postData.Currcode = oCust3;
	that.getView().getModel().
	create("/scarrSet", postData, null, function(response) {
	MessageToast.show("Airline created successfully..  " + oCust1);
	}, function(Error) {
	MessageToast.show("Airline Creation Failed  " + oCust1);
	});
},

onDelete: function() {
	var oCust1 = that.getView().byId("input0").getValue();
	//that.getOwnerComponent().getModel().
	that.getView().getModel().
	remove("/scarrSet('" + oCust1 + "')", {
		method: "DELETE",
success: function(data) {
MessageToast.show("Airline deleted Successfully with number  " + oCust1);
},
error: function(e) {
MessageToast.show("Airline deletion Failed  " + oCust1);
}
});
},
onUpdate: function() {
var oCust1 = that.getView().byId("input0").getValue();
var oCust2 = that.getView().byId("input1").getValue();
var oCust3 = that.getView().byId("input2").getValue();
var postData = {};
postData.Carrid = oCust1;
postData.Carrname = oCust2;
postData.Currcode = oCust3;
// that.getOwnerComponent().getModel().
that.getView().getModel().
update("/scarrSet('" + oCust1 + "')",
postData, null,
function(oData, response) {
MessageToast.show("Upadte successful for " + oCust1);
},
function(Error) {
MessageToast.show("Update unsuccessful for.." + oCust1);
});
}

});
});