XmlHttpRequest and Anonymous Method

M

Martin

Hello all!

I have the following class which define a property called
OnRSSRequestCompleted. The property is an Anonymous Function and will
be called one XmlHttpRequest will have read the file that it has to
read... When I call the method ParseRSS(url), the file is downloaded,
parsed, but the function defined in OnRSSRequestCompleted is never
called (in that case, I expect an Message Box - alert)! I really don't
understand what is going on... Could someone please help me to figure
out?

Thank you!

function RSSReader() {
var xmlHttpRequest;

this.Channel = null;
this.OnRSSRequestCompleted = function() { };

this.sendRequest = function(url) {
if (xmlHttpRequest == null) {
xmlHttpRequest = this.createXMLHttpRequest();
}

xmlHttpRequest.open("GET", url, true);
xmlHttpRequest.setRequestHeader("cache-control", "no-cache");
xmlHttpRequest.setRequestHeader("pragma", "no-cache");
xmlHttpRequest.onreadystatechange = function() {
if (xmlHttpRequest != null &&
xmlHttpRequest.readyState == 4 &&
xmlHttpRequest.status == 200 &&
xmlHttpRequest.responseText != null) {
this.Channel = new Channel();
this.Channel.ReadRSS(xmlHttpRequest.responseText);

if (this.OnRSSRequestCompleted != null) {
this.OnRSSRequestCompleted();
}
}
}

xmlHttpRequest.send(null);
} ;

this.Read = function(url) {
this.sendRequest(url);
} ;
}

function parseRSS(rssUrl) {
var rssReader = new RSSReader();
rssReader.OnRSSRequestCompleted = function() {
alert("Salut le monde!");
};

rssReader.Read(getSearchUrl());
}
 
T

Thomas 'PointedEars' Lahn

Martin said:
I have the following class which define a property called
OnRSSRequestCompleted.

Client-side ECMAScript implementations do not have classes yet, currently
they "only" support prototype-based inheritance. You have the constructor
of an object.
The property is an Anonymous Function

The property *value* is.
and will be called one XmlHttpRequest will have read the file that it has to
read...

No, it will be called every time the XHR::readyState property value changes.
Only readyState == 4 indicates that the HTTP message header and body has
been fully processed. Hence the conditionals included below.
When I call the method ParseRSS(url), the file is downloaded,
parsed, but the function defined in OnRSSRequestCompleted is never
called (in that case, I expect an Message Box - alert)! [...]

Why would you expect that when the method in question does not contain any
statement?
Thank you!

You're welcome.
function RSSReader() {
var xmlHttpRequest;

this.Channel = null;
this.OnRSSRequestCompleted = function() { };
^^^ empty

Only identifiers of constructors and constants should begin with a capital
letter, to distinguish them from identifiers for other language features.
this.sendRequest = function(url) {
if (xmlHttpRequest == null) {
xmlHttpRequest = this.createXMLHttpRequest();
}

xmlHttpRequest.open("GET", url, true);
xmlHttpRequest.setRequestHeader("cache-control", "no-cache");
xmlHttpRequest.setRequestHeader("pragma", "no-cache");

Be careful with these, not all user agents support them. At least you
should test whether setRequestHeader() is supported before you call it;
additional exception handling would be even better, but it requires a
workaround for incompatible engines.
xmlHttpRequest.onreadystatechange = function() {
if (xmlHttpRequest != null &&

This condition does not make sense; you should remove it. The call of a
method of an object requires the object to exist.
xmlHttpRequest.readyState == 4 &&
xmlHttpRequest.status == 200 &&
xmlHttpRequest.responseText != null) {

responseText is a *string* property. Both "" and `null' type-convert to
`false' (ultimately to 0). Testing against xmlHttpRequest.responseText
suffices here:

if (...
&& xmlHttpRequest.responseText)
{
...
}
this.Channel = new Channel();

I don't think it does make sense to create the Channel object here instead
of before, but YMMV. Nevertheless, the error, if there is one, might as
well occur in that constructor.
this.Channel.ReadRSS(xmlHttpRequest.responseText);

You have not posted the Channel() constructor or the Channel::ReadRSS()
method. The error, if there is one, might as well occur in there.
if (this.OnRSSRequestCompleted != null) {
this.OnRSSRequestCompleted();
}

I don't think it makes sense to test the existence of a method that you just
created above, but YMMV. Also, since we do not know what is going on in
ReadRSS(), it might be that calling this.OnRSSRequestCompleted() is
premature here.
[...] }
}

xmlHttpRequest.send(null);
} ;

this.Read = function(url) {
this.sendRequest(url);
} ;
}

