Question

Am using 3.1.3.GA Titanium SDK, Alloys and 2.3.3 Android Emulator. I am trying to post an Ajax using Ti.Network.createHTTPClient() and at some point I need to abort it, Now I am trying this code and its not getting work or ajax request not getting abort. My code,

index.xml

<Alloy>
    <Window backgroundColor="white">
        <Label onClick="sendAjax">Send</Label>
        <Label onClick="cancelAjax">Cancel</Label>
    </Window>
</Alloy>

index.js

function sendAjax(){
var xhr = Ti.Network.createHTTPClient();
        xhr.onerror = function(e){
            var error = e.error;
            alert(error);               
        };
        xhr.open('GET', url);
        xhr.send(params);
        xhr.onload= function(e){
            if (this.readyState == 4) {
                  alert('success');
            }
            else if (cancelSend) {
                  xhr.abort();
            }
        };
        xhr.ondatastream = function(e){
            if(ajaxCancel){
                xhr.abort();
            }   
        };
}

function cancelAjax(){
    ajaxCancel = true;  
}

Is it possible to abort an ajax request, else have to change code at anywhere. Anyone got success in aborting ajax request using appcelerator?

Was it helpful?

Solution

until now there is no solution for: abort ajax request using HttpClient object.

I have been trying code to find out a solution but I gave up. Is not a big problem to detect when you have aborted a request and stop sending following requests in code, but the HttpClient object won't stop performing the requests that are already being sent.

If you can wait until next releases:

Someone has filled in an issue regarding this problem TIMOB-15612 and is already solved, maybe solves yours too.

If you can't:

After some googling I saw this post where they point out that the solution comes by using TCP sockets, and they suggest looking some code here

If what you want is to detect when you have aborted a request and stop sending following requests:

According to HTTPClient sdk 3.x documentation the onload property:

Must be set before calling open.

And the same happens with ondatastream and onreadystatechange properties.

Your index.js code should be reorganized and I'd suggest you something like this:

Ti.Network.HTTPClient.UNSENT = 0;
Ti.Network.HTTPClient.OPENED = 1;
Ti.Network.HTTPClient.HEADERS_RECEIVED = 2;
Ti.Network.HTTPClient.LOADING = 3;
Ti.Network.HTTPClient.DONE = 4;

var ajaxCancel = false;
var xhr = createHTTPClient();
var url = "";    //MUST BE SET BEFORE USE
var params = ""; //MUST BE SET BEFORE USE
function createHTTPClient(){
    var xhr = Ti.Network.createHTTPClient();
    xhr.onerror = function(e){
        Ti.API.info("-----------------------");
        var error = e.error;
        Ti.API.info("onerror:" + error);               
    };
    xhr.onreadystatechange= function(e){
        Ti.API.info("-----------------------");
        Ti.API.info("[onreadystatechange]readyState:" + xhr.readyState);
    };
    xhr.onload= function(e){
        Ti.API.info("-----------------------");
        Ti.API.info("[onload]");
        if (!ajaxCancel && this.readyState === Ti.Network.HTTPClient.DONE) {
            Ti.API.info("[onload]success:");// + JSON.stringify(e));
        }else{
            Ti.API.info("[onload]readyState:" + xhr.readyState);
            if(ajaxCancel){
                Ti.API.info("[onload]abortCall:");// + JSON.stringify(e));
            }else{
                Ti.API.info("[onload]:");// + JSON.stringify(e));
            }
        }
    };
    xhr.ondatastream = function(e){
        Ti.API.info("-----------------------");
        if(ajaxCancel){
            Ti.API.info("[ondatastream]abortCall:");// + JSON.stringify(e));
        }else{
            Ti.API.info("[ondatastream]:");// + JSON.stringify(e));
        } 
    };
    return xhr;
}
function sendAjax(){
    if(ajaxCancel)
        return;
    Ti.API.info("----------CALL---------");
    //xhr.open('GET', url);
    xhr.open('POST', url);
    Ti.API.info("Ti.Network.HTTPClient.UNSENT:" + Ti.Network.HTTPClient.UNSENT);
    Ti.API.info("Ti.Network.HTTPClient.OPENED:" + Ti.Network.HTTPClient.OPENED);
    Ti.API.info("Ti.Network.HTTPClient.HEADERS_RECEIVED:" + Ti.Network.HTTPClient.HEADERS_RECEIVED);
    Ti.API.info("Ti.Network.HTTPClient.LOADING:" + Ti.Network.HTTPClient.LOADING);
    Ti.API.info("Ti.Network.HTTPClient.DONE:" + Ti.Network.HTTPClient.DONE);
    Ti.API.info("[sendAjax]before request");
    xhr.send(params); //params not needed for a GET operation
    Ti.API.info("[sendAjax]request send");
}

function cancelAjax(){
    if(!xhr || ajaxCancel)
        return;
    Ti.API.info("-----------------------");
    Ti.API.info("[cancelAjax]abort petition");
    xhr.abort();
    Ti.API.info("[cancelAjax]abort call executed");
    ajaxCancel = true;
    if(xhr.readyState === Ti.Network.HTTPClient.UNSENT ||
       xhr.readyState === Ti.Network.HTTPClient.DONE){
        //maybe it wasn't already sent or the cycle is completed
        Ti.API.info("[cancelAjax]request not send or already done: " + xhr.readyState);
    }else{
        Ti.API.info("[cancelAjax]xhr.readyState:" + xhr.readyState);
    }

}
function allowAjaxCalls(){
    ajaxCancel = false;
}

In your index.xml add another label/button to control if you want to allow sending request after having canceled them:

<Alloy>
    <Window backgroundColor="white">
        <Button onClick="sendAjax">Send</Button>
        <Button onClick="cancelAjax">Cancel</Button>
        <Button onClick="allowAjaxCalls">AllowSend</Button>
    </Window>
</Alloy>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top