PDA

View Full Version : Ext.Ajax.request issue



KJD
3 Dec 2009, 9:13 AM
I am new to Ext and I am having trouble using the Ext.Ajax.request function with a CGI script. I have this all working in HTML and JS but cannot get it to work in Ext. I have a button on my page that when I click it should send a command to the server to toggle and LED. I thought this code would show me what is being returned from the server. I am not sure how to tie this into the CGI file either. Any help would be greatly appreciated.

This is my code that executes when the button is activated -




Ext.Ajax.request({
url:'leds.cgi',
method:'GET',
success:function(result, request){
Ext.MessageBox.alert('Success','Data returned: '+ result.responseText);
},
failure:function(result, request){
Ext.MessageBox.alert('Failed','Data returned: '+ result.responseText);
}
// newAJAXcommand('leds.cgi?led=1') // was my simple AJAX + CGI that worked
});

tryanDLS
3 Dec 2009, 9:29 AM
What do see in firebug? Does the request get sent? What is the data string returned?

KJD
3 Dec 2009, 9:40 AM
Hi Tim -
I am getting an error in Firebug although I don't understand what it means.
It says -



this.getConnectionObject is not a function
anonymous("POST", "leds.cgi", Object scope=Object argument=Object timeout=30000, Object name=postData, Object async=true headers=Object url=leds.cgi method=POST)code-display.js (line 332)
anonymous("POST", "leds.cgi", Object scope=Object argument=Object timeout=30000, Object name=data, Object async=true headers=Object url=leds.cgi method=POST)code-display.js (line 280)
anonymous()ext-all.js (line 7)
anonymous()aladdin-...m-grid.js (line 295)
anonymous(Object browserEvent=Event blur button=-1 type=blur)ext-all.js (line 7)
y()ext-all.js (line 7)


chrome://firebug/content/blank.gif var o = this.getConnectionObject();\r\n

CrazyEnigma
3 Dec 2009, 9:18 PM
What is:


this.getConnectionObject();


Where are you referencing this? Is it your code? The scope is probably referencing window instead of your object.

KJD
4 Dec 2009, 6:50 AM
I am not referencing this function in my code. It looked like it was being called from connection.js so I then included this file in my project as well. It is still not working though. I am certain this is something really simple but I do not know enough about CGI or JS to figure it out.

Animal
4 Dec 2009, 7:47 AM
So when you break at that line, what's happening? What is "this", what's the call stack look like? How did it get there etc?

Basically, debug.

KJD
4 Dec 2009, 8:56 AM
Hi Animal -
Not really sure what you are asking me. I don't know my way around Firebug much more than Ext and CGI.
I am getting an error that says -



this.getConnectionObject is not a function

It references the code-display.js file line 332.

This functionality works with simple HTML file like this :



<input type="button" id="btn_one" onClick="toggle_one(); newAJAXCommand('leds.cgi?led=1');" value="Off">


The newAJAXcommand is in a JS file as well -



/**
* Determines when a request is considered "timed out"
*/
var timeOutMS = 5000; //ms

