Search code examples
javascriptsapui5sap-fiori

'No Data' view getting opens first and then Detail Page opens with the data in Fiori


I am developing a Master Detail application in which if the service URL doesn't return data, then a view called 'NoData' should open. But what actually is happening that first, the 'NoData' view opens and then the Detail Page with the data gets displayed. I don't know why and how that 'NoData' page is appearing first. Below is my code for Master Page :

Controller.js :

        onInit: function () {

        this.router = sap.ui.core.UIComponent.getRouterFor(this);
        this._custTemp = this.getView().byId("listItemTemp").clone();
        this.refreshFlag = true; // Flag to get new data or not for customers


        this.totalModel = sap.ui.getCore().getModel("totalModel");
        this.getView().setModel(this.totalModel, "totalModel");

        this.oDataModel = sap.ui.getCore().getModel("DataModel");
        this.getView().setModel(this.oDataModel, "DataModel");


        this.oInitialLoadFinishedDeferred = jQuery.Deferred();
        var oEventBus = sap.ui.getCore().getEventBus();

        this.getView().byId("listId").attachEvent("updateFinished", function () {
            this.oInitialLoadFinishedDeferred.resolve();
            oEventBus.publish("MasterPage", "InitialLoadFinished", {
                oListItem: this.getView().byId("listId").getItems()[0]
            });
            if (!sap.ui.Device.system.phone) {
                this._getFirstItem();
            }
        }, this);

        this.functionData = [];
    },
waitForInitialListLoading: function (fnToExecute) {
        jQuery.when(this.oInitialLoadFinishedDeferred).then(jQuery.proxy(fnToExecute, this));
    },

    _getFirstItem: function () {
        sap.ui.core.BusyIndicator.show();
        this.waitForInitialListLoading(function () {
            // On the empty hash select the first item
            var list = this.getView().byId("listId");
            var selectedItem = list.getItems()[0];
            if (selectedItem) {
                list.setSelectedItem(selectedItem, true);
                var data = list.getBinding("items").getContexts()[0];
                sap.ui.getCore().getModel("detailModel").setData(data.getObject());

                this.router.navTo('DetailPage', {
                    QueryNo: data.EICNO
                });
                sap.ui.core.BusyIndicator.hide();
            } else {
                this.router.navTo('NoData');
            }
        }, this);
    },

    onBeforeRendering: function () {
        this._fnGetData();
    },

    _fnGetData: function (oEvent) {

        var that = this;
        this.getView().setModel(this.totalModel, "totalModel");

        if (this.refreshFlag === true) {
            sap.ui.core.BusyIndicator.show(0);

            $.ajax({
                url: "/sap/opu/odata/sap/ZHR_V_CARE_SRV/EmpQueryInitSet('10002001')?$expand=QueryLoginToQueryList/QueryToLog",
                method: "GET",
                dataType: "json",
                success: function (data) {
                    that.getView().getModel("totalModel").setData(data.d.QueryLoginToQueryList);

                    that.refreshFlag = false;
                    sap.ui.core.BusyIndicator.hide();
                    that.statusList();

                },
                error: function (err) {
                    sap.ui.core.BusyIndicator.hide();
                    MessageBox.information(err.responseText + "Please try again");
                }
            });

        }

    }

Solution

  • totalModel is a json model, right? You'll get two updateFinished events on app load. The first one is triggered once the list control is rendered and binding is done (when the model has no data), and the second comes after your $.ajax call updates data to totalModel.

    I think you can solve it by moving your NoData navigation to both 'success' and 'error' callbacks of your $.ajax call. Doing so may cover other use cases e.g. if you are using URL navigation parameters and a user changes the entity ID in the URL to some random number, it'd navigate to your NoDatapage.