Skip to Content

Extending a control in the SAPUI5 library: sap.ui.model.json.JSONModel

Extending a control in the SAPUI5 library: sap.ui.model.json.JSONModel

(Written based on version 1.28 of SAPUI5)

On a recent project building SAPUI5 application to be hosted on HCP (HANA Cloud Platform) we had a requirement to interface with RESTful services exposed by PI. Being a Gateway and OData girl myself this was a new challenge. “At least a REST service is better than a SOAP service”, I thought. “But how can I load the data in, in a neat and tidy way, like I would with a OData service?” The answer: extend the standard JSONModel, and bend it to my will!

Requirements

  1. To be able to load data from a single service into the model without overwriting everything already in it
    1. The “loadData” function already available in the JSONModel could not be used to fulfil this requirement as it sets the response of the request at the root of the model, overwriting any existing data
  2. To load data onto a specified path of the model, in order to allow binding in a view to the correct path before the data is loaded in
  3. To be able to specify whether the structure of the data loaded in should be an array or not
    1. An oddity of PI, or more likely the underlying services it is communicating with, seems to be that if a request for a set of data only finds a single item, it will return an object, rather than an array with one object in it
  4. To be able to bind only specific properties of the response to the model
    1. E.g. the response data is in the following structure, we only want to bind to “Items” node to our model
      1. “d” : { “results” : { “Items” : [ “a” :  ] } }

Overall, I wanted to make my JSONModel “feel” more like an ODataModel.

Solution

  1. Extend the JSONModel control
  2. On instantiation of the model (in the constructor function) include a service URL parameter on which to base all calls subsequently made against the model
  3. Add a new function within the model for loading the data
  4. Add functions to the model to allow “create”, “update” and “remove”

In order to write the code around this I referred to the ODataModel code base, and stole relevant chunks where rewriting them would have been unnecessary.

As the code would be useful across many applications I hosted it on HCP as an HTML5 application called “shared”, even though it is simply a collection of files rather than an executable application. In this way I can now access the extended JSONModel code from other applications hosted on the same HCP by adding a new destination, of type “application”, into the neo-app.json file, and adding a new resource root into the index file.

Please see my GitHub repository, sapui5-shared, for the source code of my extended JSONModel.

Example index.html resource root


<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta charset="UTF-8">
<title>Bluefin Application One</title>
        <script id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-resourceroots='{
" bluefin.application1": "./",
"bluefin.shared": "./shared"
            }'>
</script>
<script>
            sap.ui.getCore().attachInit(function() {
                new sap.ui.core.ComponentContainer({
height : "100%",
name : "bluefin.application1"
}).placeAt("content");
            });
        </script>
    </head>
    <body class="sapUiBody" id="content">
    </body>
</html>

Example neo-app.json file


{
"welcomeFile": "index.html",
  "routes": [
    {
"path": "/resources",
"target": {
"type": "service",
"name": "sapui5",
"entryPath": "/resources"
      },
"description": "SAPUI5 Resources"
    },
    {
"path" : "/shared",
"target" : {
"type" : "application",
"name" : "shared"
      },
"description" : "Shared Utilities"
    },
    {
"path": "/Search",
"target": {
"type": "destination",
"name": "myHCPDestination",
"entryPath" : "/Search"
      },
"description": "Search UI5 destination"
    }
  ]
}

Example code-snippet for use of bluefin.shared.model.JSONModel.loadDataFromPath


jQuery.sap.require("bluefin.shared.model.JSONModel");
var oMyModel = new bluefin.shared.model.JSONModel("/Search");
// Read the booking data from the service

oMyModel.loadDataFromPath("/Objects/Bookings"
            {
sModelPath : "/Bookings",
aResponseProperty : [ "d", "results"],
bReturnArray : true
                 },
            null,
            false
        );
// Array of data can now be found on the model
var aBookings = oMyModel.getProperty("/Bookings");

bluefin.shared.model.JSONModel

The code for the extended JSON Model can be found in the model folder of my sapui5-shared repository.

8 Comments
You must be Logged on to comment or reply to a post.