/**
* Stores a queue of AJAX events to process
*/
var ajaxList = new Array();
/**
* Initiates a new AJAX command
*
* @param the url to access
* @param the document ID to fill, or a function to call with response XML (optional)
* @param true to repeat this call indefinitely (optional)
* @param a URL encoded string to be submitted as POST data (optional)
*/
function newAJAXCommand(url, container, repeat, data)
{
// Set up our object
var newAjax = new Object();
var theTimer = new Date();
newAjax.url = url;
newAjax.container = container;
newAjax.repeat = repeat;
newAjax.ajaxReq = null;

// Create and send the request
if(window.XMLHttpRequest) {
newAjax.ajaxReq = new XMLHttpRequest();
newAjax.ajaxReq.open((data==null)?"GET":"POST", newAjax.url, true);
newAjax.ajaxReq.send(data);
// If we're using IE6 style (maybe 5.5 compatible too)
} else if(window.ActiveXObject) {
newAjax.ajaxReq = new ActiveXObject("Microsoft.XMLHTTP");
if(newAjax.ajaxReq) {
newAjax.ajaxReq.open((data==null)?"GET":"POST", newAjax.url, true);
newAjax.ajaxReq.send(data);
}
}

newAjax.lastCalled = theTimer.getTime();

// Store in our array
ajaxList.push(newAjax);
}
/**
* Loops over all pending AJAX events to determine
* if any action is required
*/
function pollAJAX() {

var curAjax = new Object();
var theTimer = new Date();
var elapsed;

// Read off the ajaxList objects one by one
for(i = ajaxList.length; i > 0; i--)
{
curAjax = ajaxList.shift();
if(!curAjax)
continue;
elapsed = theTimer.getTime() - curAjax.lastCalled;

// If we suceeded
if(curAjax.ajaxReq.readyState == 4 && curAjax.ajaxReq.status == 200) {
// If it has a container, write the result
if(typeof(curAjax.container) == 'function'){
curAjax.container(curAjax.ajaxReq.responseXML.documentElement);
} else if(typeof(curAjax.container) == 'string') {
document.getElementById(curAjax.container).innerHTML = curAjax.ajaxReq.responseText;
} // (otherwise do nothing for null values)

curAjax.ajaxReq.abort();
curAjax.ajaxReq = null;
// If it's a repeatable request, then do so
if(curAjax.repeat)
newAJAXCommand(curAjax.url, curAjax.container, curAjax.repeat);
continue;
}

// If we've waited over 1 second, then we timed out
if(elapsed > timeOutMS) {
// Invoke the user function with null input
if(typeof(curAjax.container) == 'function'){
curAjax.container(null);
} else {
// Alert the user
alert("Command failed.\nConnection to development board was lost.");
}
curAjax.ajaxReq.abort();
curAjax.ajaxReq = null;

// If it's a repeatable request, then do so
if(curAjax.repeat)
newAJAXCommand(curAjax.url, curAjax.container, curAjax.repeat);
continue;
}

// Otherwise, just keep waiting
ajaxList.push(curAjax);
}

// Call ourselves again in 10ms
setTimeout("pollAJAX()",10);

}// End pollAjax

/**
* Parses the xmlResponse returned by an XMLHTTPRequest object
*
* @param the xmlData returned
* @param the field to search for
*/
function getXMLValue(xmlData, field) {
try {
if(xmlData.getElementsByTagName(field)[0].firstChild.nodeValue)
return xmlData.getElementsByTagName(field)[0].firstChild.nodeValue;
else
return null;
} catch(err) { return null; }
}
//kick off the AJAX Updater
setTimeout("pollAJAX()",500);



And I just want the same functionality within the Ext JS using a button. Maybe I am not using the correct method. Any advice would be great.

KJD
4 Dec 2009, 1:23 PM
So I figured out a way to make this work, see code below. But isn't there a better way within Ext 3.0? Why does Ext.Ajax.request not work?



