Technology Blog Posts by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
LudoNoens
Product and Topic Expert
Product and Topic Expert
3,944

Updated, 12 Nov 2024 : removed workaround to avoid an interoperability issue between SAP Build Apps and CAP version 8, as this was fixed in CAP.

This blog post is the eighth in a series of posts that cover the connectivity options available for SAP Build Apps to interface with SAP systems. The series will cover connecting SAP Build Apps with the following:

  1. CAP-based services
  2. S/4HANA systems
  3. ABAP systems

The format of this post is similar to a tutorial. However, I'll provide more comprehensive details, tips and the opportunity for you to provide feedback. Based on the feedback we will be able to adjust and enhance this post and future parts of the series, and might even be able to improve the products involved as well. 

Introduction 

Before we get into the details of setting up connections between SAP Build Apps and SAP Systems, I intend to introduce a couple of SAP technology components in each post that are relevant for the use cases covered in the series.

CRUD operations

The acronym CRUD stands for Create, Read, Update, Delete. CRUD operations refer to the four basic functions of persistent storage. In the context of OData (Open Data Protocol), these operations are used to interact with data services.

Take note that when interacting with a data service, you are not only storing or retrieving data. The service can also implement (business) logic that is executed when receiving such requests. E.g. for data validation, or triggering another process. Besides that, when looking at access control discussed in part 2 of this blog series, we can configure access to these operations individually for each user.

Use case H : creating a CRUD application in SAP Build Apps

The application we have built so far in this series only shows lists of information. There is no way for the user to create new records, update existing records, or delete records. In this blog post we will change the application we've built in SAP Build Apps into a so-called CRUD application, allowing users to make change to the data stored in the database.

Assuming we are starting a new development session, we open the SAP Build lobby.

LudoNoens_0-1724754024333.png

As visible in the list of SAP Build projects, we now have 2 versions of the UI application created in SAP Build Apps. Let's open this by selecting the link.

SAP Build Apps opens, and notifies us that there are updates in the marketplace. This is due to a recent release of updates that include components released in the marketplace.

LudoNoens_1-1724754248037.png

Clicking on the notification brings us to marketplace updates.

LudoNoens_2-1724754369217.png

Select INSTALL UPDATES to retrieve the latest updates for the flow functions covering create, update and delete a record and SAVE your updated project. These updates are actually quite relevant for this use case!

We can test the current app in Preview to see whether these changes had any impact on our app. When selecting Preview, you will be able to pick the version. We'll pick the latest.

LudoNoens_3-1724754809342.png

Just as to showcase the starting point of our development, here is a screenshot of the current web preview. It is a very basic list without pagination.

LudoNoens_5-1724757357084.png

Notice that I've deployed some more initial sample data for the service created in SAP Build Code. This will help while testing the page, for which will also implement the data pagination.

Update the data entity used in our project

Before we get started, we need to update our project to the latest changes in the data service. When we started developing the application, the data entity Products only contained the properties ID, name and price. In the previous blog post we have added a relationship to Supplier, which is stored in a S/4HANA Cloud system.

To update the project, simply navigate to the DATA tab in SAP Build Apps and select the OData integration for Products. The Data entities overview will show the additional field a_Supplier_Supplier, which we've added. However, this simply reflects the current information retrieved from the data service. This might change over time, as new versions of the service are released. Your project in SAP Build Apps does not automatically update to reflect these changes.

To update your project, select DISABLE DATA ENTITY, followed by ENABLE DATA ENTITY for the data entity Products, to ensure the newly added property Supplier is included in your project.

LudoNoens_0-1725247263758.png

 

Creating a new page to replace the existing one

Instead of changing the existing starting page of the app, we will start by creating a new one. This allows you to refer to a fully functioning page, while we create a replacement. In case you misconfigured something, you can easily check the old page.

Navigate to the pages overview and select ADD NEW PAGE. Provide a name for the page. In this case, I am assigning it the name "Products List", which is going to replace the page "Blog Demo App".

LudoNoens_6-1724757760986.png

