Nicaps Nicaps - 5 months ago 164
Javascript Question

JS & SAPUI 5 : wait for 2 asynchronous functions WITHOUT setTimeout

Here is the code I use in SAPUI5 to get data from an odata service :

var sServiceUrl = "http://localhost:8080/PlanningV0_2/proxy/sap/opu/odata/sap/ZPM_OM_WORKMANAGER_SRV";
var oOdataModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);
var oView = this.getView();
var oEmployeeModel = new JSONModel();
var oOperationModel = new JSONModel();
var aEmployees = [];
var aOperations = [];

//set odata models
var readEmp = oOdataModel.read("/EmployeeSet",{
success : function(oData,response){
oEmployeeModel.setData(oData);
oView.setModel(oEmployeeModel,"EmployeeModel");
aEmployees = oEmployeeModel.getData().results;
},
error : function(oError){
console.log(oError);
}
});

var aFilters = [new Filter("PersNo",FilterOperator.NE,"00000000")];
var readOp = oOdataModel.read("/OrderOperationSet",{
filters : aFilters,
success : function(oData,response){
oOperationModel.setData(oData);
oView.setModel(oOperationModel,"OperationModel");
aOperations = oOperationModel.getData().results;
},
error : function(oError){
console.log(oError);
}
});


After those read functions I want to reuse the arrays aEmployees and aOperations to build a custom model and bind it to my view. The problem is : these functions are asynchrone. If I put a
console.log(aEmployees)
right after the last line, it displays an empty array.

How can I wait for the end of the two async functions to use the arrays ?

I looked for something like sleep() or wait() to wait for the end of async functions, but it seems it doesn't exist for JavaScript.

EDIT : PRECISION I ask because I prefer to avoid setTimeout, because I don't want to put the treatment code into a callback, I find it awfuly readable, I want to access to 'this' easily if needed, and I don't want to use a hardcoded waiting time.

EDIT : ANSWER I used the
attachBatchRequestCompleted
, according to @Qualiture advises, to build the arrays :

oOdataModel.attachBatchRequestCompleted(function(){
var aEmp = oView.getModel("EmployeeModel").getData().results;
var aOp = oView.getModel("OperationModel").getData().results;
});


It doesn't matter how many requests are bound to the odata model, this event handler will catch them all in the end. Obviously, it is a callback, but I figured out that it is impossible to deal without. The point is that I don't have to hardcode a waiting time.

Answer

Use the ODataModel's attachRequestCompleted event handler:

yourModel.attachRequestCompleted(function(oEvent){
    var oModel = oEvent.getSource();
    //etc
});

Do this for both models, and once both events are catched, you can do your magic building your custom model structure

Comments