function parseRSS(rssUrl) {
var rssReader = new RSSReader();
rssReader.OnRSSRequestCompleted = function() {
alert("Salut le monde!");
};

rssReader.Read(getSearchUrl());
}

You don't post how you call that method, so it is impossible to say whether
you called it correctly or the error, if there is one, lies elsewhere.

http://www.jibbering.com/faq/faq_notes/clj_posts.html
http://www.jibbering.com/faq/#FAQ4_43


PointedEars
 
M

Martin

Martin said:
I have the following class which define a property called
OnRSSRequestCompleted.

Client-side ECMAScript implementations do not have classes yet, currently
they "only" support prototype-based inheritance. You have the constructor
of an object.
The property is an Anonymous Function

The property *value* is.
and will be called one XmlHttpRequest will have read the file that it has to
read...

No, it will be called every time the XHR::readyState property value changes.
Only readyState == 4 indicates that the HTTP message header and body has
been fully processed. Hence the conditionals included below.
When I call the method ParseRSS(url), the file is downloaded,
parsed, but the function defined in OnRSSRequestCompleted is never
called (in that case, I expect an Message Box - alert)! [...]

Why would you expect that when the method in question does not contain any
statement?
Thank you!

You're welcome.
function RSSReader() {
var xmlHttpRequest;
this.Channel = null;
this.OnRSSRequestCompleted = function() { };

^^^ empty

Only identifiers of constructors and constants should begin with a capital
letter, to distinguish them from identifiers for other language features.
this.sendRequest = function(url) {
if (xmlHttpRequest == null) {
xmlHttpRequest = this.createXMLHttpRequest();
}
xmlHttpRequest.open("GET", url, true);
xmlHttpRequest.setRequestHeader("cache-control", "no-cache");
xmlHttpRequest.setRequestHeader("pragma", "no-cache");

Be careful with these, not all user agents support them. At least you
should test whether setRequestHeader() is supported before you call it;
additional exception handling would be even better, but it requires a
workaround for incompatible engines.
xmlHttpRequest.onreadystatechange = function() {
if (xmlHttpRequest != null &&

This condition does not make sense; you should remove it. The call of a
method of an object requires the object to exist.
xmlHttpRequest.readyState == 4 &&
xmlHttpRequest.status == 200 &&
xmlHttpRequest.responseText != null) {

responseText is a *string* property. Both "" and `null' type-convert to
`false' (ultimately to 0). Testing against xmlHttpRequest.responseText
suffices here:

if (...
&& xmlHttpRequest.responseText)
{
...
}
this.Channel = new Channel();

I don't think it does make sense to create the Channel object here instead
of before, but YMMV. Nevertheless, the error, if there is one, might as
well occur in that constructor.
this.Channel.ReadRSS(xmlHttpRequest.responseText);

You have not posted the Channel() constructor or the Channel::ReadRSS()
method. The error, if there is one, might as well occur in there.
if (this.OnRSSRequestCompleted != null) {
this.OnRSSRequestCompleted();
}

I don't think it makes sense to test the existence of a method that you just
created above, but YMMV. Also, since we do not know what is going on in
ReadRSS(), it might be that calling this.OnRSSRequestCompleted() is
premature here.


[...] }
}
xmlHttpRequest.send(null);
} ;
this.Read = function(url) {
this.sendRequest(url);
} ;
}
function parseRSS(rssUrl) {
var rssReader = new RSSReader();
rssReader.OnRSSRequestCompleted = function() {
alert("Salut le monde!");
};
rssReader.Read(getSearchUrl());
}

You don't post how you call that method, so it is impossible to say whether
you called it correctly or the error, if there is one, lies elsewhere.

http://www.jibbering.com/faq/faq_notes/clj_posts.htmlhttp://www.jibbering.com/faq/#FAQ4_43

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <[email protected]>

Do you want to know how I call ParseRSS(url)? I simply pass an URL to
the function... The problem probably lies in the fact that the
function affected to xmlHttpRequest.onreadystatechange doesn't
recognize the "this" keyword...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top