user1678488
user1678488

Reputation:

Getting global handler to all AJAX calls in dojo

I need to invoke some common methods before an AJAX call is made and after the AJAX call (before the actual handler method is called) is success. I'm using dojo.aspect to achieve this.

This is my code sample

function makeAjaxCall(){
    dojo.xhrGet({
        url:"sample_url",
        content:{
            test:"value"
        },
        load:function(response){
            //Do some logic here
        },
        error:function(response){
            //handle error
        }
    });

}

Below is the dojo.aspect which I'm using to get a hook to the XHR calls.

define(["dojo/aspect"], function(aspect){
     aspect.after(dojo, "xhr", function(deferred){
        console.log("AJAX AFTER");
        deferred.then(function(response){
            //CALLED AFTER 'load' METHOD IS CALLED.
            console.log("Testing");
        });
     });
    aspect.before(dojo, "xhr", function(method, args){

        console.log("AJAX BEFORE");
    });
});

Now the problem is deferred.then inside aspect.after is called after the "load" function is called. Is it possible to have a method which is called before the actual load method is invoked?

Upvotes: 2

Views: 2372

Answers (3)

keemor
keemor

Reputation: 1279

In Dojo 1.10 there is new API to globally catch state of requests.

notify("error", function(error){
    console.error(error);
    //SyntaxError: Unexpected token < in JSON at position 0(…)
});

But in my case I get errors in html eg. so in error I get "error SyntaxError: Unexpected token < in JSON at position 0(…)"

In previous version there was an access to response object:

topic.subscribe("/dojo/io/error", function(/*dojo.Deferred*/ dfd, /*Object*/ response){   
  if (response.status === 401) {
    window.location.reload();
  }

});

So I figured out that json handler can be customized:

require(["dojo/request/handlers"], function(handlers){

handlers.register("json", function(response){

    if (response.status === 401) {
        window.location.reload();
        return;
    }

    return JSON.parse(response.text || null);
});

});

This way you are able to detect response.errors before JSON.parse throws exception.

Upvotes: 0

denov
denov

Reputation: 12698

If you switch to the new API - dojo/request

Then you could use dojo/request/xhr and dojo/request/notify

Upvotes: 0

Craig Swing
Craig Swing

Reputation: 8162

The short answer is yes.

First, there are two ways to make ajax calls in Dojo.

  1. dojo/xhr - this is what you have above and this is deprecated in favor of
  2. dojo/request/xhr

The first implementation will call into the second implementation. So I would recommend using aop on dojo/request/xhr.

aspect.around(require.modules['dojo/request/xhr'], 'result', function(originalXhr){
    return function(url, options, returnDeferred){

        var dfd = new Deferred();

        // Logic before making the xhr call

        originalXhr(url, options, returnDeferred)
            .then(function(response) {

                // Logic handling the response but before resolving the deferred.
                dfd.resolve(vm);
                // Logic after resolving the deferred.

            }, function(err){
                // error handling?
                dfd.reject(msgs);

            }, function(update) {
                dfd.progress(update);
        });

        return dfd;
    };
}); 

You can find the complete implementation at https://github.com/cswing/evinceframework/blob/master/evf-web-js/src/dojo/evf/serviceRegistry.js (~ line 111)

USAGE:

require('dojo/xhr/request', function(xhr){
    xhr({...}).then(
        function(response) {
            //handle response
        },
        function(error) {
            //handle error
        }
    );
});

The dojo/xhr code will translate itself to the usage above, so the code you posted should work.

Upvotes: 2

Related Questions