0

I have an algorithm which binds an object from MVC (C#) to the view. The key and the data can be anything, this is up to the implementer.

The issue that I am having is that I cannot determine if something in the JSON string is an array or a simple string. The following code works recursively. If it is an array, it needs to dig deeper. Otherwise, it will bind the value it found based on the key and value.

function constructView(data)
{
    for(var key in data)
    {
        if (data[key].length > 1)
        {
            var count = 0;

            while (count < data.length)
            {
                constructView(data[count]);
                count++;
            }
        }
        $("#" + key).html(data[key]);
    }
}

This is just a prototype, so at the moment it does not generate components but simply does bindings.

Ok, so, the issue:

When I pass in

{"data":"this is a response","strings":["test1","test2"]}

it returns 18 and 2 for lengths. This is because both are technically arrays with a valid length.

Is there a way to get a item length? Where it considers a lone string as 1 item and the array as its respective item count?

I can verify that the JSON array is passed in properly.

Any help is greatly appreciated!

tereško
  • 58,060
  • 25
  • 98
  • 150
Serguei Fedorov
  • 7,763
  • 9
  • 63
  • 94
  • So you're asking how to check to see if an item is an Array? I'm certain you'd find the answer if you searched. –  May 10 '13 at 01:04
  • I have. People recommend trying to use JSON.parse() but it always returns false not matter what I put it from the data[key] – Serguei Fedorov May 10 '13 at 01:05
  • possible duplicate of [JavaScript: Check if object is array?](http://stackoverflow.com/questions/4775722/javascript-check-if-object-is-array) This shows how to distinguish between Arrays and strings. –  May 10 '13 at 01:06
  • Note: within your `constructView()` function you are _not_ dealing with JSON at all, you are dealing with an object. (Unless of course you actually call it with a string and intend for the for loop to process one character at a time...) – nnnnnn May 10 '13 at 01:15
  • MVC uses jQuery and jQuery has $.type. You can do $.type(data[key])==="array" – HMR May 10 '13 at 01:42

4 Answers4

4
Array.isArray(x)

will check for an array, although you'll need a polyfill (pretty easy to find) if you need to support legacy browsers.

typeof x === "string"

will indicate a string

Matt Berkowitz
  • 975
  • 6
  • 13
  • 1
    `foo instanceof Array` is maybe an easier, cross browser and backwards compatible way; no polyfill needed :). – Matt May 10 '13 at 01:08
  • @Matt That should work on most cases, but will fail on objects inheriting from Array.prototype (granted, [trying to subclass Array comes with its own share of problems](http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/)). – bfavaretto May 10 '13 at 01:14
1

On modern, ES5 compatible implementations, there is Array.isArray:

var a = [];
Array.isArray(a); // true

On older implementations you need this ugly workaround:

function isArray(a) {
    return ({}).toString.call(a) === "[object Array]";
    // or: 
    // return Object.prototype.toString.call(a) === "[object Array]";
}
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
0

See the other answers, but if you don't want to worry about polyfills you seem to be using jQuery already (going on your use of $(...).html(...)), so why not use jQuery's $.isArray() function?

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
0

Since you're using JQuery you can use:

if ($.type(data[key])==="array")
HMR
  • 37,593
  • 24
  • 91
  • 160
  • That method will fail for empty arrays because a length of `0` will be falsey. Also it will give false positives for objects that aren't arrays but that do have a `.sort`, `.slice` and (non-zero) `.length` (for example it will think non-empty jQuery objects are arrays when they're not). – nnnnnn May 10 '13 at 01:24
  • I thought it should because the while loop with 0 lenght will not run once. But yes; if you need something done with empty data as well then .length should go. I am looking at jQuery (most .net MVC apps use it), the $.type checks class2type but not yet sure how this is filled. If OP uses jQuery the he can use $.type(something)==="array" – HMR May 10 '13 at 01:40
  • Changed my answer, can use jQuery. – HMR May 10 '13 at 01:55