Reputation:
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
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