user2497586
user2497586

Reputation:

Get JSON Object length with defined type

I have seen questions and answers pertaining to finding the length of a JSON object for the purpose of just knowing. However, I need to check it later with an IF statement, and I'm getting an undefined type for the length.

When I do this:

$(function() {
      $('#filter_search').click(function() {               
          var data = JSON.stringify($('#filterform').serializeObject());
          var fetch = true;
          if ((JSON.parse(data)['checkboxes-lower'].indexOf("foo") == -1 && JSON.parse(data)['checkboxes-lower'].indexOf("bar") == -1) || (Object.keys(JSON.parse(data)).length == 1))  {
              alert("Please input at least one option");
              fetch = false;
          }
      ...

I never catch that if statement, even when I know the length is 1. The type of that length is also undefined. How can I get a meaningful (meaning that I can use in this if statement) return of length for a JSON object?

My JSON object is always of length 1 or of length 2. It will either look like this:

{"checkboxes":"foo","checkboxes-lower":["bar", "tar"]}

Or it will look like this:

{"checkboxes":["foo", "bar"]}

The above is what is outputted when I run this:

alert(JSON.stringify($('#filterform').serializeObject()));

Where serializeObject is:

$.fn.serializeObject = function() {
      var o = {};
      var a = this.serializeArray();
      $.each(a, function() {
          if (o[this.name]) {
              if (!o[this.name].push) {
                  o[this.name] = [o[this.name]];
              }
              o[this.name].push(this.value || '');
          } else {
              o[this.name] = this.value || '';
          }
      });
      return o;
  };

Essentially what I am asking is:

How do I return anything besides an undefined variable when doing Object.keys(data)? It can be a string, int, whatever. As long as I can check for equality in the if statement.

EDIT

console.log(Object.keys(JSON.parse(data)).length);

Outputs the same thing. Either 1 or 2, but doesn't give me a type

Upvotes: 1

Views: 279

Answers (1)

nnnnnn
nnnnnn

Reputation: 150050

If there is no 'checkboxes-lower' property in your object then JSON.parse(data)['checkboxes-lower'] is undefined and (JSON.parse(data)['checkboxes-lower']).indexOf is trying to do (undefined).indexOf which will give an error that stops execution of your code at that point before it can evaluate the .length of the array returned by Object.keys().

Test the length first, and test whether that property exists before trying to use it. Also, it's very messy to keep calling JSON.parse() everywhere. Why not keep a reference to the object:

      var data = $('#filterform').serializeObject(),
          json = JSON.stringify(data),
          fetch = true;
      if (Object.keys(data).length == 1 ||
               !data['checkboxes-lower'] ||     // test that property exists before using
               data['checkboxes-lower'].indexOf("foo") == -1 && // .indexOf on it
               data['checkboxes-lower'].indexOf("bar") == -1)  {
          alert("Please input at least one option");
          fetch = false;
      }

(Also I don't think you need to use .indexOf() to separately test for "foo" and "bar", because from your description it sounds like if the 'checkboxes-lower' property exists at all it will always be an array with at least one of those two options. So the !data['checkboxes-lower'] test might be enough?)

By the way, there's no such thing as a JSON object. You either have an object (data, in the code I show), or you have JSON which is the string representation returned by JSON.stringify(), which I've put in a new variable called json.

Upvotes: 1

Related Questions