Once the UI canvas editor opens, switch to the VARIABLES and navigate to the DATA VARIABLES tab. Select ADD DATA VARIABLE and pick the Products entity. Rename the data variable to ProductsList. Open the logic editor and connect the Page focused event to the Get record collection. Whenever a user navigates to this page, we will refresh the record collection. This ensures we see the latest updates reflected in the list.

LudoNoens_7-1724758523071.png


We also add Page Variables to handle the pagination. This will be similar to what we created in blog episode 4, but we'll use a different UI control here and a slightly different configuration.

LudoNoens_7-1724827419062.png


Adding the list control and page navigation

Switching back to UI Canvas View, we will add list item, navigation buttons and a text field to indicate the page number.  

LudoNoens_3-1724817604246.png

To prevent the user from navigating to invalid pages, we'll make use of the Disabled property on the buttons. For the left button, we control the property with the following formula.

 

 

IF(pageVars.CurrentPage>1, false, true)

 

 

For the right button, we'll disable it to prevent the user from navigating beyond the last page. For this, configure the Disabled property and bind it to the formula:

 

 

IF(pageVars.CurrentPage<pageVars.TotalPageCount, false, true)

 

 

For the displaying the current and total amount of pages, we simply bind the Content property to the formula

 

 

"Page: "+pageVars.CurrentPage + " of "+pageVars.TotalPageCount

 

 


We'll need to add some logic to both buttons to increase or decrease the current page number respectively. Select the button and open the logic canvas.

LudoNoens_0-1725010244784.png


For the left button, we set the page variable CurrentPage as follows:

 

 

pageVars.CurrentPage-1

 

 

Since we disable the button once CurrentPage is 1, we can keep this formula simple.

For the right button, we set the page variable CurrentPage as follows:

 

 

pageVars.CurrentPage+1

 

 


After updating the CurrentPage variable, we configure "Get record collection" with pagination as below.

LudoNoens_8-1724828565668.png

And after this, we will set the data variable ProductsList to the Output value of the previous node.

LudoNoens_9-1724828678402.png

We apply the above for the both buttons.


Getting the total amount of records

The page variable TotalPageCount is based on the total amount of records in the database divided by the amount of items we display per page. In this example we will use a fixed number of 10 items per page. You could implement more sophisticated paging that fills the visible screen or window, but we'll keep it simple here.

LudoNoens_0-1724814201714.png


Select the page canvas and open the logic editor. We will get the record collection of Products, followed by setting the page variable TotalPageCount as follows:

 

 

INTEGER((outputs["Get record collection"].totalCount -1) / 10) + 1

 

 

The formula uses the output of "Get record collection" to find out the total amount of records. To prevent loading all data, adding unnecessary overhead and even potential crashes, we need to customise this data request. We configure the property Paging of Get record collection. For the binding, select Object with properties, configured as shown below.

LudoNoens_1-1724814707150.png

Since we don't need to load any data to retrieve the total record count, we will set the page size and page number to zero. What's relevant for now, is to Include total count.

Switch back to the VARIABLES view and update the logic flow of ProductsList. For Get record collection, we configure Paging.

LudoNoens_0-1725013599223.png

And we store the result of Get record collection in the ProductsList variable.

LudoNoens_1-1725013700694.png

 

Adding the new page into the application's navigation flow

Now that we are done with the list and the pagination, we add the page into the application's navigation flow. Go to the NAVIGATION tab and select Add item. Select the page we have developed. Give it a meaningful name and assign it a suitable icon.

LudoNoens_2-1724815057098.png

 

Previewing and testing the updated app

Navigate to LAUNCH and select Open preview portal. Select Open web preview and use the latest version to Open preview. If all is configured correctly, we should see a list of 10 products and are able to use the buttons to navigate the pages.

LudoNoens_12-1724829385916.png

 

Adding Create, Update and Delete

In the previous section, we have covered the Read operations for this CRUD app. It is now time to add the functionality for Create, Update and Delete.

Navigate to the pages overview and select ADD NEW PAGE. Provide a name for the page. In this case, I am assigning it the name "Create new product".

Once the page is opened in UI Canvas editor, switch to the variables and create a new data variable for storing the new record. Add a new data variable based on Products. As for the data variable type, select New data record. For the name of the data variable, I am using "newProduct".

