Giehl Man
Giehl Man

Reputation: 430

dojo/Deferred chaining mechanism not respecting async call

I'm quite new to dojo, but I have a certain error dealing with the Deferred API I can't help

my invoking code is

function openEditor(id, fieldName) {
    editOptionsDialog_fetchData(id, fieldName).then(function(data){
    console.log("done!");
    });
    console.log("leaving openEditor!");
}

which calls this function

function editOptionsDialog_fetchData(id, fieldName) {
    require(["dojo/ready", "dojo/data/ObjectStore", "dojo/Deferred"], function(ready,     ObjectStore, Deferred) {
        var store;
        var def;

        switch (fieldName) {
            case "degree":
                store = new degreeStore();
                def = store.getJsonData();
                break;
            case "faculty":
                store = new facultyStore();
                def = store.getJsonData();
                break;
            default:
                console.log("error in editOptionsDialog_fetchData: " + fieldName);
        }

        return def.then(function(data){
            store.data = data.items;
            editOptionsDialog_select.setStore(new ObjectStore({ objectStore : store }));
            editOptionsDialog_select.store.query({ "id" : id });
            editOptionsDialog_select.startup();
        });
    });
}

where store.getJsonData() creates a Deferred, which I want to use for chaining the Deferred resolving (see additional code after the main text).

The error I receive is

editOptionsDialog_fetchData(id, fieldName).then(function(data)...) is undefined

Since the error message appears right after accessing the openEditor function, it is clear, that the value of the function call has to be undefined, since the callback is not yet done.

My question is, where this misunderstanding of the Deferred API must be within my code, since the purpose is to evaluate the function call of editOptionsDialog AS SOON AS the async call is done and called backed, AND NOT BEFORE this call has finished (in the state where the function call still leads to undefined, but I thought this is the purpose of the then-return).

Thx for your help

--- additional code for getJsonData() ---

getJsonData: function() {
        return xhr(this.handlerUrl, {
            handleAs: "json",
            method: "POST",
            data: {
                action: "getJsonData"
            }
        }).then(function(data){
            return data;
        }, function(err){
            alert("Data cannot be fetched in degreeStore.getJsonData! " + err);
        });
    }

Upvotes: 1

Views: 630

Answers (2)

Giehl Man
Giehl Man

Reputation: 430

Resolved the problem by restructuring the code. In principle, the Deferred-object seems not to be able to be returned to a distinct require-clause. Therefore, this worked for me:

var editMultilanguageDialog_Startup;
// one require-clause, wrapping all the Deferred-sensitive statements
require(["dojo/request/xhr", "dojo/json", "dojo/Deferred", "dojo/store/Memory", "dojox/timing", "dojo/domReady!"], function(xhr, json, Deferred, Memory, timing, domReady) {

   function editMultilanguageDialog_Startup(id, fieldName) {
    // code from former mainForm -> moved into this require-clause
    //[...]
    // here, the invocation is no longer undefined and waits for the resolve        
    editMultilanguageDialog_fetchData(id, fieldName).then(function(data){
            //[...]
            editMultilanguageDialog.show(); 
        });    
    }

    function editMultilanguageDialog_fetchData(id, fieldName) {
        // unchanged, returns Deferred
    }

}); 

This is a workaround, I don't know if this feature is on purpose by dojo.

Upvotes: 0

Craig Swing
Craig Swing

Reputation: 8162

I created a fiddle to demonstrate what you are trying to do.

Basically I am returning the Deferred to the editOptionsDialog_fetchData method from getJsonData. editOptionsDialog_fetchData creates another Deferred that it returns to openEditor. In editOptionsDialog_fetchData, I connect the resolving of the first Deferred to the resolve the second Deferred.

http://jsfiddle.net/cswing/yUTT8/

Upvotes: 1

Related Questions