3
votes

I am trying to use expand option in my XML view but it's resulting no data.

Screenshot No Data

Data are coming from backend as I can see in debugging under 'Network' option but there seems to be some binding issue in XML view.

Component.js

sap.ui.define([
    "sap/ui/core/UIComponent",
    "sap/ui/Device",
    "sem/stock_app/model/models"
], function(UIComponent, Device, models) {
    "use strict";

    return UIComponent.extend("sem.stock_app.Component", {

        metadata: {
            manifest: "json"
        },

        /**
         * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
         * @public
         * @override
         */
        init: function() {
            var url = "/sap/opu/odata/sap/ZMATLIST_SRV_02";
            var odata = new sap.ui.model.odata.ODataModel(url, {
                json: true
            });
            this.setModel(odata);
            UIComponent.prototype.init.apply(this, arguments);
            this.getRouter().initialize();
            this.setModel(models.createDeviceModel(), "device");
        }
    });
});

manifest.json

{
    "_version": "1.7.0",
    "sap.app": {
        "id": "sem.stock_app",
        "type": "application",
        "i18n": "i18n/i18n.properties",
        "applicationVersion": {
            "version": "1.0.0"
        },
        "title": "{{appTitle}}",
        "description": "{{appDescription}}",
        "sourceTemplate": {
            "id": "ui5template.basicSAPUI5ApplicationProject",
            "version": "1.40.12"
        }
    },
    "sap.ui": {
        "technology": "UI5",
        "icons": {
            "icon": "",
            "favIcon": "",
            "phone": "",
            "phone@2": "",
            "tablet": "",
            "tablet@2": ""
        },
        "deviceTypes": {
            "desktop": true,
            "tablet": true,
            "phone": true
        },
        "supportedThemes": [
            "sap_hcb",
            "sap_belize"
        ]
    },
    "sap.ui5": {
        "rootView": {
            "viewName": "sem.stock_app.view.mat",
            "type": "XML"
        },
        "dependencies": {
            "minUI5Version": "1.30.0",
            "libs": {
                "sap.ui.core": {},
                "sap.m": {}
            }
        },
        "contentDensities": {
            "compact": true,
            "cozy": true
        },
        "models": {
            "i18n": {
                "type": "sap.ui.model.resource.ResourceModel",
                "settings": {
                    "bundleName": "sem.stock_app.i18n.i18n"
                }
            }
        },
        "resources": {
            "css": [{
                "uri": "css/style.css"
            }]
        },
        "routing": {
            "config": {
                "routerClass": "sap.m.routing.Router",
                "viewType": "XML",
                "viewPath": "sem.stock_app.view",
                "controlId": "idAppControl",
                "controlAggregation": "pages"
            },
            "routes": [{
                "name": "r1",
                "pattern": "",
                "target": "t1"
            },
                {
                    "name": "r2",
                    "pattern": "page2/{noti}",
                    "target": "t2"
                }],
            "targets": {
                "t1": {
                    "viewName": "mat",
                    "viewId": "idmat",
                    "controlAggregation": "pages",
                    "viewLevel": 1
                },
                "t2": {
                    "viewName": "table",
                    "viewId": "idtable",
                    "controlAggregation": "pages",
                    "viewLevel": 2
                }
            }
        }
    }
}

Root View

<mvc:View
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    controllerName="sem.stock_app.controller.mat"
    displayBlock="true"
>
    <App id="idAppControl">
        <Page title="Material Input">
            <Label text="Material Selection"/>
            <Input id="materialInput"
                type="Text"
                width="50%"
                placeholder="Enter Material"
                showSuggestion="true"
                showValueHelp="false"
                valueHelpRequest="handleValueHelp"
                submit="onSubmit"
                suggestionItems="{/matlistSet}"
            >
                <suggestionItems>
                    <core:Item text="{Matid}"/>
                </suggestionItems>
            </Input>
            <Button text="Get Details" enabled="true" press="myPress"/>
        </Page>
    </App>
</mvc:View>

Table View

