SAPUI5 for ABAPers – Consuming OData Service from SAPUI5 Application – CRUD Operations

The ultimate fate of on OData Service is to get consumed by the front-end applications. SAPUI5 Applications follow Model View Controller (MVC) Architecture. In MVC, from UI5 perspective, View and Controller are the Views (XML, HTML, JavaScript and JSON Views) and Controllers (JavaScript Controllers) respectively of the UI5 Application. The role of Model is played by OData, JSON, Resource or XML Model in the UI5 Application.

In this tutorial, we will talk about OData model and hand hold you to create a front-end application and call the OData Model to perform the CRUD Operations.

Using OData Model, you can consume the OData Service. For this we need to create an OData Service and implement CREATE, READ, UPDATE and DELETE methods of the service. Then we need to create an OData Model Instance in the UI5 application and call these methods using read(), create(), update() and remove() functions respectively of the OData model.

So let’s start…

Business scenario: Customer wants to display records from a custom table onto the UI5 application and provide functions of Read, Create, Update and Delete to the end users.

Step 1: Get a Custom Table ready for us to play

Creating a custom table by the name ‘zuserdata’ with id, name, email and mobile fields.

Step 2: Creating an OData service

1. Go to transaction SEGW and create a new OData Service, name it zcrud_demo.

1. Create an entity ‘userdata’ and create associated entityset as well ‘userdataSet’.
2. Create 4 properties in ‘userdata’ entity namely id, name, email and mobile.

3. Ensure Properties datatype and length matches with that of the fields created in table in step1.

4. Activate the OData service which will generate its runtime artifacts.
5. Redefine Create, Read, Update and Delete methods of …DPC_EXT Class of the oData service.

7. Write your logic (code) in each of the redefined methods (Redefinition code is given in below part of the tutorial)

8. Go to t-code /n/iwfnd/maint_service and Add the Service.

9. Perform ICF settings for the generated OData service to enable Create operations using OData model. Go to SICF transaction, open OData service’s ICF node and double click on it, Click on GUI Configuration button

Set ~CHECK_CSRF_TOKEN value to 0. This will bypass CSRF protection on the service. This is required for CREATE, UPDATE and DELETE operations to work. If you don’t want this protection to be turned off (from a security perspective), you need to fetch X-CSRF-TOKEN using READ operation every time you want to perform CREATE, UPDATE or DELETE operations from UI5 application. In this tutorial, for the sake of simplicity, we have chosen to turn off X-CSRF-TOKEN security feature.

OData ABAP code for Create – CREATE_ENTITY Method

method USERDATASET_CREATE_ENTITY.
    data : wa_userdata type zcl_zcrud_demo_mpc=>ts_userdata.
*    read data recieved from ui5
    io_data_provider->read_entry_data(
    IMPORTING
      es_data  = wa_userdata
    ).
    MODIFY zuserdata from wa_userdata.
    if sy-subrc eq 0.
      move 'success' to er_entity-name.
      else.
        move 'error' to er_entity-name.
        endif.
  endmethod.

OData ABAP code for Get (Single record) – GET_ENTITY method

method USERDATASET_GET_ENTITY.
    data : wa_userdata TYPE ZCL_ZCRUD_DEMO_MPC=>TS_USERDATA.
    SELECT SINGLE * from zuserdata into CORRESPONDING FIELDS OF wa_userdata.
      MOVE-CORRESPONDING wa_userdata to er_entity.
  endmethod.

OData ABAP Code for Get (multiple records) – GET_ENTITYSET Method

method USERDATASET_GET_ENTITYSET.
    data : it_userdata TYPE ZCL_ZCRUD_DEMO_MPC=>TT_USERDATA.
    SELECT * from zuserdata into table et_entityset.
  endmethod.

OData ABAP code for Update – UPDATE_ENTITY Method

method USERDATASET_UPDATE_ENTITY.
    data : wa_userdata type zcl_zcrud_demo_mpc=>ts_userdata.
*    read data recieved from ui5
    io_data_provider->read_entry_data(
    IMPORTING
      es_data  = wa_userdata
    ).
*    move 'success' to er_entity.
    UPDATE zuserdata set email = wa_userdata-email where id = wa_userdata-id.
 
  endmethod.

OData ABAP code for Delete – DELETE_ENTITY Method

method USERDATASET_DELETE_ENTITY.
    data : wa_keytab LIKE LINE OF it_key_tab.
    READ TABLE it_key_tab into wa_keytab WITH KEY name = 'id'.
    if sy-subrc eq  0.
      DELETE from zuserdata where id eq wa_keytab-value.
      ENDIF.
  endmethod.

Step 3: Create SAPUI5 Application

