Question

I have a widget that I created that uses an $.ajax() call to get data from the server. I allow the users to refresh the data from the server when they want, so I need to be able to cancel the existing request so that there is not a collision with multiple datasets returning from the server. Only a single request should be executed at a time.


Widget Code
(function ($) {
    $.widget("w.widgetName", {

        options: { { /*set the widget options here*/ }},

        _create: function () { /*do the create stuff here */ },

        _cancelAjaxRequest: function(){//private method to cancel the current ajax request
            var xhr = this.ajaxGetCall;
            if (xhr && xhr.readyState != 4){
                xhr.abort();//line that throws the error, but in the jQuery code
            }
        },

        refresh: function () {
            var self = this;

            self._cancelAjaxRequest();

            self.ajaxGetCall = $.ajax({//I assign the $.ajax() xhr object here
                type: "POST",
                contentType: "Application/json; charset=utf-8",
                dataType: "json",
                url: "url/goes/here",
                data: dataGoesHere,
                success: function (data) { /*Do stuff here*/},
                error: function (xhr, status, error) { /*Do stuff here*/},
                complete: function (r, s) { /*Do stuff here*/}
            });

        },

        destroy: function () {
            var self = this;
            self._cancelAjaxRequest();
            //do other stuff to destroy the object
        }
    });
} (jQuery));

Using both jQuery 1.8.2 and 1.9.1, I get the following error when executing xhr.abort();.

 TypeError: Cannot read property 'length' of undefined

I put the full version of jQuery 1.8.2 and 1.9.1 and they both point to line 622.

each: function( obj, callback, args ) {
        var value,
            i = 0,
            length = obj.length,
            //remaining code removed for brevity
            }

I any help or insight to this problem that I am having is much appreciated!


Update: I have been doing a console.log(xhr) just to double check and make sure that I am getting an xhr object back. Here is a copy and paste from the Chrome console.

Object {readyState: 1, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…}
abort: function ( statusText ) {
always: function () {
complete: function () {
done: function () {
error: function () {
fail: function () {
getAllResponseHeaders: function () {
getResponseHeader: function ( key ) {
overrideMimeType: function ( type ) {
pipe: function ( /* fnDone, fnFail, fnProgress */ ) {
progress: function () {
promise: function ( obj ) {
readyState: 0
setRequestHeader: function ( name, value ) {
state: function () {
status: 0
statusCode: function ( map ) {
statusText: "abort"
success: function () {
then: function ( /* fnDone, fnFail, fnProgress */ ) {
__proto__: Object
Was it helpful?

Solution

Based on Kevin B's comments to my question, I used the stack trace in Chrome to get to the problem line of code.

Fortunately it has nothing to do with the code that I posted in my question. It is related to a function that I have written to handle errors from the server. Calling xhr.abort() forces the error method of $.ajax() to be called. I have a function assigned to the error method that was looking at the xhr.responseText and I failed to check to see if xhr.responseText was not null and not undefined.

I hope this helps someone else!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top