1

I was using this to test if server returned data is json.

try {
    json = $.parseJSON(resp);
} catch (error) {
    json = null;
}

if (json) {
    //
} else {
    //
}

But it returns true if resp is a number lik 2 or 3 or... It returns null if resp is 0.

Any ideas how to avoid this false situation?

I'm outputting data using php:

echo 0; //returns null
echo 2; //returns as valid json

It appears, 0 is read as string, and 2 is read as number.

3 Answers3

2

If you're expecting an integer, use parseInt:

try {
    val = parseInt(resp, 10);

    if(val > 0) /* act accordingly ... */
} catch (error) {
    val = null;
}

If you want to know if the "JSON is valid," you can use something akin to the following:

function isValidJSON(string){
    try { 
        $.parseJSON(string);
        return true;
    }
    catch(e){ return false; }
}
Alex
  • 34,899
  • 5
  • 77
  • 90
  • I'm not expecting an integer. I use integers for error messages. –  Dec 23 '13 at 16:26
  • 3
    @salivan Use HTTP error code for that ! Don't send an error message in place of a data value ! – Denys Séguret Dec 23 '13 at 16:27
  • @dystroy: Sometimes errors are internal messages that are not HTTP or REST related. – cookie monster Dec 23 '13 at 16:28
  • @cookiemonster exactly my case. –  Dec 23 '13 at 16:29
  • @cookiemonster 1) http error codes include server error. 2) if it's not enough, if semantically the error is part of the message, data can **contain** the error : `{"error":34}`. A sane protocol shouldn't use polymorphic data where the signification is deduced from the type of the value. – Denys Séguret Dec 23 '13 at 16:30
  • 1
    I agree with @dystroy that such errors should be communicated as part of a structure as he shows instead of just a plain number. – cookie monster Dec 23 '13 at 16:31
  • @dystroy agreed. Will do that in my next app :) –  Dec 23 '13 at 16:33
  • Regarding your second example, I'm doing exactly the same thing. And it is giving me trouble. –  Dec 23 '13 at 16:44
1

I suggest something like:

// source from Angular source
function isJson(data) { 
  return (/^\s*[\[\{]/.test(data) && /[\}\]]\s*$/.test(data));
};

So...

if (isJson(resp))
  json = $.parseJSON(resp);
else
  alert ('another response: ' + resp);
Paul Rad
  • 4,820
  • 1
  • 22
  • 23
0

Numbers like 2 or 3 are technically valid JSON data. Do you expect an object? See e.g. this SO post for methods of checking if the returned variable is an object.

Basically your workflow would be to try to parse it as JSON, and if it succeeds, check if it's an object/list (depending on what you expect).

Example:

try {
    json = $.parseJSON(resp);
    return (typeof(json) === "object")
} catch (error) {
    json = null;
}
Community
  • 1
  • 1
Uli Köhler
  • 13,012
  • 16
  • 70
  • 120
  • A number doesn't make, according to the spec, a valid message : *"JSON-text = object / array"* – Denys Séguret Dec 23 '13 at 16:25
  • @dystroy This is true in respect to the JSON spec, but Javascript doesn't handle it that way. E.g. execute `JSON.parse("3")` in Node.JS, it yields 3. – Uli Köhler Dec 23 '13 at 16:26
  • @UliKöhler: But it doesn't handle `"0"` any differently than `"2"` or `"3"`. – cookie monster Dec 23 '13 at 16:27
  • @cookiemonster Do you think parsing "0" is the main problem here? I assumed the main question here is how to see the difference between numbers (including "0") and "JSON" (probably objects). To me, "0" returning false is just a sidenote. – Uli Köhler Dec 23 '13 at 16:32
  • I was only responding to your answer where you say that numbers like `2` or `3` are technically valid. Numbers like `0` aren't any different. We don't know what the actual issue is because `0` will not give `null` in the example in the question. – cookie monster Dec 23 '13 at 16:37