As a reminder, in my last blog, I described how to set up the backend for my social media mashup app, which lets you create ratings and discussions around business data.
Now I will describe how to build the front-end.
How I built the front-end
Setting up the business backend
For this exercise, I created a destination to the Northwind Odata service, but I could have easily used a destination to an S/4HANA system.
I created this destination in the SAP BTP cockpit (note the Additional Properties which let you see it in SAP Build Apps):
Creating new front-end project
In the lobby, I clicked Create → Build an Application → Application Backend, and created a project called RatingSystem.
Connecting app to backends.
On the Data tab, I click Add Integration → BTP Destinations → Northwind.
I then select Install Integration, and then select Products → Enable Data Entity → Save.
To use my backend entities and function, I did pretty much the same thing.
On the Data tab, I click Add Integration → Visual Cloud Functions → Product Ratings (name of my backend project ).
I then selected Install Integration, and selected Ratings → Enable Data Entity → Save. I did the same for the Comments entity.
Then go to the Cloud functions tab, and select AverageRatings → Enable Data Entity → Save.
In the end, I had these entities/function ready to be consumed.
Creating the list of products page
I first created a new page called List of Products. But I wanted to create a special component to help me.
All I used were a Large Image List Item components and a Star Rating component, but I duplicated them so I could modify it for this project without changing them in other projects. (You must install both components from the Marketplace).
Once duplicated, the components are in the By Me tab of the components pane.
I added my duplicated list item component to my page and then opened up the component editor – select the component on the canvas and go to Properties, and at the bottom you can open the component template editor.
I removed the existing text field and added a Star Rating component, as well as 2 text components, so it would look like this.
I also added two properties to the component, Rating and Rating Count, so I could bind those to the values for each product from outside the component. Inside the component, I switched on the Properties view, then selected Properties, and added the 2 properties.
The last thing in the setup of the component was to bind the internal properties to the star rating, and the 2 text components. For example, for the text component showing the count, I did the binding with a formula like this:
"(" + internalProps.RatingCount + ")"
Creating variables and binding
All that was left was to create a data variable for the Northwind Products entity, and an app variable (type List of Object) to hold the results of my Visual Cloud Function. And then bind it all together.
The Northwind data is retrieved automatically when I create the data variable, and to the page mounted event I added the new Execute cloud function flow function, specified my function, and set the output to my app variable.
On my component, I set for it to repeat based on the data variable for the products, and then for the 2 rating properties I set the bindings. The following is for the rating (the one for the count is very similar):
DEFAULT(FIND_BY_KEY(pageVars.Ratings, "productID", STRING(repeated.current.ProductID)).avg,0)
Creating the product details page
I create a standard detail page (with page parameter) to display the product, its rating, and discussion. See this video for the basics of navigation/page parameters for main-detail pages.
For letting the user give a rating, I just added a Star Rating component, and created logic (Value change event) to create a new rating in my backend entity and then disable the component so the user could not add another rating. (Yes, this could be done better, but for the demo I thought it enough.)
For posting a new comment (button tap event), I did a standard Create record flow to my entity, and then wiped out the values in the form form. Once the comment was added to the backend, I retrieved all comments for the product so the page could be updated.
For displaying the comments, I filtered on the current product (in the Get record collection flow function).
And I sorted in descending on the date so the latest comments are always on top.
Finally, I do paging with a page variable. I display 3 records. At the bottom there is a More button and if pressed, it will change the paging to another 3 records, and I will retrieve the records again. I could have done this more cleverly, retrieving just the next page and adding that to my local variable, but, you know, this is enough for the demo.
Sources
I have provided the source projects:
- Import the backend project into your SAP Build lobby. You must open it and then deploy the backend.
- Import the frontend project. You must open it and create the data resource to your backend, and enable the 2 entities and the function.
You can import these into the community edition or SAP AppGyver on BTP. These sources do not use a destination but use a standard OData data resource for Northwind, so you can run this right away without a destination.
Epilogue
Overall, I thought it a cool way to use the Visual Cloud Functions, and to start to enable discussions/social media in apps.
There were a few things I had to do related to modifying the components — e.g., making the stars larger and orange, plus dealing with Star Rating’s two-way property. This area of modifying components is something I am still a little fuzzy about.
A few things I would/should do different next time:
- Get User: I wanted to get the current user so I could label all ratings/comments with that user. But my understanding is that that feature is not yet working for SAP Build Apps (as opposed to SAP AppGyver). Let me know if this changed.
- Change rating: Right now the user cannot change their rating once selected and, at the same time, the user can restart the app and enter another rating.
- Scrolling data and auto-paging: Ideally, the user would scroll to the bottom of the page and then I would retrieve some more records. But my understanding is that there is no event for scrolling, so I used a button. Also, instead of getting all the records again on a slowly growing single page, I would get the next page and add the data to a local variable that would grow.
- Sorting products by rating: This wasn’t as simple as I thought, since my data is still in separate lists. It could be a better solution to mash up the data first and then bind it to the UI. I imagine I could do this after the fact, mash it up, sort, and then unmash, but this seems complicated and prone to problems as the app changes. I have to think about this.
Let me know if you have any questions. Happy Building!!
See all my blogs (Daniel Wroblewski) and connect with me on Twitter / LinkedIn