[SOLVED] AJAX issues

JavaScript and client side scripting.

Moderator: General Moderators

Locked
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

[SOLVED] AJAX issues

Post by Chris Corbyn »

Code: Select all

Error: uncaught exception: [Exception... "Component returned failure code: 0xc1f30001 (NS_ERROR_NOT_INITIALIZED) [nsIXMLHttpRequest.send]"  nsresult: "0xc1f30001 (NS_ERROR_NOT_INITIALIZED)"  location: "JS frame :: http://iris/shane-dev2/index.php?___sys_op___=link&___link___=144 :: killIt :: line 183"  data: no]
I can't for the life of me see why this is breaking :( It an ajax call on one particular function that does just about the same as the other AJAX stuff that's causing grief.

Code: Select all

function relistBlurbs()
{	
	if (http.readyState == 4) {
		document.getElementById('blurb_listing').innerHTML = http.responseText;
	}
}

function killIt(el, el2)
{
	var theID = el2.id.replace(/^linkid_(.*)$/, "$1");
	http.open("GET", ('index.php?___stub_only&killit='+theID), true);
	http.onreadystatechange = relistBlurbs;
	http.send(false); //Line 183
	el.removeChild(el2);
}
The function relistBlurbs() never gets executed when killIt() is called. All vars inside killIt have been parsed correctly since I've tried alert()'ing them to check... http.open() and http.onreadystatechange are working fine too... if I comment out the send() line it doesn't error... WTF??? :(
Last edited by Chris Corbyn on Tue Feb 14, 2006 4:53 am, edited 1 time in total.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

OK now this is just frickin' weird :?

Code: Select all

function relistBlurbs()
{	
	if (http.readyState == 4) {
		document.getElementById('blurb_listing').innerHTML = http.responseText;
	}
}

function killIt(el, el2)
{
	var theID = el2.id.replace(/^linkid_(.*)$/, "$1");
	alert(theID);
	http.open("GET", ('index.php?___stub_only&killit='+theID), true);
	http.onreadystatechange = relistBlurbs;
	http.send(false);
	el.removeChild(el2);
}
Guess what? Yep, that actually works. Notice the difference? All I've done is added an alert! WTF?
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

