Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
Product and Topic Expert
Product and Topic Expert


Dear reader, thanks for coming to have a look at the second part of our SAP HANA XSA series where we investigate smart tables and smart variants.

It's the peak of summer in Tokyo and working under airconditioning and having a coffee in the afternoon helps to stay focused. ? Let's get to code!

Highlights of this course:

  • Convert any OData v4 served by CDS into v2 which is what is required when we use SAP UI5 and not Fiori Elements.

  • We will see how to use smart variants to save the selection and filter as well as the table customization for each user on SAP HANA.

Adding a smart table to our project

We add an SAP UI5 HTML5 module to our project tree. I gave it the meaningful name "usingSmartTables".

When we look into the aSimpleSmartTable.view.xml you can see that I have added Customers as an entityset to be used by the table and filterbar. You might recall that this is the name we defined in our CDS service in the last blog!

We aim to consume the CDS Odata service we created before which runs on our SAP HANA XSA system. There is a tiny problem, though: While CDS serves Odata v4, SmartTable needs v2 to work! What now? Well, we have two options:

  1. Turn our attention to Fiori Elements which work natively with v4 and give up on SmartTable.

  2. Convert the OData v4 service into and Odata v2 service by using CDS OData V2 Adapter Proxy.

As you might have already guessed we will persue option 2.? SAP provided an extremely useful tool to on one hand have the benefit of using CDS with its simplicity to expose services and on the other keep the wonderful world of UI5 accessible by converting down to v2.

For that we must make some adjustments to our srv-CDS service. We add a new file server.js to the module and add the v2 adapter proxy into the package.json.

When we open the new server.js file it should look like this:
'use strict';

const proxy = require('@sap/cds-odata-v2-adapter-proxy');
const cds = require('@sap/cds');
cds.on('bootstrap', app => app.use(proxy()));
module.exports = cds.server;

You can see that we include the proxy and the cds which is the core library of the CAP (Cloud Application Programming) model. At the time the CDS service starts up, we inject the proxy into the express middleware framework and make the proxy therefore available for all requests to the CDS service.

Attention: reading a server.js file by a CDS service is a functionality provided since February 2020. Make sure you have the latest CDS in the package.json. For example, my HANA used version 3.21.1 by default!

