cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with promise sapui5+

al_sapui5
Participant

i have a little problem , i'm trinying to use a promise so only when my odata calls is resolve continue the program but nothing happends and the app freezes

i have a button that triggers this function:

onClickContinuar:function(check){

            if( this.validarCamposContinuar() ){ MessageToast.show("Faltan datos obligatorios!", false, 2000); return; };
            const that       = this;
            const centro     = this.cbCentro.getSelectedKey();
            const almacen    = this.cbCentroAlmacen.getSelectedKey();
            const transporte = this.inputTransporte.getValue();
            const contenedor = this.inputContenedor.getValue();
            this.view.setBusy(true);

            this._checkTransporte().then( function(check) {
// another process
});
_checkTransporte : function() {
            return new Promise(function RESOLVER (resolve) {
                var url = "/sap/opu/odata/sap/ZCLMMVSR_ODATA_CALIDAD_CONT_SRV";
                var oDataModel = new sap.ui.model.odata.ODataModel(url, true);
                var transporte = this.inputTransporte.getValue();
                var mensaje = "";
                sap.ui.core.BusyIndicator.show(0);

                oDataModel.read("/DatosFiltrosSet('" + transporte + "')", {
                    success: function(oData, response) {
                        sap.ui.core.BusyIndicator.hide();
                        if ( oData.EnTratamiento === "X" ) {
                            // TODO OK
                            resolve(mensaje = "");
                        } else if ( oData.EnTratamiento === "O" ) {
                            resolve(mensaje = `El transporte ${transporte} no ha sido inspeccionado`);
                        } else if ( oData.EnTratamiento === "B" ) {
                            resolve(mensaje = `El transporte ${transporte} se encuentra bloqueado por otro proceso`);
                        } else if ( oData.EnTratamiento === "E" ) {
                            resolve(mensaje = `Error al bloquear objeto`);
                        }
                    },
                    error: function(oError) {
                        sap.ui.core.BusyIndicator.hide();
                        try {
                            var json = JSON.parse(oError.responseText);
                            resolve(mensaje = `Code: ${json.error.code}. Descrip: ${json.error.message.value}`);
                        } catch(e){
                            MessageBox.error("Ha ocurrido un error al obtener los datos.");
                        }
                    }
                });
            }.bind(this));
}

is it ok the way that i'm doing this ?

ricardo7227
Participant
0 Kudos

I see the code well, that it stays frozen is very rare, the request is made without problem? I'm thinking that it may have fallen into a loop that blocks the main thread of the application.

View Entire Topic
boghyon
Product and Topic Expert
Product and Topic Expert

Promise is not the issue. The freezing behavior comes from the synchronous XHRs made by the deprecated "sap.ui.model.odata.ODataModel". In your case, there are two sync XHRs when "_checkTransporte" is called: one from the model instantiation (requesting $metadata), and another one from the "read"-method. During such calls, the UI-/main-thread of the browser is suspended until the response arrives.

There are options to send the requests asynchronously, but again, the model you're using is outdated and no longer maintained. Better migrate to the v2.ODataModel. It sends all requests asynchronously. Also declare the model in the app descriptor instead of instantiating and thus requesting $metadata every time "_checkTransporte" is called. The model will be then instantiated only once and set on the UIComponent automatically.

"sap.app": {
  "dataSources": {
    "myODataService": {
      "uri": "/sap/opu/odata/sap/ZCLMMVSR_ODATA_CALIDAD_CONT_SRV/",
      "type": "OData",
      "settings": {
        "odataVersion": "2.0"
      }
    }
  }
}
"sap.ui5": {
  "models": {
    "": {
      "dataSource": "myODataService",
      "settings": {
        "defaultBindingMode": "TwoWay",
        "preliminaryContext": true,
        "useBatch": true|false depending on your service
      },
      "preload": true
    }
  }
}

For more information, the following documentation topics might help:

Feel free to report issues on GitHub if some content is unclear or missing.

ricardo7227
Participant

I didn't know that Odatamodel's V1 didn't make asynchronous requests, I've always used V2 but I didn't know the features of the obsolete version. Good to know.

boghyon
Product and Topic Expert
Product and Topic Expert
0 Kudos

ricardo7227 Yes, the first ODataModel is pretty harmful to the UX due to sending requests via sync XHR by default. It should be replaced immediately if anyone is still using it. But even now, I still see too many new questions coming up with the old model. I wish the framework communicated better how bad the model actually is. Simply deprecating it is not enough.