//---------------------------------------------
// Add buttons for update
//---------------------------------------------
buttons:[{
text:'Edit',
disabled: false,
clickEvent: 'editPanel' // Enable the Edit button first
},{
//----------------------------------------------------
// LED #1 Button
text:'LED #1', // Text on the button
disabled: false, // It is enabled
handler: function() // Call this when button is clicked
{
var xhr;
//
if (window.XMLHttpRequest) // Object of the current windows
{
xhr = new XMLHttpRequest(); // Firefox, Safari, ...
}
else
if (window.ActiveXObject) // ActiveX version
{
xhr = new ActiveXObject("Microsoft.XMLHTTP"); // Internet Explorer
}
//
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4)
{
if(xhr.status == 200)
Ext.MessageBox.alert('Success', 'Data returned: ' + xhr.responseText);
else
Ext.MessageBox.alert('Failed', 'Data returned: ' + xhr.responseText);
}
};
//
xhr.open("POST", "leds.cgi?led=1", true);
xhr.send(null);
}
},{

hendricd
5 Dec 2009, 8:08 AM
@KJD --
Have you tried:



Ext.Ajax.request({
url:'leds.cgi',
method:'POST',
params: {led: 1},
success:function(result, request){
Ext.MessageBox.alert('Success','Data returned: '+ result.responseText);
},
failure:function(result, request){
Ext.MessageBox.alert('Failed','Data returned: '+ result.responseText);
}
});

KJD
7 Dec 2009, 7:27 AM
Hi Doug -
I tried the code you showed above and it does not work. I get an error that says -


this.getConnectionObject is not a function

I'm not sure what causes this error, any ideas?

Mike Robinson
7 Dec 2009, 8:11 AM
You may not be aware that this is a variable that can point to anything -- and that very often does not refer to what you expect it to.

In many languages, variables of this nature (called, variously, this or self) have a predefined meaning based on the physical location of the statement in the source-code. Not so JavaScript. You are instead obliged to be continually aware of what this points to, and often must explicitly change it.

If, at the time of the call, the value of this is not what you expect, then your can get errors like these. The object that this actually refers to does not contain the method or property that you expect, even though the object that you thought it would refer to, does.

Have a quick read of this page (http://odetocode.com/blogs/scott/archive/2007/07/04/function-apply-and-function-call-in-javascript.aspx) for more information about some of the fee-churs which JavaScript provides for dealing with this.

KJD
7 Dec 2009, 10:32 AM
Hi Mike -
Thanks for the feedback on this. Unfortunately I am new to Ext and still do not understand how this relates to the Ext.Ajax.Request() function. Could you offer an example of where "this" should be used?

Animal
7 Dec 2009, 12:14 PM
WHy not just set a breakpoint on that line where it drops out and debug it?

KJD
7 Dec 2009, 4:50 PM
Hi Animal -
As I have stated I am new to this stuff. I will look at Firebug and see if I can figure out how to do the breakpoint.

CrazyEnigma
8 Dec 2009, 7:02 PM
Ext.Ajax.request replaces all of the work you just posted with the XHR. It obscures having to deal with browser discrepancies.

Because you are moving an existing site to EXT JS, and you get this error when you are using Ext.Ajax.request, the XHR object must have been changed with a prototype and overwriting a crucial function and calling this.getConnectionObject. Maybe your existing site uses another framework.

I am assuming that you didn't write this code and that you are responsible of taking over an existing site. It would be nice to just start all over with the framework than to extend an existing site, but if you must, then you will have to dig into the existing javascript code to see what is causing the error, and fix it. This is not a CGI error.

KJD
9 Dec 2009, 10:46 AM
Hi CrazyEnigma
This is an embedded design that I am working on. It consists of a microcontroller running a TCP/IP stack and can serve web pages over a 10/100 connection. I have this plugged into a 10/100 hub on my network and can get the webpages served up with no problems. I like the look and feel of the Ext library and have started a webpage/application which I would like to get running with XML or CGI to communicate the data to and from the server. I have tried every way to get the Ext.Ajax.request() function to work and had no success. I used the XHR post code and that works. I am able to control LED's using that method. Obviously I am new to JS, TCP/IP, Ext . . . just looking for a little help with the Ext.Ajax command as it seems it would be better than the XHR method that I am currently using.

CrazyEnigma
9 Dec 2009, 12:51 PM
@KJD

XHR for you is probably an interim solution as you would like to dig deeper into a framework, namely EXT JS. But this is not an EXT JS issue. It happens in any JS framework or JS or dynamically scripted language. You can read up on this here (http://www.extjs.com/learn/Tutorial:What_is_that_Scope_all_about).

It is the way in which the object is designed that could get any programmer into a little bit of trouble. One example I can think of is, if you create a variable that references a JSON object (namely a config file that you are going to use to create an EXT JS object), and one of your properties or methods is a function and inside the function you refer to "this". The scope may be wrong and would likely refer to the creator rather than the created. If in any instance where this is happening you have to pass in the scope for which to run the function, much like a delegate.

But this may not be your core issue.

My question is: I am assuming that you are including connection.js from the ext\src\data\core. This is the wrong include. You only have to include one js file - ext-all.js.



<script type="text/javascript" src="lib/ext/ext-all.js"></script>
<!-- This is what is causing the error -->
<script type="text/javascript" src="lib/ext/examples/shared/code-display.js"></script>


I tried this out, and there is your offending include. I get the same error as you if I put code-display.js after ext-all.js. You should be good to go now.

KJD
9 Dec 2009, 7:51 PM
Hi CrazyEnigma -
That was it! Wow, you nailed this one. I did not realize that I only needed to include one JS file for my application. The Ext.Ajax.request() function is working now but it only works with a method of GET while the other XHR was using POST. Not sure why that is but it is working now. Thanks! Now I am on to XML data . . .

CrazyEnigma
10 Dec 2009, 7:05 AM
@KJD

Don't get me wrong, you can include other js files from the shared, like Portal Examples that would extend the framework with Portals. Sometime, you may want to include those files.

Anyways, the POST should work the same as GET. It's just symantics of delivery.

What is the error you are getting?

KJD
10 Dec 2009, 11:21 AM
Hi CrazyEnigma -
Yes, I understand that other files can be included. I have my application JS file that is included. I just didn't understand what an effect the wrong file could have. I was also having trouble with an XML file but once I removed the JS file it fixed that as well.
I tried using the POST method and I don't see any errors, it actually looks like it should be working. Firebug shows in the post tab POST led 1 which is what I would expect. It just doesn't work though. If I use the GET method all is well. Firebug shows in the params tab
_dc 1260472257299
led 1
I'm not sure what the _dc and those numbers are but that is working.

I really appreciate your help BTW.