views:

415

answers:

7

So, this may be a really stupid question, but I'm obviously missing something here.

Consider the following code:

    var selectedItems = [];
    selectedItems.push("0ce49e98-a8aa-46ad-bc25-3a49d475e9d3");
    //fyi, selectedItems[selectedItems.length] = "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3"; produced the same result.

At the end selectedItems content looks like this:

Name              Value                                    Type
-------------     --------------------------------------   ------
selectedItems     {...}                                    Object
   -  [0]         "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3"   String
   -  length      1                                        Long

But if I just try to call split() on the same string, like this:

selectedItems = "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3".split(",")

Now the content of my supposed array looks like this (missing length):

Name              Value                                    Type
-------------     --------------------------------------   ------
selectedItems     {...}                                    Object
   -  [0]         "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3"   String

Any idea what the difference is? What's actually happening here?
Thanks in advance.

UPDATED: I have a feeling there's actually something structurally different about the two resulting values, because (atlas) ajax chokes on the one with the length property when I try to pass it to a server-side WebMethod (no actual error message, but I know the call fails). I'm not sure.

UPDATE #2 I noticed that setting the targetLocationIdList this way, results in no 'length' property being displayed in Quick Watch window:

  var params = 
  {
    jobId : args.get_JobId(), 
    targetLocationIdList : retVal.split(',')
  };

But this results contain 'length' property displayed in Quick Watch window:

  var retValArr = [];
  retValArr = retVal.split(',');

  var params = 
  {
    jobId : args.get_JobId(), 
    targetLocationIdList : retValArr 
  };
A: 

What browser are you using, and are you sure there is no length property? I just did

var arr = "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3".split(",")

in my Firebug console, and arr does have a length property equal to 1, as expected.

Vinay Sajip
I'm debugging in Visual Studio 2008. Yes, the length property is available is accurately showing 1 if I actually call arr.length in the code. But doing a Quick Watch on arr, doesn't show me 'length' in this case.
Kon
sounds like a Microsoft deficiency
Jason S
perhaps. but I have a feeling there's actually something structurally different about the two resulting values, because (atlas) ajax chokes on the one with the length property when I try to pass it to a server-side WebMethod (no actual error message, but I know the call fails).
Kon
I just looked at it in Chrome's console and both entities are the same. I think it's the Visual Studio quickwatch window. It probably thinks one is an object and the other is an array (in JavaScript arrays and objects are both reported as objects).
Nosredna
I'd agree that it's a Visual Studio issue if it actually worked fine outside of it. but asp.net ajax (atlas) code errors out in IE7. I'll try to provide more detailed info tomorrow.
Kon
+2  A: 

Might this be a bug in the debugger? (Or is this causing problems in the browser?)

edeverett
Yes, this does actually cause a problem for me in IE7 when I try to return this value from a dialog popup.
Kon
Show us the code that doesn't work. I think you must be doing something else wrong. In one case maybe you're looking at the string length and the other the array length? Anyhow, we don't have enough info yet to help.
Nosredna
+3  A: 

There isn't a difference at all programmatically. If you run your example in both chrome developers window and firebug it looks like the 2nd

 Name              Value               
 Type
 -------------     --------------------------------------   ------ 
 selectedItems     {...}                                    Object
    -  [0]         "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3"   String

Length is an implied property

EDIT

var retVal = 'test';
var params = 
  {
    jobId : 1, 
    targetLocationIdList : retVal.split(',')
  }; 
console.log(params.targetLocationIdList.length) // prints 1

The code above prints 1 in IE8,Firefox,Chrome (in their dev tools or firebug) so think that this must be an issue with Visual Studio or with Atlas in the way that it shows the object.

AutomatedTester
See comment under edeverett's answer. Thanks.
Kon
I've added more to my explanation that might be useful
AutomatedTester
A: 

How do you know the call fails? Make sure you run in debug mode, or use a failed handler to be notified of the reason.

InfinitiesLoop
I know it fails because the code execution breaks inside asp.net ajax code. Sadly, there's a try and finally block, but not catch. :)
Kon
You mean there is a javascript error then -- what is the error message exactly if you let it run? That try/finally block is the result of processing a response from the server, so you should be able to use Fiddler to see what the response was, which could also have an important clue.
InfinitiesLoop
No, it's not processing a response from the server - the request never gets to the server. The try/finally block is with in asp.net ajax's front-end script.
Kon
There is no error message, because there is no catch block - that's the problem. But I'm not about to go editing and rebuilding asp.net ajax assembly just to figure this out - not worth my time. I figured maybe someone ran into a similar issue already.
Kon
There being no catch doesn't mean there is no error. In javascript a try/finally that has no catch has the unfortunate side effect of hiding where the original error came from. It's like it resets the stack, so the error appears to come from the finally block instead of where it really came from. If you just let the error happen, you should see something in the browser's error list. Now, that may not be true in FF, due to a bug in how it reports errors, which I've reported but has gotten much attention, so try IE.mozilla bug if interested: https://bugzilla.mozilla.org/show_bug.cgi?id=377347
InfinitiesLoop
+2  A: 

In the first instance, you are declaring selectedItems as an array and then assigning to it.

In the second instance, you are assigning to it directly from the split method.

I can only assume that VS takes the array declaration as a hint to display the length property.

Oded
+1  A: 

It looks like you've found a defect in Microsoft's Javascript implementation. It's likely that Visual Studio and IE share the same implementation so that's why you're experiencing the error in just those two programs and not in Firefox or Chrome.

In the EMCAScript standard: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf

15.5.4.14 String.prototype.split (separator, limit)
Returns an Array object into which substrings of the result of converting this object to a string have been stored.

In the definition of Array Object:

15.4 Array Objects
... Every Array object has a length property whose value is always a nonnegative integer less than 232.
William
A: 

Here's a very simple test:

var selectedItems = [];
selectedItems.push("0ce49e98-a8aa-46ad-bc25-3a49d475e9d3");
alert(selectedItems);
selectedItems = "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3".split(",");
alert("boo");
alert(selectedItems.length);

After boo, we check if there is still a length.

Answer: yes. So in other words, this is an error of Visual Studio, that and nothing more.

WebDevHobo
You guys are not paying attention. Refer to comments under Vinay Sajip's answer.
Kon