mx.data.create requests randomly handled

0
Hi I am currently testing my custom widget in which I need to Create multiple objects and add references to a certain object.For eg. Create a 'Label' object Create multiple 'Options' objects and add reference to the above created label object as each object is created(in the callback) mx.data.create( { entity: this.SaveEntryEntity, callback: function(obj) { console.log("Label Object created on server with Guid:"+obj.getGuid()); Labelguid=obj.getGuid(); }, error: function(e) { console.log("an error occured: " + e); } }); for(var i=0;i<selectedoption.length;i++) { mx.data.create( { entity: "TestSuite.Option", callback: function(Optionobj) { console.log(" Label Object created with Guid:"+Optionobj.getGuid()); Optionobj.set("OptionName", selectedoption[i]); Optionobj.addReference("TestSuite.Option_Label",Labelguid ); }, error: function(e) { console.log("an error occured: " + e); } }); but I observed the create object requests are handled randomly, sometimes the Label object is not created before the Options and hence the add reference is failing. Is there a way to serialize the creation requests to follow a particular order?
asked
2 answers
5

There are a number of issues in the above code snippet, caused by the fact that creating objects is asynchronous, and the order in which objects are created is non deterministic:

  1. It assumes that the creation of the Label object is finished before the Option objects are created. But because of it being asynchronous, the creation of the Label object might not be finished yet when the first Option callback is reached, in which case LabelGuid will be undefined.

  2. In the Option callback, the loop counter i is used to set the OptionName. But the first callback will only be called after the loop is finished, which is why in the callback i will always have its final value. See also this example, where a timeout is used to mimic asynchronicity.

The first issue can be fixed by splitting the code in two and creating the Option objects only after the creation of the Label object is finished. The second issue can be fixed by using a forEach, which creates a new function scope for every item, instead of a normal for loop. See the following example.

function createLabelObject(callback) {
    mx.data.create({
        // ...
        callback: function(obj) {
            callback(obj);
        }
    });
}

function createOptionObjects(labelObj) {
    selectedOptions.forEach(function(option) {
        mx.data.create({
            // ...
            callback: function(obj) {
                obj.set("OptionName", option);
                obj.addReference("TestSuite.Option_Label", labelObj.getGuid());
            }
        });
    });
}

createLabelObject(function(labelObj) {
    createOptionObjects(labelObj);
});
answered
1

You could do the creation of your option entity objects in the callback in which you created the label entity object.

Since the mx.data.create function is async you never know when it is finished making them sequential means using the call back functions to set the correct order.

answered