Reputation: 199
I have an issue in displaying BusyIndicator for post call in for loop. Before posting this question i have explored all possible ways and didnt find any solution. Hence im posting here. Please apologize if this is silly question..
For one of the requirement, i have to call ODataModel POST call for 10 times in a for loop.
Here im able to get the results perfectly without any issue. But the problem is to fire all 10 services, it is taking nearly 20 seconds to finish execution of all services.
So i want to display BusyDialog
before executing services. Below is my code..
var payload = {
"sectionIndex": 3,
"ratingType": "overall",
"userId": "",
"rating": "76",
"ratingKey": "wf_sect_3_rating"
};
//var busy = new sap.m.BusyDialog();
//busy.open();
for (var i = 0; i < 10; i++) {
//var busy = new sap.m.BusyDialog();
//busy.open();
var that = this;
oModel.create("/URL", payload, {
success: function (oData, oResponse) {
if (oData.results[0].status === "OK") {
that.getView().getModel("employeesModel").refresh(true);
} else {
MessageBox.error("Error : " + oData.results[0].message);
}
},
error: function (e) {
MessageBox.error("Error : " + e);
}
});
busy.close();
}
I also tried with sap.ui.core.BusyIndicator.show()
, hide()
, creating separate BusyDialog.fragment
and calling explicitly in controller. But none of the ways worked.
But when i try to debug, then im not getting any issue. BusyIndicator is loading perfectly if im keeping breakpoint.
Can someone help me to load BusyDialog
at the before calling POST call and close BusyDialog
once the execution of services finished.
Upvotes: 0
Views: 2791
Reputation: 3765
Please use batch requests instead of single requests in loops.
var sError;
var aErrorMessages = [];
var payload = {
"sectionIndex": 3,
"ratingType": "overall",
"userId": "",
"rating": "76",
"ratingKey": "wf_sect_3_rating"
};
var busy = new sap.m.BusyDialog();
busy.open();
oModel.setUseBatch(true);
oModel.setDeferredGroups(["myBatchRequest"]);
for (var i = 0; i < 10; i++) { //Loop
oModel.create("/URL", payload, { //Create request without sending
groupId: "myBatchRequest",
changeSetId: "myChangeSet",
single: false,
success: function(oData, oResponse) { //Catch error for each request
if (oData.results[0].status !== "OK") {
aErrorMessages.push("Error : " + oData.results[0].message); //store error message for each request
}
}.bind(this),
error: function(e) {
aErrorMessages.push(e);
}
});
}
oModel.submitChanges({ //Send all requests at once
groupId: "myBatchRequest",
success: function(oResponse) {
if (aErrorMessages.length > 0) { //Are there any errors...
for (var i = 0; i < aErrorMessages.length; i++) {
sError += aErrorMessages[i]; //...put it in string
}
MessageBox.error(sError); //Show all errors
busy.close(); //Close Busy Dialog
} else {
this.getView().getModel("employeesModel").refresh(true);
}
}.bind(this),
error: function(oError) {
MessageBox.error(oError);
busy.close(); //Close Busy Dialog
}
});
Upvotes: 1
Reputation: 345
For this scenario I would recommend using Promises
var payload = {
sectionIndex: 3,
ratingType: "overall",
userId: "",
rating: "76",
ratingKey: "wf_sect_3_rating"
};
//var busy = new sap.m.BusyDialog();
//busy.open();
var aPromises = [];
// Open your busy dialog
for (var i = 0; i < 10; i++) {
//var busy = new sap.m.BusyDialog();
//busy.open();
var that = this;
var pCall = new Promise(function(resolve, reject) {
oModel.create("/URL", payload, {
success: function(oData, oResponse) {
resolve();
if (oData.results[0].status === "OK") {
that
.getView()
.getModel("employeesModel")
.refresh(true);
} else {
MessageBox.error("Error : " + oData.results[0].message);
}
},
error: function(e) {
reject();
MessageBox.error("Error : " + e);
}
});
aPromises.push(pCall);
}).bind(this);
Promise.all(aPromises).then(function() {
// Happy case
// Close your busy dialog
}, function() {
// At least one of the promises went wrong
});
//busy.close();
}
Note that once one of the Promises is rejected, it will go into the second function of Promise.all()
, so maybe just use resolve()
Upvotes: 3
Reputation: 582
You can solves it by using oData model method attachRequestCompleted
. An easy way would be.
if(i == 10) {
oModel.attachRequestCompleted(function(oEvent) {
busy.close();
});
}
Of course that's not a perfect solution because it could be, that the 9th request is later finished than your 10th etc.
Normally you need to check every request and if every request is completed successfully, the busy dialog get closed. if one or more of them got an error, you can close if all 10 requests are completed you can close the busy dialog and you show an error message or sth.
so normally on every attachRequestCompleted
you need to check your loop counter if it's size is 10 and if yes, you can close the dialog.
Upvotes: 0