you might try also checking to make sure the status it returns is 200...
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Burrito wrote:you might try also checking to make sure the status it returns is 200...
I'll give it a go thanks :) But the only thing is that it won't execute the call to send() so I wouldn't get that far. I've tried adding setTimeout() on both open() and send() to no avail too :(

EDIT | By the way this is the sort of context I'm using it in too....

Code: Select all

<div id="linkid_282" style="position: absolute;" class="foo">
    <div class="title_bar">
        <span style="float: right;" onclick="killIt(this.parentNode.parentNode.parentNode, this.parentNode.parentNode);">X</span>
        Some title here
        </div>
    </div>
    Some silly boxed in text here... this div should get deleted and it's ID number sent to the server
</div>
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

I'd try process if elimination...start commenting out lines and see which one kills it.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Burrito wrote:I'd try process if elimination...start commenting out lines and see which one kills it.
Yep... I tried that first :( The one and only line that kills it is the send(). It's really weird. The div layer that this works on (the one with id="linkid_XXX") is tied to walter zorn's drag/drop library too... maybe I'll start looking into whether that's causing issues. There's all kinds of AJAX being handle on tyhese layers though to track positions in the database as well as creating new layers etc.. The error from Firefox suggests it's the XMLHttpRequest object that's at fault. Kinda at a loss :(
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

I'm grasping at straws here, but maybe it's the set of parens you have in the second param of your open method....

I've never seen it done that way before, try removing them and see if that makes any differerence 8O
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Burrito wrote:I'm grasping at straws here, but maybe it's the set of parens you have in the second param of your open method....

I've never seen it done that way before, try removing them and see if that makes any differerence 8O
LOL :P I actually added those because I wondered if the issue was with concatenating the string for the URL :lol:

Hmm... It's just sporadically done it on another of my AJAX calls when I create a new layer so I'll re-post here when I look away from the current issue and more towards my XMLHttp object handling... seems like something's got itself a little bit confuddled more towards the root of the scripting. Geesh.. I dunno... bad software developers 8O ... oh hang on... did I write this? :P
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Reading this ( http://www.quirksmode.org/blog/archives ... s_a_1.html ) suggests it's because the XMLHttpRequest object is busy. I doubted this because this happens even on first page load. In any case I wrote an object to handle this better and ensure that the XMLHttpRequest object in use is a fresh copy.

Code: Select all

function XMLHttpObj()
{
	this.xmlHttpArray = new Array();

	this.newXmlHttp = function()
	{
		var XMLHttp;
		if (window.XMLHttpRequest) XMLHttp = new XMLHttpRequest();
		else if (window.ActiveXObject)
		{
			try {
				
				XMLHttp = new window.ActiveXObject("Microsoft.XMLHTTP");
				
			} catch(e) {
				
				XMLHttp = false;
			
			}
		}
		else XMLHttp = false;
		
		return XMLHttp;
	}

	this.addNewInstance = function()
	{
		this.xmlHttpArray.push(this.newXmlHttp());
	}

	this.getCurrentInstance = function()
	{
		return this.xmlHttpArray[this.xmlHttpArray.length-1];
	}

	//Construct
	this.addNewInstance();
	//End construct
}

var myXMLHttp = new XMLHttpObj();
Still no banana.

Then I decided to add an alert to check if it was indeed the readyState that's busy:

Code: Select all

function killIt(el, el2)
{
	var theID = el2.id.replace(/^linkid_(.*)$/, "$1");
	//alert(theID);
	myXMLHttp.getCurrentInstance().open("GET", ('index.php?___stub_only&killit='+theID), true);
	myXMLHttp.getCurrentInstance().onreadystatechange = relistBlurbs;
	alert(myXMLHttp.getCurrentInstance().readyState);
	myXMLHttp.getCurrentInstance().send(false);
	el.removeChild(el2);
	return true;
}
I get an alert that indicates readyState = 0. That's good... that means it's a new instance and waiting for orders :)

Yet, I still get the error:

Code: Select all

Error: uncaught exception: [Exception... "Component returned failure code: 0xc1f30001 (NS_ERROR_NOT_INITIALIZED) [nsIXMLHttpRequest.send]"  nsresult: "0xc1f30001 (NS_ERROR_NOT_INITIALIZED)"  location: "JS frame :: http://iris/shane-dev2/index.php?___sys_op___=link&___link___=144 :: killIt :: line 195"  data: no]
For info reagrding readyState to anyone JS happy but not used to AJAX.

0 = Idle, ready for anything
1 = Loading
2 = Sending/dealing with headers
3 = Downloading data
4 = Finished downloading, ready for next command

onreadystatechange is simply the event that happens when the readyState changes from 0 to 1 to 2 to 3 to 4 etc....

Hoping someone may have found a better article that offers other solutions than quirks mode does.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

W00t! I just solved my own problem :P

It was due to me using the walter zorn drag/drop library in combination with the pluggable my_dropFunc(). I was sending AJAX requests on dropping items but didn't realise that it still counts it as a srop even if you didn't drag the layer anywhere. So my onclick was being run immediately after an mousedown event and thus, the instances of the XMLHttpRequest object were being flooded too quickly. I've simply changed the code in my_dropFunc() to check if the layer was actually dragged before sending an AJAX reuqest off :)
savaticus
Forum Newbie
Posts: 1
Joined: Tue Oct 24, 2006 9:34 am

Post by savaticus »

It is allways a good idea to check the state of the connector before sending anything to it, and if it's busy set a timeout to retry in x. This willkeep your problem from happening, because you should be aware that a user IS going to get that error message with the current code. Here is what I do, I have a generic requestor function and a generic handler function.

Code: Select all

function initreq( args ){
 if ( xhReq.readyState == 0 || xhReq.readyState == 4 ){
    //initiate XmlHTTPRequest
    xhReq.open("GET", "page.php?" + args, true);
    xhReq.onreadystatechange = aSRhandle;
    xhReq.send(null);
  }else{
    setTimeout('initreq( ' + args + ' )', 1000);
  }
}
Then the handler also checks the ready state as well as the completion status.

Code: Select all

function aSRhandle(){
//handles all server responses.
  if ( xhReq.readyState == 4 ){
    if ( xhReq.status == 200 ){
      try{
        xmlR = xhReq.responseXML;
       try{
          /*firefox speicific fix because it breaks xml text nodes into 4096 character chunks*/
          xmlR.normalize();
       }catch(e){}
       xmlDE = xmlR.documentElement;
       //specific code
       }
  }else{
    setTimeout("aSRhandle()", 1000);
  }
}
I put all of my callback data such as what funcion to return the data to in my XML structure. I only use XML as packager, because I am working with large data sets. So what I often do is package JSON into xml elements, this way my server response handler only needs to know about a few things to get the data to the right place. It is not hard to wrap your code in these kinds of checks and will save you a lot of pain.
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

holy thread from the dead batman..

locked.
Locked