I guess you access oEntry
or i
in the "Additional Processing".
The problem is that the inner success function with the additional processing is capturing the local variables defined outside like i
and oEntry
in a closure. The variables values are not copied.
- The for loop increments
i
, changes oEntry
and executes the oModel.create()
method.
- Next loop: The for loop increments
i
again, changes oEntry
and executes oModel.create()
again.
- When the loop is done or any time later after the request to the backend has completed, your inner success handlers will be called. They access the outer variables which have only survived that long because they were captured in the closure. And they will be in the state they were when the for loop has finished.
So if you don't mind that your additional processing might happen out of order you can move the code inside the for loop into a separate function. When you call that function from the for loop the variable values will be copied so that each before mentioned closure will capture the copies which will not be changed by the for loop:
createSurvey: function(oEntry){
var that = this;
oModel.create("/SurveySet", oEntry, {
success: function(oData) {
for (var i = 0; i < questionData.questions.length; i++) {
that.createQuestion(oModel, questionData.questions, i, oData);
}
}
}
}
createQuestion(oModel, questions, i, survey){
var oEntry = {};
oEntry.SurveyId = survey.SurveyId;
oModel.create("/QuestionSet", oEntry, {
changeSetId: i.toString(),
success: function(oData) {
//Additional Processing
}
}
}
PS: You can also use questionData.questions.forEach(function(question, i){ ... });
to get the same effect. This time the anonymous function copies the values.
If you need to maintain strict order for your additional processing and send the requests sequencially to the backend, i would indeed recommend the use of promises:
createSurvey: function(oEntry){
var that = this;
oModel.create("/SurveySet", oEntry, {
success: function(oData) {
var promise = Promise.resolve();
questionData.questions.forEach(function(question, i) { //copy local variables
//Chain the promises
promise = promise.then(function(){ return that.createQuestion(oModel, question, i, oData)});
});
promise.then(function(){
//All done
})
.catch(function(){
//Error somewhere. remaining not executed
})
}
}
}
createQuestion(oModel, question, i, survey){ //returns a Promise now
var oEntry = {};
oEntry.SurveyId = survey.SurveyId;
return new Promise(function(resolve,reject){ //Wrap the UI5 stuff into a Promise
oModel.create("/QuestionSet", oEntry, {
changeSetId: i.toString(),
success: function(oData) {
//Additional Processing
resolve(oData);
},
error: reject
}
});
}