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:
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.
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.
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.
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.
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.
Clicking on the notification brings us to marketplace updates.
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.
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.
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.
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.
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".
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.
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.
Switching back to UI Canvas View, we will add list item, navigation buttons and a text field to indicate the page number.
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.
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.
And after this, we will set the data variable ProductsList to the Output value of the previous node.
We apply the above for the both buttons.
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.
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.
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.
And we store the result of Get record collection in the ProductsList variable.
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.
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.
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".
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.
For the Create button, we need to add some more logic.
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:
For ID, we will generate UUID using a formula. The properties name and price are assigned the corresponding values in the newProduct record.
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.
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.
Going back to the UI canvas, we drag and drop a few buttons and input fields.
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.
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.
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.
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.
Upon receiving the Component tap event, we open the 'Create new product' page, and provide the selected item as parameter.
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.
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:
Stay tuned for improvements in this area, while we are adding more features to SAP Build Apps.
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).
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.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
12 | |
11 | |
7 | |
7 | |
7 | |
6 | |
6 | |
5 | |
5 | |
5 |