0

I am checking if the input value is json type or not using JavaScript but for some particular value its failing. I am explaining my code below.

isJSON = async(str) => {
  try {
    return (JSON.parse(str) && !!str);
  } catch (e) {
    return false;
  }
}

var testJSON = '{"name": "foo"}'
var number = 22
console.log("result is : ", isJSON(testJSON))
console.log("result is : ", isJSON(number))

Here str contains the input value and this method is checking that value is json type or not. But if the input value is any number i.e-str=22 then also its returning true. Here I need to check only the input value is json type value or not. Please help me to resolve the issue.

hafiz ali
  • 1,378
  • 1
  • 13
  • 33
subhra_user
  • 439
  • 5
  • 19
  • Why async? .... – mplungjan Feb 24 '21 at 08:55
  • 1
    Does this answer your question? [How to check if a string is a valid JSON string in JavaScript without using Try/Catch](https://stackoverflow.com/questions/3710204/how-to-check-if-a-string-is-a-valid-json-string-in-javascript-without-using-try) – hafiz ali Feb 24 '21 at 08:58
  • Please update your question so it's internally consistent given '22' is valid JSON. This means fixing the title and maybe "But if the input value is any number i.e-str=22 then also its returning true." Perhaps give us some example input & matching output so we don't have to guess what you want. – Allan Wind Feb 24 '21 at 09:29

2 Answers2

1

JSON.parse will coerce values into strings.

So the only other check you need to do is to test if the value is a string or not.

if (typeof str !== "string") return false;

The string "22" is a valid JSON text.


If you want to check that the value is not only JSON but a JSON representation of a non-array object. Then you would need to test for that explicitly.

isObjectAsJSON = (str) => {
  if (typeof str !== "string") return false;
  try {
    const parsed = JSON.parse(str);
    if (typeof parsed !== "object") return false;
    if (Array.isArray(parsed)) return false;
    return true;
  } catch (e) {
    return false;
  }
};

const values = {
  number: 22,
  json_number: JSON.stringify(22),
  json_array: JSON.stringify(["foo", "bar"]),
  json_object: JSON.stringify({
    foo: "bar"
  }),
};

Object.entries(values).forEach(([key, value]) => {
  console.log(key, isObjectAsJSON(value))
});
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • typeof JSON.parse('22') == 'number' – Allan Wind Feb 24 '21 at 09:12
  • @AllanWind — Yes. The JSON text `22` is a JSON representation of a number. If you parse it as JSON you get a number. – Quentin Feb 24 '21 at 09:13
  • You said "The string "22" is a valid JSON text." but I was trying to say is that instead of text use number or maybe input. – Allan Wind Feb 24 '21 at 09:15
  • @AllanWind — I have absolutely no idea what that suggestion has to do with the question this is answering. – Quentin Feb 24 '21 at 09:16
  • @Quentin, your answer is quite good but its failing for input `'{ "operation":"GET", "uri":"/asds/sadas", "headers":[{"key":"Accept","value":"application/json" }]}'` – subhra_user Feb 24 '21 at 09:23
  • @subhra_user — No. It returns true for that. It is a valid JSON text with an object at the top level. If you want to add another check that recursively searches the result to make sure there are no arrays anywhere in the data, feel free, but we're getting further and further away from what the question asked. – Quentin Feb 24 '21 at 09:25
  • yes, it was my mistake. Thanks a lot for your answer. – subhra_user Feb 24 '21 at 09:27
0

The string 22 is valid json (json is an element, element is a ws value ws, and value can be a number) per https://www.json.org/json-en.html.

Allan Wind
  • 23,068
  • 5
  • 28
  • 38
  • Not sure why my answer was down-voted. Op seems to be trying to do something different than validate the input. Maybe op expects a object which is not what is being asked. The answer would then be to check the result to see if it's the expected type with `typeof`, and to tell object or array with Array.isArray(). – Allan Wind Feb 24 '21 at 09:05