Search code examples
javascriptdojoaspect

Dojo aspect before not working on dojo request


I have a Dojo class that uses dojo/request to submit various requests to the server.

I need to use dojo/aspect to add a before advice to those requests.

The docs seem relatively easy to understand.

My class declaration looks something like this:

'myPackage/MyClass':function(){
    define("myPackage/MyClass", [
        "dojo/request", 
        // etc. etc. 
        "dojo/aspect"
    ], function(request, ..., aspect) {
        return declare("myPackage.MyClass", null, {
            constructor: function(options){
                aspect.before(dojo, "request", 
                    function(url, args){
                        // TODO
                        alert("before advice applied"); 
                    }
                );
            },
            // various functions that use dojo request
        });
    }

);
}

My problem is that the before advice is never executed.

I've tried a few variants, such as targeting this instead of dojo, or targeting request directly and its only visible function when inspected, xhr.

I even went back to the doc page in desperation and tried targeting dojo with method "xhr" to see if it couldn't by chance be invoked internally, but nothing ever worked.

Is there maybe something obvious that I've overlooked?

Edit

I tried modifying my code so that the before advice was executed targeting this and a frequently used function.

Something like: aspect.before(this, "theFrequentlyUsedFunction",

That worked just fine right out of the box, which means I can use a cumbersome workaround and add a before advice for each of the functions invoking request, assuming the time complexity of statements preceding the request call in those functions is trivial.

My conclusion so far is that I'm not referencing the right target and function name when applying advice before Dojo request calls, but I'm still baffled as per why this doesn't work.


Solution

  • In your case "request" is not a property of "dojo" object. It's just a name of argument passed in function. So you can assign it to any property of any object, even to property of your module. So you was close to solution. Take a look on my example:

    define([
        "dojo/_base/declare",
        .....
        "dojo/request",
        "dojo/aspect"
    ], function (
        declare,
        .....
        request,
        aspect
    ) {
    
        return declare("Test", [...], {            
            request: request,  
            constructor: function () {
                aspect.before(this, "request", function () {
                    console.log("before advice applied");
                });
            }
            ......
        });
    });