0

I want to basically create a new function signature for ajax done and fail handlers...given the simplified example below, I'm just trying to append resource as the last parameter to be sent to the handler.

    const customAjax = function( url, resource ) {
        const p = $.ajax({
            converters: {
                'text script': function (text: string) {
                    return text;
                }
            },
            url: url + "?" + resource
        }).then(
            function () {
                [].push.apply(arguments, [resource]);
                return arguments;
            },
            function() {
                [].push.apply(arguments, [resource]);
                return arguments;
            }
        );

        return p;
    };

Then the preferred usage is something like:

customAjax( "url", "resourceKey" )
   .done( function( data, textStatus, jqXHR, resourceName ) { /* do something */ } )
   .fail( function( jqXHR, textStatus, errorThrown, resourceName ) { /* do something */ } );

The problem is, in both handlers, there is only one parameter. The javascript arguments object. So, to access each parameter I really want, I have to do something like this instead:

customAjax( "url", "resourceKey" )
   .done( function( args ) { 
      var data = args[ 0 ];
      var textStatus = args[ 1 ];
      var jqXHR = args[ 2 ];
      var resourceName = args[ 3 ];
      /* do something */
   } )
   .fail( function( args ) { 
      var jqXHR = args[ 0 ];
      var textStatus = args[ 1 ];
      var errorThrown = args[ 2 ];
      var resourceName = args[ 3 ];
      /* do something */ 
} );

Is there any way to make it work the way I'd prefer?

Update - Not sure how to communicate with person that closed my question, but I don't see how the referenced 'duplicate' question answers/addresses my issue.

Terry
  • 2,148
  • 2
  • 32
  • 53
  • You'd have to overwrite the `fail` and `done` properties of the returned object. I would not go that way. Stick to the Promise interface, which has native support in JavaScript; that has more future than the specific jQuery interface. – trincot Feb 13 '21 at 16:55

1 Answers1

0

You would need to overwrite the fail and done method properties of the object that $.ajax returns, so to make sure that the callback that is eventually passed to these two methods is then called with the extra argument:

const customAjax = function( url, resource ) {
    const p = $.ajax({
        converters: {
            'text script': function (text: string) {
                return text;
            }
        },
        url: url + "?" + resource
    });
    let result = {
        ...p,
        done(f) {
            p.done(function (...args) {
                f.call(this, ...args, resource);
            });
            return result;
        },
        fail(f) {
            p.fail(function (...args) {
                f.call(this, ...args, resource);
            });
            return result;
        }
    };
    return result;
};

Demo:

const customAjax = function( url, resource ) {
    const p = $.ajax({
        converters: {
            'text script': function (text) {
                return text;
            }
        },
        url: url + "?" + resource
    });
    let result = {
        ...p,
        done(f) {
            p.done(function (...args) {
                f.call(this, ...args, resource);
            });
            return result;
        },
        fail(f) {
            p.fail(function (...args) {
                f.call(this, ...args, resource);
            });
            return result;
        }
    };
    return result;
};


customAjax( "https://jsonplaceholder.typicode.com/todos/1", "resourceKey" )
    .done( function( data, textStatus, jqXHR, resourceName ) { 
        console.log( {data, textStatus, jqXHR, resourceName});
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
trincot
  • 317,000
  • 35
  • 244
  • 286
  • Hmm...I never enter the `done(f)` or `fail(f)` handlers with this code. – Terry Feb 14 '21 at 01:46
  • You must be doing something wrong then. I added a demo to my answer. When I run it, the `done` method is run with the extra argument. – trincot Feb 14 '21 at 07:50
  • It was tricky to get it to work in TS (just didn't know all the argument types at first). JS can still be mind bending to me, lol. – Terry Feb 14 '21 at 19:08
  • Another tricky one for you if you are up for it ;) https://stackoverflow.com/q/66212471/166231 – Terry Feb 15 '21 at 17:44
  • If I wanted to only use the `then()` instead of the obsolete `done` and `fail`, how would that be done? – Terry Mar 04 '21 at 18:07
  • If you have a new question, and you cannot make it work, then please post it as a new question. – trincot Mar 04 '21 at 18:11
  • https://stackoverflow.com/questions/66481036/custom-ajax-then-signature – Terry Mar 04 '21 at 18:35