[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

Puzzling JS Error

Mel Smith

4/9/2015 5:50:00 PM

Hi:

I've been buzzing around an Ajax set up for a couple of weeks now, and
have done this successfully quite a few times over the past few years

I have serially used a older and successful Ajax set up function for
several year (a fe years ago) and am now using a slight variation of it. I
show a small fragment of the set up code which I have finally determined is
buggy -- but only in this newest case)

Within my Ajax set up ES/JS code I have the following few lines

****** fragment of Ajax set up code ********

var HTTP;
/*
// problem in this next statement
if (HTTP && (typeof HTTP !== "object" || HTTP.NAME)) {
throw new Error("Namespace 'HTTP' already exists");
}
*/
alert("Ready toComplete Ajax set up.") ;

*********************************

If I REMOVE the /* ... */ remark indicators above, my Ajax set up
function Fails ! and I get no farther in this code. A following Alert() is
never executed, and my Ajax is not operative. My later HTTP.post() function
fails as it says that HTTP is undefined

If I comment out the statement (as shown above), my Ajax request works
perfectly, and my HTTP.post() functions sends my request and I get a quick
0.5 second response !

I cannot see where my error is, and JSLint didn't help me. Also, my
other Ajax setups using this code in another app still lwork perfectly using
the code above.

Question:

What is there in the statement above that is incorrect and now causing
ES/JS to fail ??

Thanks for hints / suggestions

-Mel Smith


16 Answers

Evertjan.

4/9/2015 8:22:00 PM

0

"Mel Smith" <syntel@cox.net> wrote on 09 apr 2015 in comp.lang.javascript:

> ****** fragment of Ajax set up code ********
>
> var HTTP;
[..]
> // problem in this next statement
> if (HTTP && (typeof HTTP !== "object" || HTTP.NAME)) {

This 'if' will never see (true),
since HTTP is only declared so is false
and false && true :

try:

var HTTP;alert(!!HTTP && true); // returns false
var HTTP2;alert(!!HTTP2 && false); // returns false



> throw new Error("Namespace 'HTTP' already exists");
> }
> */
> alert("Ready toComplete Ajax set up.") ;
>
> *********************************
>



--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Thomas 'PointedEars' Lahn

4/9/2015 10:21:00 PM

0

Mel Smith wrote:

> ****** fragment of Ajax set up code ********
>
> var HTTP;
> /*
> // problem in this next statement
> if (HTTP && (typeof HTTP !== "object" || HTTP.NAME)) {
> throw new Error("Namespace 'HTTP' already exists");
> }
> */
> alert("Ready toComplete Ajax set up.") ;

Please post *real* code.

With *this* code, the alert will be displayed because you have *commented
out* the offending code.

If we assume that you have not commented it out, there will never be thrown
an exception because, barring an assignment to â??HTTPâ? earlier, the value of
the â??HTTPâ? variable is the â??undefinedâ? value, the sole value of the
Undefined type, with which all variables are initialized if they are not
initialized explicitly.

â??undefinedâ?? is type-converted to boolean â??falseâ?, and shortcut evaluation of
a logical AND expression causes the remaining operands to be ignored if one
operand evaluates to â??falseâ? (because the result can never become â??trueâ? by
further evaluation).

Next time, before you post use the debugger that is nowadays built into
*all* Web browsers (by virtue of the most of them being based on WebKit,
Gecko or MSHTML); see the FAQ.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

Mel Smith

4/9/2015 10:26:00 PM

0

Hi Evertjan:

Here is the complete Ajax set up from an *older working* Ajax
initializer that still works. Why does this *still* work when my newer one
fails ?

Thanks for a bit more insight into that 'throw' statement (and there is no
visible message when the newer one 'fails'

(I'm really mixed up now)

-Mel Smith


:


****** start of 'Older' Working Ajax initializer ********

// Make sure we haven't already been loaded
var HTTP;
if (HTTP && (typeof HTTP != "object" || HTTP.NAME)) {
throw new Error("Namespace 'HTTP' already exists");
}

// Create our namespace, and specify some meta-information
HTTP = {};
HTTP.NAME = "HTTP"; // The name of this namespace
HTTP.VERSION = 1.0; // The version of this namespace

// This is a list of XMLHttpRequest creation factory functions to try
HTTP._factories = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
];

// When we find a factory that works, store it here
HTTP._factory = null;

/**
* Create and return a new XMLHttpRequest object.
*
* The first time we're called, try the list of factory functions until
* we find one that returns a nonnull value and does not throw an
* exception. Once we find a working factory, remember it for later use.
*/
HTTP.newRequest = function() {
if (HTTP._factory != null) return HTTP._factory();

for(var i = 0; i < HTTP._factories.length; i++) {
try {
var factory = HTTP._factories[i];
var request = factory();
if (request != null) {
HTTP._factory = factory;
return request;
}
}
catch(e) {
continue;
}
}

// If we get here, none of the factory candidates succeeded,
// so throw an exception now and for all future calls.
HTTP._factory = function() {
throw new Error("XMLHttpRequest not supported");
}
HTTP._factory(); // Throw an error
}

HTTP.post = function(url, values, callback) {
var request = HTTP.newRequest();
request.open("POST", url);
// This header tells the server how to interpret the body of the request
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");


request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200 ) {
callback(request.responseText);
}
else {
callback(request.status);
}
}
}


