Search code examples
odatasapui5

How to get model on onInit?


In manifest.json, I have following model definition:

{
    "sap.ui5": {
        "models": {
            "SalesInvoices": {
                "type": "sap.ui.model.odata.v2.ODataModel",
                "settings": {
                    "defaultOperationMode": "Server",
                    "defaultCountMode": "Request"
                },
                "dataSource": "ZAM_SALES_STATISTICS_CDS",
                "preload": true
            }
        }
    }
}

As you can see, SalesInvoices is connected to the OData service.

Now on the onInit function in the controller, I am trying to get Metadata from OData as following:

{ // Controller
    onInit: function() {
        const oPayerModel = this.getView().getModel("SalesInvoices");
        console.log(oPayerModel.getMetadata());
        setTimeout(() => {
            const oPayerModel = this.getView().getModel("SalesInvoices");
            console.log(oPayerModel.getMetadata());
        }, 600);
    },
    // ...
}

As you can see, I have to delay to get the OData instance.
setTimeout is not recommended to use in SAPUI5, how can I do it better?


Solution

  • You can avoid setTimeout, as mentioned in this answer, by using the v2.ODataModel API metadataLoaded instead which returns a promise. The promise is fulfilled once the service metadata is loaded successfully.

    onInit: async function() {
      const oPayerModel = this.getOwnerComponent().getModel("SalesInvoices");
      try {
        await oPayerModel.metadataLoaded(true);
        const oServiceMetadata = oPayerModel.getServiceMetadata(); // NOT .getMetadata()
        // ...
      } catch (oError) {/* ... */}
    },
    

    About the model being undefined in onInit, here are answers with better explanations: