JSON.parse parsing a string into string - javascript

I have confusion over the functionality of JSON.parse.
I am writing code :
dynamicMsgObj = '"rest, no disc"';
var jsonObj = {};
var isJsonString = function isJsonString(str) {
try {
jsonObj = JSON.parse(str);
} catch (e) {
return false;
}
return true;
}(dynamicMsgObj);
console.log(isJsonString);// returns true
console.log(typeof jsonObj);//returns string
How is this happening??
In this way I can't determine if I am receiving string or object, which is my main objective.
Please help

That's because JSON.parse is able to successfully parse that input, it will parse it as a string and a string is what the return result will be.
Check out the documentation and look at the examples. This one specifically:
JSON.parse('"foo"'); // "foo"
And in regards to achieving your objective, you have done that already:
if(isJsonString && typeof jsonObj == 'string')
// is string
else
// is something else

Related

How can i try to get json string when i receive something more that json string?

Good morning, folks.
I have a php using AJAX. For some updates been emplemented currently i'm using json, but sometimes we receive something like
'<div class="trigger error">Some error</div>{"1":{"message":"Success something."},"2":{"message":"There is update available"}}'
There is a way to write something like
try{
obj = JSON.parse(data);
function_to_print_result(obj);
} catch (e){
var string_json = REGEX(something(data));
var old_system_error = REGEX(something(data));
try{
obj = JSON.parse(string_json);
function_to_print_result(obj);
function_to_print_old_error(old_system_error);
} catch (e){
$('.msg').empty().html(data);
}
}
I'm trying understand REGEX but, realy, i have so much difficult. I need only REGEX.
Very thanks.
First of all, you really need to work on fixing the API response. There is no way valid JSON would accept HTML strings in it.
Now, try this temporary solution to extract the data and error message from the mixed value of the API response.
var data = '<div class="trigger error">Some error</div>{"1":{"message":"Success something."},"2":{"message":"There is update available"}}';
var obj;
try{
obj = JSON.parse(data);
function_to_print_result(obj);
} catch (e){
var old_system_error;
var regex = /^<[a-zA-Z"= ]+>[a-zA-Z ]+<\/+[a-zA-Z]+>(?={)/gi;
var string_json = data.replace(regex, function(match, token){
old_system_error = match;
return '';
})
try{
obj = JSON.parse(string_json);
console.log(obj);
console.log(old_system_error);
} catch (e){
console.log(e);
}
}

Why it works like this? [duplicate]

I'm parsing some data using a type class in my controller. I'm getting data as follows:
{
"data":{
"userList":[
{
"id":1,
"name":"soni"
}
]
},
"status":200,
"config":{
"method":"POST",
"transformRequest":[
null
],
"transformResponse":[
null
],
"url":"/home/main/module/userlist",
"headers":{
"rt":"ajax",
"Tenant":"Id:null",
"Access-Handler":"Authorization:null",
"Accept":"application/json, text/plain, */*"
}
},
"statusText":"OK"
}
I tried to store the data like this
var userData = _data;
var newData = JSON.parse(userData).data.userList;
How can I extract the user list to a new variable?
The JSON you posted looks fine, however in your code, it is most likely not a JSON string anymore, but already a JavaScript object. This means, no more parsing is necessary.
You can test this yourself, e.g. in Chrome's console:
new Object().toString()
// "[object Object]"
JSON.parse(new Object())
// Uncaught SyntaxError: Unexpected token o in JSON at position 1
JSON.parse("[object Object]")
// Uncaught SyntaxError: Unexpected token o in JSON at position 1
JSON.parse() converts the input into a string. The toString() method of JavaScript objects by default returns [object Object], resulting in the observed behavior.
Try the following instead:
var newData = userData.data.userList;
The first parameter of the JSON.parse function is expected to be a string, and your data is a JavaScript object, so it will coerce it to the string "[object Object]". You should use JSON.stringify before passing the data:
JSON.parse(JSON.stringify(userData))
Don't ever use JSON.parse without wrapping it in try-catch block:
// payload
let userData = null;
try {
// Parse a JSON
userData = JSON.parse(payload);
} catch (e) {
// You can read e for more info
// Let's assume the error is that we already have parsed the payload
// So just return that
userData = payload;
}
// Now userData is the parsed result
Just above JSON.parse, use:
var newData = JSON.stringify(userData)
We can also add checks like this:
function parseData(data) {
if (!data) return {};
if (typeof data === 'object') return data;
if (typeof data === 'string') return JSON.parse(data);
return {};
}
You can simply check the typeof userData & JSON.parse() it only if it's string:
var userData = _data;
var newData;
if (typeof userData === 'object')
newData = userData.data.userList; // dont parse if its object
else if (typeof userData === 'string')
newData = JSON.parse(userData).data.userList; // parse if its string
Unexpected 'O' error is thrown when JSON data or String happens to get parsed.
If it's string, it's already stringfied. Parsing ends up with Unexpected 'O' error.
I faced similar( although in different context), I solved the following error by removing JSON Producer.
#POST
#Produces({ **MediaType.APPLICATION_JSON**})
public Response login(#QueryParam("agentID") String agentID , Officer aOffcr ) {
return Response.status(200).entity("OK").build();
}
The response contains "OK" string return.
The annotation marked as #Produces({ **MediaType.APPLICATION_JSON})** tries to parse the string to JSON format which results in Unexpected 'O'.
Removing #Produces({ MediaType.APPLICATION_JSON}) works fine.
Output : OK
Beware:
Also, on client side, if you make ajax request and use JSON.parse("OK"), it throws Unexpected token 'O'
O is the first letter of the string
JSON.parse(object) compares with jQuery.parseJSON(object);
JSON.parse('{ "name":"Yergalem", "city":"Dover"}'); --- Works Fine
The reason for the error is Object is not in the form of string, it is {} and it should be string Object('{}')
Give a try catch like this, this will parse it if its stringified or else will take the default value
let example;
try {
example = JSON.parse(data)
} catch(e) {
example = data
}
First set request value in variable like:
let reqData = req.body.reqData;
if (reqData) {
let reqDataValue = JSON.parse(JSON.stringify(reqData));
}

Unable to access JSON Element in Javascript via Object.property

I am unable to access a simple JSON Element from a JSON Structure that looks like:
{
"ACTION": "AA",
"MESSAGE": "Customer: 30xxx Already Approved on 2017/01/01"
}
I get the data in JSON Format but when i do data.ACTION or data.MESSAGE i get Undefined as the output.
By doing case sensitive also, its not working( Image attached )
var url = base + query;
var getJSON = function (url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.withCredentials = true;
xhr.onload = function () {
var status = xhr.status;
if (status == 200) {
resolve(xhr.response);
} else {
reject(status);
}
};
xhr.send();
});
};
getJSON(url).then(function (data) {
console.log(data); //Getting JSON Data
var output = JSON.stringify(data);
var obj = JSON.parse(output.replace(/ 0+(?![\. }])/g, ' '));
console.log(output);
console.log(obj.message); //Here getting UNDEFINED
}, function (status) { //error detection....
alert('Something went wrong.');
});
Console:
{"ACTION":"AA","MESSAGE":"Customer No. 0000030332 Already Approved On 20170113"}
stringify returns the following
{\"ACTION\":\"AA\",\"MESSAGE\":\"Customer No. 0000030332 Already Approved On 20170113\"}"
EDITED. I first thought the error was due to parsing, given the print. -.-
Solution:
When you print the output, obj it's still a string, not an object. So it is OK at that point.
Your "undefined" property message should be replaced by MESSAGE.
Instead of console.log(obj.message); just use console.log(obj.MESSAGE);
Also. An example of parsing JSON:
var myJson = '{"ACTION":"AA","MESSAGE":"Customer No. 0000030332 Already Approved On 20170113"}';
console.log(myJson); // This prints the literal string
console.log(JSON.parse(myJson)); // this prints an "object"
obj.message property is not defined and when you try to get the property which is not defined on an object, you get undefined.
Javascript is case sensitive. You should try obj.MESSAGE instead to get the property value. Also, to check if a property exists on an object you can make use of object.hasOwnProperty([propName]) method to check if a property exists on a object or not.
EDIT 1: Try running the following code snippet. JSON data string is parsed before accessing the property.
var jsonString = "{\"ACTION\":\"AA\",\"MESSAGE\":\"Customer No. 0000030332 Already Approved On 20170113\"}";
var obj = JSON.parse(jsonString);
console.log(obj.MESSAGE);
data already is a JSON string, there's no need to JSON.stringify it (which returns a string with a JSON-encoded string literal). Parsing it into output only leads to a string again, which has no properties. You should use
console.log(data);
var obj = JSON.parse(data);
console.log(obj);
obj.MESSAGE = obj.MESSAGE.replace(/ 0+(?![\. }])/g, ' ');
(notice the proper casing of the property name)
You can try:
var jsonObject = data.data;
console.log(jsonObject.ACTION)

SyntaxError: Unexpected token o in JSON at position 1

I'm parsing some data using a type class in my controller. I'm getting data as follows:
{
"data":{
"userList":[
{
"id":1,
"name":"soni"
}
]
},
"status":200,
"config":{
"method":"POST",
"transformRequest":[
null
],
"transformResponse":[
null
],
"url":"/home/main/module/userlist",
"headers":{
"rt":"ajax",
"Tenant":"Id:null",
"Access-Handler":"Authorization:null",
"Accept":"application/json, text/plain, */*"
}
},
"statusText":"OK"
}
I tried to store the data like this
var userData = _data;
var newData = JSON.parse(userData).data.userList;
How can I extract the user list to a new variable?
The JSON you posted looks fine, however in your code, it is most likely not a JSON string anymore, but already a JavaScript object. This means, no more parsing is necessary.
You can test this yourself, e.g. in Chrome's console:
new Object().toString()
// "[object Object]"
JSON.parse(new Object())
// Uncaught SyntaxError: Unexpected token o in JSON at position 1
JSON.parse("[object Object]")
// Uncaught SyntaxError: Unexpected token o in JSON at position 1
JSON.parse() converts the input into a string. The toString() method of JavaScript objects by default returns [object Object], resulting in the observed behavior.
Try the following instead:
var newData = userData.data.userList;
The first parameter of the JSON.parse function is expected to be a string, and your data is a JavaScript object, so it will coerce it to the string "[object Object]". You should use JSON.stringify before passing the data:
JSON.parse(JSON.stringify(userData))
Don't ever use JSON.parse without wrapping it in try-catch block:
// payload
let userData = null;
try {
// Parse a JSON
userData = JSON.parse(payload);
} catch (e) {
// You can read e for more info
// Let's assume the error is that we already have parsed the payload
// So just return that
userData = payload;
}
// Now userData is the parsed result
Just above JSON.parse, use:
var newData = JSON.stringify(userData)
We can also add checks like this:
function parseData(data) {
if (!data) return {};
if (typeof data === 'object') return data;
if (typeof data === 'string') return JSON.parse(data);
return {};
}
You can simply check the typeof userData & JSON.parse() it only if it's string:
var userData = _data;
var newData;
if (typeof userData === 'object')
newData = userData.data.userList; // dont parse if its object
else if (typeof userData === 'string')
newData = JSON.parse(userData).data.userList; // parse if its string
Unexpected 'O' error is thrown when JSON data or String happens to get parsed.
If it's string, it's already stringfied. Parsing ends up with Unexpected 'O' error.
I faced similar( although in different context), I solved the following error by removing JSON Producer.
#POST
#Produces({ **MediaType.APPLICATION_JSON**})
public Response login(#QueryParam("agentID") String agentID , Officer aOffcr ) {
return Response.status(200).entity("OK").build();
}
The response contains "OK" string return.
The annotation marked as #Produces({ **MediaType.APPLICATION_JSON})** tries to parse the string to JSON format which results in Unexpected 'O'.
Removing #Produces({ MediaType.APPLICATION_JSON}) works fine.
Output : OK
Beware:
Also, on client side, if you make ajax request and use JSON.parse("OK"), it throws Unexpected token 'O'
O is the first letter of the string
JSON.parse(object) compares with jQuery.parseJSON(object);
JSON.parse('{ "name":"Yergalem", "city":"Dover"}'); --- Works Fine
The reason for the error is Object is not in the form of string, it is {} and it should be string Object('{}')
Give a try catch like this, this will parse it if its stringified or else will take the default value
let example;
try {
example = JSON.parse(data)
} catch(e) {
example = data
}
First set request value in variable like:
let reqData = req.body.reqData;
if (reqData) {
let reqDataValue = JSON.parse(JSON.stringify(reqData));
}