LudoNoens_13-1724831467348.png

On the UI Canvas, drag and drop a Button and a few Input fields. Bind the value of the input fields, to the newProduct record items. 

LudoNoens_1-1725248235487.png

For the Create button, we need to add some more logic.

LudoNoens_17-1724833932654.png

On receiving the component tap event, we create a new data record in Products. Upon success, we briefly show a toast message and navigate back to the previous page. Upon failure, we will show an alert and stay on the current page.

As for the configuration of Create record, we use the following custom object:

LudoNoens_3-1725015241606.png

For ID, we will generate UUID using a formula. The properties name and price are assigned the corresponding values in the newProduct record.

Adding a detail page for Read, Update and Delete

Following the master-detail UI pattern, we will now add a new page that shows the details of a selected record.

Navigate to the pages overview and select ADD NEW PAGE. Provide a name for the page. In this case, I am assigning it the name "Product Details".

Once the page is opened in UI Canvas editor, switch to the variables and create a new data variable for the storing the selected record.

We add a page parameter called productID of type UUID.

LudoNoens_0-1724991357833.png

Add a new data variable based on Products. As for the data variable type, select New data record. For the name of the data variable, I am using "selectedProduct", and the ID will be the previously created productID.

LudoNoens_1-1724991492866.png

Going back to the UI canvas, we drag and drop a few buttons and input fields.

LudoNoens_2-1725248700754.png

For the Delete button, we add some more logic. When the Delete button is pressed, we ask for confirmation using a dialog. If confirmed, we delete the record with ID productID from Products. When successful, we navigate back to the previous page. If deletion fails, we show an alert to inform the user.

LudoNoens_0-1724995075939.png

For the Update button, we add a similar logic flow. When the Update button is pressed, we update the record with ID productID of Products. When successful, we navigate back to the previous page. If the update fails, we show an alert to inform the user.

LudoNoens_1-1724995613499.png

Now that we are done with the Product Details page, we will configure the page navigation for accessing the new pages we have added to the app.

Adding page navigation

We go back to the newly created Products List page, and drag and drop a button onto the page. I've also removed the Title and the Text on top of the page to make room for a button.

LudoNoens_19-1724834641791.png

Upon receiving the Component tap event, we open the 'Create new product' page, and provide the selected item as parameter.

LudoNoens_2-1724996073048.png

 

After testing the app in preview, and are happy with the new page, we can remove the old Products List and replace it with the new one. We also rename the new page and move it to the top of the navigation list.

LudoNoens_0-1725255948953.png

 

Not the most efficient implementation

Is this the most perfect and efficient configuration of a CRUD app in SAP Build Apps? Not likely. That was not the goal of this blog post. I have tried to keep things simple. There is surely room for improvement, such as:

  • Trigger less OData service requests
  • Make use of entity data already received, instead of sending another query
  • Faster trigger of queries when navigating pages

Stay tuned for improvements in this area, while we are adding more features to SAP Build Apps.

The end-result on Mobile (preview app)

Below is a screen recording of the app running on my iPhone inside the SAP Build Apps app. I am showing a list of products (Read), Adding a new product (Create), checking whether the pagination counts the correct number of pages, update to price of a selected product (Update) and finally remove a selected product (Delete).

CRUD_iPhone2 (2).gif


Summary – use case G

In this use case we have replaced a simple list view page with a CRUD page. Instead of modifying the existing page, we've introduced a new one, that eventually replaced the original page.

As a first step, we've added pagination. This avoids loading lot's of data coming from an S/4HANA Cloud system. 

Next, we've added a page for adding new products and add a button to navigate to this page.

Follow the master-detail UI pattern, when a user selects a product from the list, a new page will open that shows all the details of the product. In our example we have Supplier as additional information. But there is surely room for more. The detail page allows users to update the record. We've also added a button to delete the record.

What's next

We have come to the end of this blog series that was mainly focussed on SAP Build Apps. I will soon start a new series focussed on mobile application development in SAP Build, using Mobile Development Kit (MDK) and SAP Mobile Services.

 

2 Comments