// Encode the properties of the values object and send them as
// the body of the request.
request.send(HTTP.encodeFormData(values));
scrrequest=request; // set global vrbl screquest
};

/**
* Encode the property name/value pairs of an object as if they were from
* an HTML form, using application/x-www-form-urlencoded format
*/
HTTP.encodeFormData = function(data) {
var pairs = [];
var regexp = /%20/g; // A regular expression to match an encoded space

for(var name in data) {
var value = data[name].toString();
// Create a name/value pair, but encode name and value first
// The global function encodeURIComponent does almost what we want,
// but it encodes spaces as %20 instead of as "+". We have to
// fix that with String.replace()
var pair = encodeURIComponent(name).replace(regexp,"+") + '=' +
encodeURIComponent(value).replace(regexp,"+");
pairs.push(pair);
}

// Concatenate all the name/value pairs, separating them with &
return pairs.join('&');
};
***** end of older *working* Ajax setup ****


JJ

4/10/2015 4:15:00 AM

0

On Thu, 9 Apr 2015 11:49:46 -0600, Mel Smith wrote:

> Hi:
>
> I've been buzzing around an Ajax set up for a couple of weeks now, and
> have done this successfully quite a few times over the past few years
>
> I have serially used a older and successful Ajax set up function for
> several year (a fe years ago) and am now using a slight variation of it. I
> show a small fragment of the set up code which I have finally determined is
> buggy -- but only in this newest case)
>
> Within my Ajax set up ES/JS code I have the following few lines
>
> ****** fragment of Ajax set up code ********
>
> var HTTP;
> /*
> // problem in this next statement
> if (HTTP && (typeof HTTP !== "object" || HTTP.NAME)) {
> throw new Error("Namespace 'HTTP' already exists");
> }
> */
> alert("Ready toComplete Ajax set up.") ;
>
> *********************************
>
> If I REMOVE the /* ... */ remark indicators above, my Ajax set up
> function Fails ! and I get no farther in this code. A following Alert() is
> never executed, and my Ajax is not operative. My later HTTP.post() function
> fails as it says that HTTP is undefined
>
> If I comment out the statement (as shown above), my Ajax request works
> perfectly, and my HTTP.post() functions sends my request and I get a quick
> 0.5 second response !
>
> I cannot see where my error is, and JSLint didn't help me. Also, my
> other Ajax setups using this code in another app still lwork perfectly using
> the code above.
>
> Question:
>
> What is there in the statement above that is incorrect and now causing
> ES/JS to fail ??
>
> Thanks for hints / suggestions
>
> -Mel Smith

The reason why it fails is already explained by others.
As for the fix, use this.

//var HTTP; //don't declare
if (typeof HTTP !== "undefined" && HTTP.NAME) {
throw new Error("Namespace 'HTTP' already exists");
}
alert("Ready toComplete Ajax set up.");

Assuming that if it doesn't throw the exception, the code following the
alert() is the code that setup the "HTTP" object.

Evertjan.

4/10/2015 8:32:00 AM

0

"Mel Smith" <syntel@cox.net> wrote on 10 apr 2015 in comp.lang.javascript:

> Here is the complete Ajax set up from an *older working* Ajax
> initializer that still works. Why does this *still* work when my newer one
> fails ?
>
> Thanks for a bit more insight into that 'throw' statement

I did not say a thing about 'throw'

