views:

216

answers:

3

I have a COM object which has a method that returns an unsigned int64 (VT_UI8) value. We have an HTML page which contains some JavaScript which can load the COM object and make the call to that method, to retrieve the value as such:

var foo = MyCOMObject.GetInt64Value();

This value can easily be displayed to the user in a message dialog using:

alert(foo);

or displayed on the page by:

document.getElementById('displayToUser').innerHTML = foo;

However, we cannot use this value as a Number (e.g. if we try to multiply it by 2) without the page throwing "Number expected" errors. If we check "typeof(foo)" it returns "unknown".

I've found a workaround for this by doing the following:

document.getElementById('displayToUser').innerHTML = foo;
var bar = parseInt(document.getElementById('displayToUser').innerHTML);
alert(bar*2);

What I need to know is how to make that process more efficient. Specifically, is there a way to cast foo to a String explicitly, rather than having to set some document element's innerHTML to foo and then retrieve it from that. I wouldn't mind calling something like:

alert(parseInt((string)foo) * 2);

Even better would be if there is a way to directly convert the int64 to a Number, without going through the String conversion, but I hold out less hope for that.

+3  A: 

This:

alert(Number(String(foo)) * 2);

should do it (but see below), if your COM object implements toString (or valueOf with the "string" hint) correctly (and apparently it does, if your innerHTML trick works -- because when you assign foo to innerHTML, the same process of converting the COM object to a string occurs as with String(foo)).

From Section 15.5.1 of the 5th Edition ECMAScript spec:

When String is called as a function rather than as a constructor, it performs a type conversion.

And Section 15.7.1

When Number is called as a function rather than as a constructor, it performs a type conversion

It may be worth trying just Number(foo) * 2 to make sure, but I don't think it'll work (it seems like your COM object only handles conversion to String, not Number, which isn't surprising or unreasonable).


Edit If String(foo) is failing, try:

alert(Number("" + foo) * 2);

I'm very surprised that your innerHTML trick is working but String(foo) is throwing an error. Hopefully "" + foo will trigger the same implicit conversion as your innerHTML trick.


Edit Okay, this COM object is being very strange indeed. My next two salvos:

alert(("" + foo) * 2);

That uses all implicit conversions (adding an object to a string converts the object to a string; applying the * operator to a string converts it to a number).

Alternately, we can make the string->number conversion explicit but indirect:

alert(parseInt("" + foo) * 2);
T.J. Crowder
I tried that, unfortunately, calling "String(foo)" yields a "String expected" error.
Matt
@Matt: Try `alert(Number("" + foo) * 2)` instead. (I'm *very* surprised that `String(foo)` doesn't work, but if `innerHTML = foo` works, then `"" + foo` should work.) (Edited my answer to include this.)
T.J. Crowder
Interesting, the result of that is, apparently, always 0, so that won't work either. Thanks though.
Matt
@Matt: Did you try `alert(parseInt("" + foo) * 2)`? Just in case? (Or, actually, `alert(("" + foo) * 2)` should work -- that's using all implicit conversions.) (Answer edited; maybe it should just be a list of options using strikeout for the ones that didn't work. :-) )
T.J. Crowder
@TJ Unfortunately those didn't work either. They both result in "NaN". Thanks for all the help, though!
Matt
@Matt: What's the string version of the number? Are you sure it's not just too big to fit in a Javascript Number? (Although I guess if your `innerHTML` trick works...)
T.J. Crowder
+1  A: 

Eek. Well if none of the explicit conversions are working because of the strange behaviour of the host object, let's try the implicit ones:

var n= +(''+foo);

I'm assuming you don't mind that the target type Number doesn't cover the full range of values of an int64 (it's a double, so you only get 52 bits of mantissa).

bobince
That results in n being set to 0. I know Number won't give me the range I need, but it's better than having nothing (especially since I've never seen this particular method return a result that couldn't fit in 32 bits).
Matt
A: 

Matt, from the comments to other answers, I suspect you're running this code in some sort of loop. If so, make sure that you check the returned value for null before trying your conversions.

var foo = MyCOMObject.GetInt64Value(); 
if (foo == null) {
  foo = 0; // Or something else
}
John Fisher