<mvc:View
    xmlns:core="sap.ui.core"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m"
    controllerName="sem.stock_app.controller.table"
>
    <App id="tableApp">
        <Page
            title="Table"
            showNavButton="true"
            navButtonPress="onNavBack"
        >
            <Table
                growing="true"
                items="{
                    path: 'odata>/matlistSet',
                    parameters: {
                        expand: 'NP_ON_MATID'
                    }
                }"
                itemPress="onListItemPressed"
                width="100%"
                mode="MultiSelect"
            >
                <columns>
                    <Column>
                        <Text text="Material ID"/>
                    </Column>
                    <Column>
                        <Text text="Category"/>
                    </Column>
                    <Column>
                        <Text text="Material Desc"/>
                    </Column>
                    <Column>
                        <Text text="Plant"/>
                    </Column>
                </columns>
                <items>
                    <ColumnListItem type="Active">
                        <Text text="{odata>NP_ON_MATID/Matid}"/>
                        <Text text="{odata>NP_ON_MATID/Category}"/>
                        <Text text="{odata>NP_ON_MATID/Matdesc}"/>
                        <Text text="{odata>NP_ON_MATID/Plant}"/>
                    </ColumnListItem>
                </items>
            </Table>
        </Page>
    </App>
</mvc:View>

Table Controller

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/routing/History"
], function(Controller, History) {
    "use strict";

    return Controller.extend("sem.stock_app.controller.table", {
        onInit: function() {this.getOwnerComponent().getRouter().getRoute("r2").attachPatternMatched(this.mynav, this);
            this.getOwnerComponent().getRouter().setView("table");
        },

        mynav: function(oeve) {
            var data = oeve.getParameters().arguments.noti;
            var params = "('" + data + "')?$expand=NP_ON_MATID";
            var path = "/matlistSet" + params + "";
            this.getView().bindElement(path);
        },

        onNavBack: function(window) {
            var oHistory = History.getInstance();
            var sPreviousHash = oHistory.getPreviousHash();
            if (sPreviousHash !== undefined) {
                window.history.go(-1);
            } else {
                var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
                oRouter.navTo("overview", {}, true);
            }
        },

    });
});

metadata.xml

<?xml version="1.0" encoding="utf-8" ?> 
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:sap="http://www.sap.com/Protocols/SAPData">
    <edmx:DataServices m:DataServiceVersion="2.0">
        <Schema Namespace="ZMATLIST_SRV_02" xml:lang="en" sap:schema-version="1" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
            <EntityType Name="matlist" sap:content-version="1">
                <Key>
                    <PropertyRef Name="Matid" />
                </Key>
                <Property Name="Matid" Type="Edm.String" Nullable="false" MaxLength="18" sap:unicode="false" sap:label="Material" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Category" Type="Edm.String" Nullable="false" MaxLength="20" sap:unicode="false" sap:label="Char20" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Matdesc" Type="Edm.String" Nullable="false" MaxLength="40" sap:unicode="false" sap:label="Char" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Plant" Type="Edm.String" Nullable="false" MaxLength="4" sap:unicode="false" sap:label="Plant" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Status" Type="Edm.String" Nullable="false" MaxLength="20" sap:unicode="false" sap:label="Char20" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Qty" Type="Edm.Decimal" Nullable="false" Precision="13" Scale="3" sap:unicode="false" sap:label="Quantity" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <NavigationProperty Name="NP_ON_MATID" Relationship="ZMATLIST_SRV_02.MATASSOCIATION" FromRole="FromRole_MATASSOCIATION" ToRole="ToRole_MATASSOCIATION" />
            </EntityType>
            <EntityType Name="matdetails" sap:content-version="1">
                <Key>
                    <PropertyRef Name="Matid" />
                </Key>
                <Property Name="Matid" Type="Edm.String" Nullable="false" MaxLength="18" sap:unicode="false" sap:label="Material" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Matitno" Type="Edm.Int32" Nullable="false" sap:unicode="false" sap:label="Number" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Category" Type="Edm.String" Nullable="false" MaxLength="20" sap:unicode="false" sap:label="Char20" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Matdesc" Type="Edm.String" Nullable="false" MaxLength="40" sap:unicode="false" sap:label="Char" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Plant" Type="Edm.String" Nullable="false" MaxLength="4" sap:unicode="false" sap:label="Plant" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
            </EntityType>
            <Association Name="MATASSOCIATION" sap:content-version="1">
                <End Type="ZMATLIST_SRV_02.matlist" Multiplicity="1" Role="FromRole_MATASSOCIATION" />
                <End Type="ZMATLIST_SRV_02.matdetails" Multiplicity="*" Role="ToRole_MATASSOCIATION" />
                <ReferentialConstraint>
                    <Principal Role="FromRole_MATASSOCIATION">
                        <PropertyRef Name="Matid" />
                    </Principal>
                    <Dependent Role="ToRole_MATASSOCIATION">
                        <PropertyRef Name="Matid" />
                    </Dependent>
                </ReferentialConstraint>
            </Association>
            <EntityContainer Name="ZMATLIST_SRV_02_Entities" m:IsDefaultEntityContainer="true" sap:supported-formats="atom json xlsx">
                <EntitySet Name="matlistSet" EntityType="ZMATLIST_SRV_02.matlist" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:content-version="1" />
                <EntitySet Name="matdetailsSet" EntityType="ZMATLIST_SRV_02.matdetails" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:content-version="1" />
                <AssociationSet Name="MATASSOCIATIONSet" Association="ZMATLIST_SRV_02.MATASSOCIATION" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:content-version="1">
                    <End EntitySet="matlistSet" Role="FromRole_MATASSOCIATION" />
                    <End EntitySet="matdetailsSet" Role="ToRole_MATASSOCIATION" />
                </AssociationSet>
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>
1