Serializing to JSON in jQuery [duplicate]

This question already has answers here:
Serializing an object to JSON
(4 answers)
Closed 5 years ago.
I need to serialize an object to JSON. I'm using jQuery. Is there a "standard" way to do this?
My specific situation: I have an array defined as shown below:
var countries = new Array();
countries[0] = 'ga';
countries[1] = 'cd';
...
and I need to turn this into a string to pass to $.ajax() like this:
$.ajax({
type: "POST",
url: "Concessions.aspx/GetConcessions",
data: "{'countries':['ga','cd']}",
...
JSON-js - JSON in JavaScript.
To convert an object to a string, use JSON.stringify:
var json_text = JSON.stringify(your_object, null, 2);
To convert a JSON string to object, use JSON.parse:
var your_object = JSON.parse(json_text);
It was recently recommended by John Resig:
...PLEASE start migrating
your JSON-using applications over to
Crockford's json2.js. It is fully
compatible with the ECMAScript 5
specification and gracefully degrades
if a native (faster!) implementation
exists.
In fact, I just landed a change in jQuery yesterday that utilizes the
JSON.parse method if it exists, now
that it has been completely specified.
I tend to trust what he says on JavaScript matters :)
All modern browsers (and many older ones which aren't ancient) support the JSON object natively. The current version of Crockford's JSON library will only define JSON.stringify and JSON.parse if they're not already defined, leaving any browser native implementation intact.
I've been using jquery-json for 6 months and it works great. It's very simple to use:
var myObj = {foo: "bar", "baz": "wockaflockafliz"};
$.toJSON(myObj);
// Result: {"foo":"bar","baz":"wockaflockafliz"}
Works on IE8+
No need for jQuery, use:
JSON.stringify(countries);
I haven't used it but you might want to try the jQuery plugin written by Mark Gibson
It adds the two functions: $.toJSON(value), $.parseJSON(json_str, [safe]).
No, the standard way to serialize to JSON is to use an existing JSON serialization library. If you don't wish to do this, then you're going to have to write your own serialization methods.
If you want guidance on how to do this, I'd suggest examining the source of some of the available libraries.
EDIT: I'm not going to come out and say that writing your own serliazation methods is bad, but you must consider that if it's important to your application to use well-formed JSON, then you have to weigh the overhead of "one more dependency" against the possibility that your custom methods may one day encounter a failure case that you hadn't anticipated. Whether that risk is acceptable is your call.
I did find this somewhere. Can't remember where though... probably on StackOverflow :)
$.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;
};
If you don't want to use external libraries there is .toSource() native JavaScript method, but it's not perfectly cross-browser.
Yes, you should JSON.stringify and JSON.parse your Json_PostData before calling $.ajax:
$.ajax({
url: post_http_site,
type: "POST",
data: JSON.parse(JSON.stringify(Json_PostData)),
cache: false,
error: function (xhr, ajaxOptions, thrownError) {
alert(" write json item, Ajax error! " + xhr.status + " error =" + thrownError + " xhr.responseText = " + xhr.responseText );
},
success: function (data) {
alert("write json item, Ajax OK");
}
});
The best way is to include the polyfill for JSON object.
But if you insist create a method for serializing an object to JSON notation (valid values for JSON) inside the jQuery namespace, you can do something like this:
Implementation
// This is a reference to JSON.stringify and provides a polyfill for old browsers.
// stringify serializes an object, array or primitive value and return it as JSON.
jQuery.stringify = (function ($) {
var _PRIMITIVE, _OPEN, _CLOSE;
if (window.JSON && typeof JSON.stringify === "function")
return JSON.stringify;
_PRIMITIVE = /string|number|boolean|null/;
_OPEN = {
object: "{",
array: "["
};
_CLOSE = {
object: "}",
array: "]"
};
//actions to execute in each iteration
function action(key, value) {
var type = $.type(value),
prop = "";
//key is not an array index
if (typeof key !== "number") {
prop = '"' + key + '":';
}
if (type === "string") {
prop += '"' + value + '"';
} else if (_PRIMITIVE.test(type)) {
prop += value;
} else if (type === "array" || type === "object") {
prop += toJson(value, type);
} else return;
this.push(prop);
}
//iterates over an object or array
function each(obj, callback, thisArg) {
for (var key in obj) {
if (obj instanceof Array) key = +key;
callback.call(thisArg, key, obj[key]);
}
}
//generates the json
function toJson(obj, type) {
var items = [];
each(obj, action, items);
return _OPEN[type] + items.join(",") + _CLOSE[type];
}
//exported function that generates the json
return function stringify(obj) {
if (!arguments.length) return "";
var type = $.type(obj);
if (_PRIMITIVE.test(type))
return (obj === null ? type : obj.toString());
//obj is array or object
return toJson(obj, type);
}
}(jQuery));
Usage
var myObject = {
"0": null,
"total-items": 10,
"undefined-prop": void(0),
sorted: true,
images: ["bg-menu.png", "bg-body.jpg", [1, 2]],
position: { //nested object literal
"x": 40,
"y": 300,
offset: [{ top: 23 }]
},
onChange: function() { return !0 },
pattern: /^bg-.+\.(?:png|jpe?g)$/i
};
var json = jQuery.stringify(myObject);
console.log(json);
It's basically 2 step process:
First, you need to stringify like this:
var JSON_VAR = JSON.stringify(OBJECT_NAME, null, 2);
After that, you need to convert the string to Object:
var obj = JSON.parse(JSON_VAR);
One thing that the above solutions don't take into account is if you have an array of inputs but only one value was supplied.
For instance, if the back end expects an array of People, but in this particular case, you are just dealing with a single person. Then doing:
<input type="hidden" name="People" value="Joe" />
Then with the previous solutions, it would just map to something like:
{
"People" : "Joe"
}
But it should really map to
{
"People" : [ "Joe" ]
}
To fix that, the input should look like:
<input type="hidden" name="People[]" value="Joe" />
And you would use the following function (based off of other solutions, but extended a bit)
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (this.name.substr(-2) == "[]"){
this.name = this.name.substr(0, this.name.length - 2);
o[this.name] = [];
}
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;
};

Categories

Resources