> (and there is no visible message when the newer one 'fails'

Better change the code so that it does show: start debugging.

I suppose "fails" just means "does not do what you supposed",
because just does what it does.

> (I'm really mixed up now)

Well, you should be, methinks your approach to your Q is wrong.

Giving us a lot of code does not help,
because we then should do
what you should do in the first place.

What you should do is ***debug***:

The art of debugging is just logical thinking,
setting breakpoints, analyzing the momentary values,

.... setting non-break points where you just update
the error-console with momentary and timing values.

.... dividing your code into logical chunks you can test
like black boxes with input and output parameters,
you can declare 'working' or improve till they are.

If then,
you find a suspected error in such a minute black box,
then ask others for their experience.

But don't give us code
that clearly does not behave like you state,
like asking why alert(false); shows true.

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Denis McMahon

4/10/2015 2:52:00 PM

0

On Thu, 09 Apr 2015 16:26:11 -0600, Mel Smith wrote:

> Here is the complete Ajax set up from an *older working* Ajax
> initializer that still works. Why does this *still* work when my newer
> one fails ?

First I would suggest looking at all the differences between your old
working code and your new not working code.

Secondly, are you loading any other scripts such as external advertising
scripts, google statistics, some other analytics, or anything else from
external sources in the page that fails that might be causing a naming
conflict with your global "HTTP" variable?

Describing your error in terms of "the code I'm not showing you doesn't
work but the code I'm showing you does work and making this little change
to the code I'm showing you makes it work or not work" really isn't very
helpful to us in trying to diagnose the issue.

All I can guess at the moment is that something is not as you think it
is, but unless you can show evidence for the error being in the code you
have identified, then I don't think that's where the real problem is.

When you said

> If I REMOVE the /* ... */ remark indicators above, my Ajax set up
> function Fails ! and I get no farther in this code.

did you mean that it threw the error "Namespace 'HTTP' already exists",
that you received some other error indication in the console, or what?

I understand:

> A following Alert() is never executed

but I'm not sure whether that's because (a) the code has thrown it's
error as instructed, in which case you need to investigate why HTTP is
defined and is either an object or has a name attribute; or (b) because
of some syntax error (which might be being caused by, for example, a non
visible encoded character in the source code file that is breaking the
javascript parser.

So: Does it throw the "Namespace 'HTTP' already exists" exception? If
not, what does the error console show (a) when the page is loaded and (b)
when the code is executed.

--
Denis McMahon, denismfmcmahon@gmail.com

Mel Smith

4/10/2015 3:48:00 PM

0

Denis said:
>
> First I would suggest looking at all the differences between your old
> working code and your new not working code.

I've looked on and off for several weeks before coming here with this
'puzzler'

>
> Secondly, are you loading any other scripts such as external advertising
> scripts, google statistics, some other analytics, or anything else from
> external sources in the page that fails that might be causing a naming
> conflict with your global "HTTP" variable?

Only my own scripts that I use for urilities. No 'outside' scripts. No
other mention of the var 'HTTP'

>
> Describing your error in terms of "the code I'm not showing you doesn't
> work but the code I'm showing you does work and making this little change
> to the code I'm showing you makes it work or not work" really isn't very
> helpful to us in trying to diagnose the issue.

To try to be more helpful:
1. I use the alert(...) function as my main (usually only) debugging
tool.
2. In this current instance, I placed an alert() ahead of my suspect
statement, and an alert() immediately after the statement
3. When the statement is 'active', the 1st alert() is displayed, but
the 2nd alert() is not shown.
4. Which leads me to believe that:
a. the statement is syntactically incorrect, or
b. An exception is 'thrown'.
5. I don't even know what 'throw' does or where it displays, or where
it can be seen
6. If it *is* 'thrown', maybe that's why I don't get to the seconf
alert() but still keep running and showing my page correctly


I guess its obvious that I copied this code years ago (maybe
incorrectly). Its from Flanagan's 'The Definitive Guide' 5th edition.

I've been using it of and on for four years now without really
understanding what was happening. But now I'm getting a better idea.

> When you said
>
>> If I REMOVE the /* ... */ remark indicators above, my Ajax set up
>> function Fails ! and I get no farther in this code.
>
> did you mean that it threw the error "Namespace 'HTTP' already exists",
> that you received some other error indication in the console, or what?
>
> I understand:
>
>> A following Alert() is never executed
>
> but I'm not sure whether that's because (a) the code has thrown it's
> error as instructed, in which case you need to investigate why HTTP is
> defined and is either an object or has a name attribute; or (b) because
> of some syntax error (which might be being caused by, for example, a non
> visible encoded character in the source code file that is breaking the
> javascript parser.

for a above . If it is 'thrown' then where is it thrown too ?
for b above. I'll retype it completely and try again later today.


>
> So: Does it throw the "Namespace 'HTTP' already exists" exception? If
> not, what does the error console show (a) when the page is loaded and (b)
> when the code is executed.

Sorry, using (mostly) IE11 , and visiting my own web site for this
page, I don't know how to activate the 'error console'. I just plug along
with Alert() functions until I narrow my bug down to some statement I can
fix. Where does this thrown error display ?

btw, because of other complexities, my CGI server (a C-based exe), gets
the request for my first/only page in this app, then looks at the IP
address. If it is my own personal IP, then I send the test page with my
error in it. Otherwise, my regular users, get the older working non-HTTP
page. When I've got this problem worked out (or ignored as above), I'll
introduce my new page to the users.

Thanks for the response.

I just got my 1st smartphone from London, England yesterday (a Moto G
(2nd Gen) (4G LTE ) unlocked with no SIM - $369 Cdn bucks+ shipping $29,97+
$28.61 Duty/taxes), and I'm excited about going out to a kiosk and getting a
SIM and getting to use the phone. New things to learn :)

In the meantime, I'm going to leave the problem statement *commented
out*, and carry on with the app development until some greater insight jumps
at me.

When I surface again in a few days, I'll be back.

Thanks again.

-Mel Smith


Christoph M. Becker

4/10/2015 4:02:00 PM

0

Mel Smith wrote:

> Sorry, using (mostly) IE11 , and visiting my own web site for this
> page, I don't know how to activate the 'error console'. I just plug along
> with Alert() functions until I narrow my bug down to some statement I can
> fix. Where does this thrown error display ?

Just press F12 to open the developer tools. There is a tab named
"Console" (at least in German IE 11 it's "Konsole") where such (and
other) error messages will be displayed. That's basically the same for
other contemporary browsers, by the way.

On <http://devtoolsecret... you can learn more about the developer
tools. In my opinion it's really worth to spend some time learning to
use these tools; it'll pay back rather quickly.

--
Christoph M. Becker

Thomas 'PointedEars' Lahn

4/11/2015 2:15:00 PM

0

JJ wrote:

> On Thu, 9 Apr 2015 11:49:46 -0600, Mel Smith wrote:
>> var HTTP;
>> /*
>> // problem in this next statement
>> if (HTTP && (typeof HTTP !== "object" || HTTP.NAME)) {
>> throw new Error("Namespace 'HTTP' already exists");
>> }
>> */
>> alert("Ready toComplete Ajax set up.") ;
>> [â?¦]
>
> The reason why it fails is already explained by others.

But you have misunderstood it anyway. Again: Variables that have been
declared but not implicitly initialized are initialized with the â??undefinedâ?
value. !!undefined === false.

I do not see how this code could generate a runtime error (not: exception)
anyway. If HTTP === undefined or HTTP === null, logical shortcut evaluation
prevents what follows the â??HTTPâ? expression from being evaluated, especially
HTTP.NAME which would throw a TypeError exception if HTTP === undefined or
HTTP === null (because those are primitive values that are not convertible
to objects â?? â??undefined/null has no propertiesâ?).

The only way that I can see this code to generate a runtime error is when
â??HTTPâ? refers to an object that type-converts to true, or a host object that
cannot be type-converted, â??typeofâ? on it yields "object", and it has a
getter for a â??NAMEâ? property that throws an exception.

> As for the fix, use this.

No, do not.

> //var HTTP; //don't declare

It is *wrong* not to declare â??HTTPâ? a variable here. It causes a
ReferenceError in strict mode to assign to such a pseudo-variable
(as the OP does) later.

> if (typeof HTTP !== "undefined" && HTTP.NAME) {

That should work. However, it is pseudo-security. Nothing prevents anyone
else from adding a â??NAMEâ? property to their object referrable by â??HTTPâ?.
Because of that, I would simply write

if (typeof HTTP != "undefined")

or in my case I have written

if (typeof jsx.net == "undefined")
{
/**
* @namespace
*/
jsx.net = {};
}

// [â?¦]

jsx.net.http = {
// [â?¦]
}

<http://PointedEars.de/wsvn/JSX/trunk/h...

It is a good idea to have oneâ??s own namespace¹ (as much as possible) for
oneâ??s own objects. â??HTTPâ? is too simple, collisions are likely.

Note that I am not throwing exceptions if there is already a â??jsx.net.httpâ?;
I simply try to overwrite it. Why? Because it could be my own. A
possibility to improve efficiency would be to skip initialization if already
initialized; but it may be better to fix the problem that caused duplicate
loading instead.

BTW, The â??!==â? instead of â??!=â? adds no efficiency here as both operands are
of the same type, String; however, it may quiet code linters such as JSHint.

______
¹ for lack of a better word
--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

JR

4/11/2015 9:09:00 PM

0

On 04/11/2015 11:15 AM, Thomas 'PointedEars' Lahn wrote:

>
> or in my case I have written
>
> if (typeof jsx.net == "undefined")

<snip>

>
> BTW, The â??!==â? instead of â??!=â? adds no efficiency here as both operands are
> of the same type, String; however, it may quiet code linters such as JSHint.

JSLInt sees an error here: "Unexpected 'typeof'. Use '===' to compare
directly with undefined."

--
Joao Rodrigues