1 Answers

3
votes

Issues to fix

Backend

  • According to your service metadata, the foreign key inside matdetails is also the only primary key at the same time. I.e. the Matids in matdetails cannot be unique if one matlist is supposed be associated with multiple matdetails entities.

    → Make sure that primary keys (or them combined) are all unique in the entire entity set.

  • According to your screenshot, the response body of your entity set doesn't contain the property "results" which is not OData V2 compliant (Same as this issue. See also difference between OData V1 and OData V2). The "response" property needs to be there in each collection so that UI5 can display the items correctly.

    → Make sure that the response body is OData V2 compliant.

Frontend

Model

  • There was no model name passed when calling setModel.
    • → Either pass the model name according to your view: this.setModel(odata, "odata")
    • → Or remove the model name from everywhere. E.g.: <Text text="{Matid}"/>
  • Also worth reading: Stop Using sap.ui.model.odata.ODataModel!

UI

  • The root view and its controller are instantiating twice. In order to avoid that, please read:

  • The application contains <App> multiple times. A typical UI5 application should contain only a single root element. If not, you might end up having this kind of problems.

    → Remove all the <App> from views except from the root view.

  • Since you want to display matdetails entities of selected matlist entity in the table, binding items there with the absolute path /matlistSet doesn't make sense.

    → Replace ...

    items="{
      path: 'odata>/matlistSet',
      parameters: {
        expand: 'NP_ON_MATID'
      }
    }

    ... with items="{ path: 'odata>NP_ON_MATID', templateShareable: false }". This binding is now relative. The navigation property NP_ON_MATID will be resolved once the selected context is given in the controller. See also Binding Path from the documentation.

Controller

  • On patternMatched, the selected Matid value is given. So far so good but there are two anti-patterns in the following lines:

    var params = "('" + data + "')?$expand=NP_ON_MATID";
    var path = "/matlistSet" + params + "";
    1. Avoid creating entity key(s) manually.
    2. → Avoid appending ?$expand manually as it won't expand the entity. Pass the navigation property to the parameters/expand of bindElement/bindObject instead.
  • Off-topic but if you want to navigate back: Remove window parameter from onNavBack: function(window) { ... }. Otherwise, the window in window.history.go is not the global window object but the press event from the back button.