Let's start up the service again and have a look at the log-files:
Application is starting
8/26/20 4:41:33.829 AM [APP/12-0] OUT
8/26/20 4:41:34.850 AM [APP/12-0] OUT [HPM] Proxy created: / -> http://localhost:40409
8/26/20 4:41:34.851 AM [APP/12-0] OUT [HPM] Proxy rewrite rule created: "^/v2" ~> ""
8/26/20 4:41:34.901 AM [APP/12-0] OUT [cds] - model loaded from 1 file(s):
8/26/20 4:41:34.902 AM [APP/12-0] OUT gen/csn.json
8/26/20 4:41:35.268 AM [APP/12-0] OUT [cds] - connect to db > hana { schema: 'HANAXSATOPICS_HANAXSATOPICS_DB_HDI_CONTAINER_1',
8/26/20 4:41:35.270 AM [APP/12-0] OUT [cds] - connect to messaging > local-messaging {}
8/26/20 4:41:35.924 AM [APP/12-0] OUT [cds] - serving flightService { at: '/flight' }
8/26/20 4:41:35.926 AM [APP/12-0] OUT
8/26/20 4:41:35.926 AM [APP/12-0] OUT [cds] - launched in: 2100.037ms
8/26/20 4:41:35.926 AM [APP/12-0] OUT [cds] - server listening on { url: 'http://localhost:40409' }
Application is running

You can see the server.js' proxy was started before the CDS was called. We can now reach our CDS Odata in version 4 and 2:

Odata v4 metadata callable from [server:port]/flight/$metadata

Odata v2 metadata callable from [server:port]/v2/flight/$metadata

Very useful! We can now call our smart table module and check the output.

Smart Table using Odata v2 from proxied CDS.

You can see that our authority check is still in place from the last blog post which restricts us to see only US-based customers.

It's nice, but not perfect, we can see select and filter data. However, when we log in again, all our selections and layout settings are gone. A user wants to hide and add columns, move them, add filters etc. What we need is in the next paragraph of this blog!

Adding smart variant management and making it persistent

To achieve above, we need three things in place:

  1. Smart variant management enabled for the view elements

  2. A backend service that handles the smart variant API requests

  3. A persistence layer to store layouts and filters per user and retrieve them

Let's start in that sequence. We add smart variants to the xml-view, to the SmartFilterbar:

to the SmartTable:
persistencyKey="simpleSmartTableKey" useVariantManagement="true"

these keys are stored in the table as we will see later and must be unique for each element. Let's run our UI5 module again and see what the debugger has for us:

Smart table with variants: Debugger view

The variant selectors have become available. However, we can also see that the UI5 tries to access mysterious services that are required for variant management. On an SAP S/4HANA system you will find these services in the SICF tree /sap/bc/lrep:

LREP handler in S/4HANA transaction SICF

However, we are on HANA XSA, so what can we do?

Luckily, SAP created the Shine application and inside we find a hidden jewel in the form of a service to provide the services needed by the API. I found during testing that a few things were missing like handling of user-specific and global variant (visibile for all) so they are added to the code.

We add a new HANA db module now to our project with a table artifact that has the necessary structure to store and retrieve the variant data and call it coreDb. In the src-folder of that module let's add an HDB CDS file and call it lrep. When looking into the entity variants you will see there are clear similarilties to the Netweaver equivalent. ? Let's build and deploy the HDB CDS by right clicking on the module.

Please check if the table is deployed in the database explorer. It should look like this.

WebIDE database explorer: Lrep table artifact

Finally, let's add the missing node.js-service. In the last blog we prepared for extensibility by introducing the router and index.js. All we need to do is add a new script variantManagement.js in the folder router/routes of our coreNode module.

In the index.js we add the needed code below the line of our previous tutorial:
app.use('/tutorial/', require('./routes/tutorial')()); // Do something for our blog series
app.use('/sap/bc/lrep', require('./routes/variants')()); // Variant management

Since we need to authenticate fromt the coreNode, we have to bind the new DB module in the requires:-section of the mta.yaml. We also remove the previous binding which we used in the first part of this blog for demonstration purposes.

If you re-run the coreNode-module and then the UI5 smart table view, you should recognized the (successful) GET requests to /sap/bc/lrep/flex/ as shown below in the coreNode-log:
"GET /b541901f-0d98-4866-9cbd-f402f3e0a690/appStatus HTTP/1.1" 200 sent 153 in 42 by 01O-9ec148da-b352-453f-b175-e2bbc3f0e094
"GET /sap/bc/lrep/flex/data/usingSmartTables.usingSmartTables.Component?appVersion=1.0.0&sap-language=en-US HTTP/1.1" 200 sent 94 in 94 by 01O-9ec148da-b352-453f-b175-e2bbc3f0e094
"GET /sap/bc/lrep/flex/data/usingSmartTables.usingSmartTables.Component?appVersion=1.0.0&sap-language=en-US HTTP/1.1" 200 sent 94 in 66 by 01O-9ec148da-b352-453f-b175-e2bbc3f0e094

So, let's make the test and customize the layout and selection variant:

Customized layout and selection

The asterisk indicates that a change to the layout occured and we need to save. Let's do this now, I'll call it "HappyLayout". We set it as Default so it should be used anytime, we enter with the same user.  Public would mean it becomes available for all users. Good!

Let's have a look what happened to our DB table:

Variant saved into HANA table

Three entries got created: The default setting, the selection and the layout. Now close the browser window and log in again to our SAP UI5 page. It will pick the default settings as expected.


We saw how to consume a CDS provided service with an SAP UI5 HTML5 module. We also looked into converting an Odata v4 service by means of an SAP provided node-proxy to Odata v2. Finally, we established a persistance layer for smart table and filter variants with visbility on user or global level.