Create SAPUI5 application to Consume OData Service created in Step 2 and Call CREATE, READ, UPDATE and REMOVE functions of the OData model.

  1. Create a new SAPUI5 application by the name crud_demo.
  2. Create a XML view ‘crud_demo.view’. Write below code in it.
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
		controllerName="crud_demo.crud_demo" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:l="sap.ui.commons.layout">
	<Page title="CRUD Operations">
		<content>
	<l:AbsoluteLayout width="10rem" height="10rem"></l:AbsoluteLayout>
	<VBox xmlns="sap.m" id="vboxid">		
		<items>		
		<HBox xmlns="sap.m">		
		<items>	
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>	
		<Button xmlns="sap.m" id="cbtn" press="oDataCall" text="Create"></Button>
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>
		<Button xmlns="sap.m" id="rbtn" press="oDataCall" text="Read"></Button>
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>
		<Button xmlns="sap.m" id="ubtn" press="oDataCall" text="Update"></Button>
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>
		<Button xmlns="sap.m" id="dbtn" press="oDataCall" text="Delete"></Button>
		</items>
		</HBox>
				
		<HBox xmlns="sap.m">		
		<items>		
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>
		<Input xmlns="sap.m" 	id="uniqueid" placeholder="ID" value="1"></Input>
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>
		<Input xmlns="sap.m" 	id="nameid" placeholder="Name" value="test"></Input>
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>
		<Input xmlns="sap.m" 	id="emailid" placeholder="Email" value="test@gmail.com"></Input>
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>
		<Input xmlns="sap.m" 	id="mobid" placeholder="Mobile" value="8888888888"></Input>
		</items>
		</HBox>
		
		
		<HBox xmlns="sap.m">		
		<items>		
		<l:AbsoluteLayout width="20px" height="20px"></l:AbsoluteLayout>
		<Table xmlns="sap.m"
		id="userdatatable" headerText="User Data">		
		<items>
			<ListItemBase xmlns="sap.m" id="id1"></ListItemBase>
		</items>		
		<columns> <!-- sap.m.Column -->
			<Column xmlns="sap.m"> <header> <Text xmlns="sap.m" text="Id" ></Text></header></Column>
			<Column xmlns="sap.m"> <header> <Text xmlns="sap.m" text="Name" ></Text></header></Column>
			<Column xmlns="sap.m"> <header> <Text xmlns="sap.m" text="Email" ></Text></header></Column>
			<Column xmlns="sap.m"> <header> <Text xmlns="sap.m" text="Mobile" ></Text></header></Column>
		</columns>
		</Table>
		</items>
		</HBox>		
		</items> <!-- sap.ui.core.Control -->
</VBox>
		</content>
	</Page>
</core:View>

3. Create crud_demo.controller.js. Write below code in it.

onInit: function() {
		that = this;
		// Create Model Instance of the oData service
		var oModel = new sap.ui.model.odata.v2.ODataModel("/sap/opu/odata/sap/ZCRUD_DEMO_SRV");
		sap.ui.getCore().setModel(oModel, "myModel");
	},
oDataCall:function(oEvent)
 	{
		// call oData service's function based on which button is clicked.
		debugger;
		var myModel = sap.ui.getCore().getModel("myModel");
		myModel.setHeaders({
			"X-Requested-With" : "X"
		});
		// CREATE******************
		if ('Create' == oEvent.oSource.mProperties.text) {
			var obj = {};
			obj.id = that.getView().byId("uniqueid").getValue();
			obj.name = that.getView().byId("nameid").getValue();
			obj.email = that.getView().byId("emailid").getValue();
			obj.mobile = that.getView().byId("mobid").getValue();
			myModel.create('/userdataSet', obj, {
				success : function(oData, oResponse) {
					debugger;
					alert('Record Created Successfully...');
				},
				error : function(err, oResponse) {
					debugger;
					alert('Error while creating record - '
							.concat(err.response.statusText));
				}
			});
		}
		// READ******************
		else if ('Read' == oEvent.oSource.mProperties.text) {
			var readurl = "/userdataSet?$filter=(id eq '')";
			myModel.read(readurl, {
				success : function(oData, oResponse) {
					debugger;
					var userdata = new sap.ui.model.json.JSONModel({
						"Result" : oData.results
					});
					var tab = that.getView().byId("userdatatable");
					tab.setModel(userdata);
					var i = 0;
					tab.bindAggregation("items", {
						path : "/Result",
						template : new sap.m.ColumnListItem({
							cells : [ new sap.ui.commons.TextView({
								text : "{id}",
								design : "H5",
								semanticColor : "Default"
							}), new sap.ui.commons.TextView({
								text : "{name}",
								design : "H5",
								semanticColor : "Positive"
							}), new sap.ui.commons.TextView({
								text : "{email}",
								design : "H5",
								semanticColor : "Positive"
							}), new sap.ui.commons.TextView({
								text : "{mobile}",
								design : "H5",
								semanticColor : "Positive"
							}), ]
						})
					});
				},
				error : function(err) {
					debugger;
				}
			});
		}		
		// UPDATE******************
		if ('Update' == oEvent.oSource.mProperties.text) {
			var obj = {};
			obj.id = that.getView().byId("uniqueid").getValue();
			obj.email = that.getView().byId("emailid").getValue();
			var updateurl = "/userdataSet(id='"
					+ that.getView().byId("uniqueid").getValue() + "')";
 
			myModel.update(updateurl, obj, {
				success : function(oData, oResponse) {
					debugger;
					alert('Record Updated Successfully...');
				},
				error : function(err, oResponse) {
					debugger;
					alert('Error while updating record - '
							.concat(err.response.statusText));
				}
			});
		}		
		// DELETE******************
		if ('Delete' == oEvent.oSource.mProperties.text) {
			var delurl = "/userdataSet(id='"
					+ that.getView().byId("uniqueid").getValue() + "')";
			myModel.remove(delurl, {
				success : function(oData, oResponse) {
					debugger;
					alert('Record Removed Successfully...');
				},
				error : function(err, oResponse) {
					debugger;
					alert('Error while removing record - '
							.concat(err.response.statusText));
				}
			});
		}
	}

4. Save, Deploy and Run the application. You should be able to run the application using below URL

http://hostname:8000/sap/bc/ui5_ui5/sap/zcrud_demo/index.html

Output