SAP UI5: Declaring the Model and OData Service in manifest.json and Using Model Data in XML View

SAP UI5: Declaring the Model and OData Service in manifest.json and Using Model Data in XML View

In my previous posts on SAPUI5, I often used somewhat "creepy" methods for declaring the model and OData services in demo applications. In this post, I’d like to go over alternative — and, let’s say, more proper — ways of working with these components.

Example 1

Declaring the OData Service in manifest.json (1)

To declare the OData service used by the application, make the necessary changes in manifest.json.

See also:

Descriptor (manifest.json)
Descriptor for Applications, Components, and Libraries

For example:

"dataSources": {
            "backend": {
                "uri": "/sap/opu/odata/sap/ZREACT_APP_SRV/",
                "type": "OData",
                "settings": {
                    "odataVersion": "2.0"
                }
            }
        }

Declaring the Model in manifest.json (2)

In addition to the initialized OData service above, a newly created SAP UI5 application will also need a data model. This model can also be declared in manifest.json.

See also

Models

Example:

employee": {
                "dataSource": "backend",
                "type": "sap.ui.model.odata.v2.ODataModel"
            }

N.B. Pay attention to the type of the declared model (type attribute).
See also:

Class class sap.ui.model.odata.v2.ODataModel

The resulting manifest.json with the relevant changes will look like this:

Using manifest.json to Populate View with Data (3)

Once the OData service and corresponding data model are declared, you need to update the View in your SAPUI5 app to display the data returned by the service.

<mvc:View controllerName="com_zapplication99.controller.Table" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
    displayBlock="true" xmlns="sap.m">
    <App>
        <pages>
            <Page>
                <content>
                    <Table id="idEmployeesTable" inset="false" fixedLayout="Strict" alternateRowColors="true" items="{path: \'employee>/employeeSet\'}">
                        <headerToolbar>
                            <OverflowToolbar>
                                <Title text="{i18n>title}" level="H2"/>
                            </OverflowToolbar>
                        </headerToolbar>
                        <columns>
                            <Column >
                                <Text text="Personnel Number"/>
                            </Column>
                            <Column >
                                <Text text="Name of Employee"/>
                            </Column>
                            <Column minScreenWidth="Tablet">
                                <Text text="EMail"/>
                            </Column>
                        </columns>
                        <items>
                            <ColumnListItem>
                                <cells>
                                    <ObjectIdentifier text="{employee>id}"/>
                                    <Text text="{employee>name}"/>
                                    <Text text="{employee>email}"/>
                                </cells>
                            </ColumnListItem>
                        </items>
                    </Table>
                </content>
            </Page>
        </pages>
    </App>
</mvc:View>

Please note that the View specifies the model and corresponding  entitySet, allowing data to be fetched for the control. A key feature of this approach is that the model is bound directly to the control. As a result, the framework independently handles the call to the OData service and the specified entitySet to retrieve and display the data.

0:00
/0:59

Testing the Output

Declaring the OData Service in manifest.json (1)

To try an alternative approach, I’ll register a new data source, which in this case will be a locally created JSON file.

Shown here in the project structure:

Declaring the Model in manifest.json (2)

I define the data model in manifest.json.

N.B. Pay attention to the type of the declared model (type attribute).
See also:

Class class sap.ui.model.json.JSONModel

Retrieving Data for the View (3)

In this example, it’s not enough to rely solely on manifest.json settings — we’ll need to handle some logic in the controller.

Example:

var oModel = this.getOwnerComponent().getModel("employee");
 
var oModel2 = this.getOwnerComponent().getModel("localJSON");
 
oModel.read("/employeeSet", {
    success: function(oData, response) {
    oModel2.setProperty("/employeeData", oData.results);
 }
}

See also:

Controller

Class class sap.ui.model.json.JSONModel (setProperty)

Then I update the View:

<mvc:View controllerName="com_zapplication99.controller.Table" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
    displayBlock="true" xmlns="sap.m">
    <App>
        <pages>
            <Page>
                <content>
                    <Table id="idEmployeesTable" inset="false" fixedLayout="Strict" alternateRowColors="true" items="{path: \'localJSON>/employeeData\'}">
                        <headerToolbar>
                            <OverflowToolbar>
                                <Title text="{i18n>title}" level="H2"/>
                            </OverflowToolbar>
                        </headerToolbar>
                        <columns>
                            <Column >
                                <Text text="Personnel Number"/>
                            </Column>
                            <Column >
                                <Text text="Name of Employee"/>
                            </Column>
                            <Column minScreenWidth="Tablet">
                                <Text text="EMail"/>
                            </Column>
                        </columns>
                        <items>
                            <ColumnListItem>
                                <cells>
                                    <ObjectIdentifier text="{localJSON>id}"/>
                                    <Text text="{localJSON>name}"/>
                                    <Text text="{localJSON>email}"/>
                                </cells>
                            </ColumnListItem>
                        </items>
                    </Table>
                </content>
            </Page>
        </pages>
    </App>
</mvc:View>

Testing the Output

0:00
/1:41

Compared to the approach in Example #1, this method provides more flexibility for the developer/consultant to manipulate the data in the model before binding it to application controls.

See also:

Class  class sap.ui.model.json.JSONModel (setProperty)

A Small Adjustment to the Controller Code

onAfterRendering: function() {
            var oModel = this.getOwnerComponent().getModel("employee");
 
            var oModel2 = this.getOwnerComponent().getModel("localJSON");
 
            oModel.read("/employeeSet", {
                    success: function(oData, response) {
                        oModel2.setProperty("/employeeData", oData.results);
                        oModel2.setProperty("/myProperty", "signatov.com");
                    }
                }
 
            );
        }

Adding New Property Output in the View

<mvc:View controllerName="com_zapplication99.controller.Table" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
    displayBlock="true" xmlns="sap.m">
    <App>
        <pages>
            <Page>
                <content>
                    <Table id="idEmployeesTable" inset="false" fixedLayout="Strict" alternateRowColors="true" items="{path: \'localJSON>/employeeData\'}">
                        <headerToolbar>
                            <OverflowToolbar>
                                <Title text="{i18n>title}" level="H2"/>
                                <Title text="with love from {localJSON>/myProperty}" level="H2"/>
                            </OverflowToolbar>
                        </headerToolbar>
                        <columns>
                            <Column >
                                <Text text="Personnel Number"/>
                            </Column>
                            <Column >
                                <Text text="Name of Employee"/>
                            </Column>
                            <Column minScreenWidth="Tablet">
                                <Text text="EMail"/>
                            </Column>
                        </columns>
                        <items>
                            <ColumnListItem>
                                <cells>
                                    <ObjectIdentifier text="{localJSON>id}"/>
                                    <Text text="{localJSON>name}"/>
                                    <Text text="{localJSON>email}"/>
                                </cells>
                            </ColumnListItem>
                        </items>
                    </Table>
                </content>
            </Page>
        </pages>
    </App>
</mvc:View>

Checking the Output

0:00
/1:02

P.S.

Special thanks to my colleague Mikhail for assistance and advice on some of the technical aspects.