0

I have the following:

if(typeof searchDOM === "undefined"){
    dojo.xhrPut({
        url: addrPath + "/ContServlet?mod=1&act=23",
        handleAs: "xml",
        timeout: xhrTimeout(TIMEOUT_LRG),
        load: function(dom, ioArgs){
            if(dom instanceof Error){
                console.error(dom);
            } else{
                cacheDOM = dom;
            }
        },
         error: function(response, ioArgs){
             xhrError(ioArgs, methodName);
         }
    });    
}

The variable cacheDOM is a global variable declared(but not initialised) elsewhere in another script. It is an xml document containing the entire dom, and it is passed into:

the problem is, cacheDOM is undefined when it gets to fetchXml, and this is causing problems for methods like selectNode further down the function.

I haven't had much exposure to xhr calls, or things such as deferreds or promises, but I think that they may be able to help with this. How do i code this so that the rest of the method that this block is in will only execute if cacheDOM has been assigned the value of dom? Or if deferreds are the answer, how would i incorporate them into this code? The version of dojo i am using is 1.7.8

jbailie1991
  • 1,305
  • 2
  • 21
  • 42

1 Answers1

1

Well, the problem is indeed that you're using an XHR request which is asynchronous. So, the fetchXml function has to wait until that request is completed.

There are several ways to do this, you could call the fetchXml function from within the load function of dojo.xhrPut, but this is not really a good solution when your project grows because it creates a lot of dependencies on each other.

So, some smart people created an API for resolving asynchronous requests, called promises/deferreds.

So, what you have to do is assigning a new deferred to cacheDOM, for example:

require(["dojo/_base/Deferred"], function(Deferred) {
    cacheDOM = new Defered();
});

Then, in the fetchXml() code you have to change your code a bit to do this:

function fetchXml() {
    cacheDOM.then(function(realCache) {
       console.log(realCache); 
    });
}

So in stead of directly using cacheDOM you have to wait for it using cacheDOM.then(). It will fire a callback when it's resolved, and the data will be available in realCache.

An alternative would be to call the entire fetchXml function when the XHR request has fired:

cacheDOM.then(fetchXml);

function fetchXml(cacheDOM) {
    // Work with cacheDOM
}

This might take less work and less alteration to the fetchXml function depending on how much it relies on cacheDOM.

Then finally, inside your dojo.xhrPut you will have to do the following:

cacheDOM.resolve("My data");

Where "My data" would be the actual data which you would put inside cacheDOM.

DEMO: http://jsfiddle.net/rf20s9hb/1/

g00glen00b
  • 41,995
  • 13
  • 95
  • 133