String to JSON convert - javascript

I am having String like this
{Name: India, Path: test.png, Id: 1, Uri: /api/1}
Through Javascript I tried to parse this value like this
var sCountry = document.getElementById("countries").value; // this will give value as {Name: India, Path: test.png, Id: 1, Uri: /api/1}
var fixedJSON = sCountry
// Replace ":" with "#colon#" if it's between double-quotes
.replace(/:\s*"([^"]*)"/g, function(match, p1) {
return ': "' + p1.replace(/:/g, '#colon#') + '"';
})
// Replace ":" with "#colon#" if it's between single-quotes
.replace(/:\s*'([^']*)'/g, function(match, p1) {
return ': "' + p1.replace(/:/g, '#colon#') + '"';
})
// Add double-quotes around any tokens before the remaining ":"
.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?\s*:/g, '"$2": ')
// Turn "#colon#" back into ":"
.replace(/#colon#/g, ':')
;
console.log('Before: ' + sCountry);
console.log('After: ' + fixedJSON);//Output comes like this {"Name": India, "Path": test.png, "Id": 1, "Uri": /api/1}
var obj = JSON.parse(fixedJSON);
It gives error like this
unexpected token e in json at position 10 at json.parse
I guess the output should be like this
{"Name": "India" , "Path": "test.png", "Id": 1, "Uri": "/api/1"}
Can anyone help me to solve this String to JSON conversion. so that I can parse and get the value of "Id"

Try it with split and join:
I have listed every step needed, but you can probably make it much smaller.
let val = '{"Name": India, "Path": test.png, "Id": 1, "Uri": /api/1}';
// Remove brackets from string (first and last char)
let valWithoutBrackets = val.substring(1, val.length-1);
// Make key value pair array in string format (delimited by : )
let keyValuePairStrings = valWithoutBrackets.split(",");
// Make two dimensional key value pair array
let keyValuePairs = keyValuePairStrings.map(k => k.split(":").map(kv => kv.trim()));
// Map all values to values with brackets, except Id
let keyValuePairsWithBrackets = keyValuePairs.map(k => {
if(k[0] != '"Id"') {
k[1] = `"${k[1]}"`;
}
return k;
});
// Make two dimensional key value pair array to key value string array
let resultKeyValuePairStrings = keyValuePairsWithBrackets.map(k => k.join(":"));
// Make key value string array to list of keyvalues and add brackets again
let resultString = `{${resultKeyValuePairStrings.join(",")}}`;
// Log the parsed JSON Id
let obj = JSON.parse(resultString);
console.log(obj);
console.log(obj.Id);
Also you can skip your regex stuff if you add it directly to my code like this:
let val = '{Name: India, Path: test.png, Id: 1, Uri: /api/1}';
// Remove brackets from string (first and last char)
let valWithoutBrackets = val.substring(1, val.length-1);
// Make key value pair array in string format (delimited by : )
let keyValuePairStrings = valWithoutBrackets.split(",");
// Make two dimensional key value pair array
let keyValuePairs = keyValuePairStrings.map(k => k.split(":").map(kv => kv.trim()));
// Map all values to values with brackets, except Id
let keyValuePairsWithBrackets = keyValuePairs.map(k => {
if(k[0] != 'Id') {
k[1] = `"${k[1]}"`;
}
k[0] = `"${k[0]}"`; // <-- Also put the key under quotations
return k;
});
// Make two dimensional key value pair array to key value string array
let resultKeyValuePairStrings = keyValuePairsWithBrackets.map(k => k.join(":"));
// Make key value string array to list of keyvalues and add brackets again
let resultString = `{${resultKeyValuePairStrings.join(",")}}`;
// Log the parsed JSON Id
let obj = JSON.parse(resultString);
console.log(obj);
console.log(obj.Id);

With converting to JSON, you can easily get the items you want using split :
var result = sCountry.split(/ *, */);
var path = result[1].split(/ *: */)[1];
var id = result[2].split(/ *: */)[1];
Please add some error checking in case you get a string of an unexpected format.

Related

Facing issues to get matched element in same order from Json Object array

I am having string with column names and trying to get value of matched element from the json object with key,value
var str=""Object Status","Reason","Date From","Date To","Object Number",";
I am having Json Object inside an array
dataResult.Objects[0]={OBJECT_NUMBER:123,OBJCET_STATUS:"NEW",DATE_FROM:"/Date(1587764199000)/",DATE_TO:"/Date(1619755200000)/",REASON:"FRESHCOPY"}
I am trying to loop through array and try to get matched element but I shoudl be expecting them in the same order as the string values are present.
for (var i = 0; i <= dataResult.Objects.length; i++) {
var item = dataResult.Objects[i - 1];
var val = '';
$.each(item, function (key, value) {
var columnCollection = str.replace(/ /g, "").toUpperCase();
var matchingKey = key.replace(/_/g, '');
if (columnCollection.includes(matchingKey)) {
val += '"' + value + '",';
}
});
}
I tried with the above code snippet but I am getting result like "123,NEW,"/Date(1587764199000)/","/Date(1619755200000)/",FRESHCOPY" but I want the data tobe in same order as string.
I am expecting the result should be "NEW,"FRESHCOPY","/Date(1587764199000)/","/Date(1619755200000)/",123"
Please let me know how can I achieve in the same order of string columns.
Wouldn't something like that work for you?
const str=`"Object Status","Reason","Date From","Date To","Object Number"`,
obj = {OBJECT_NUMBER:123,OBJECT_STATUS:"NEW",DATE_FROM:"/Date(1587764199000)/",DATE_TO:"/Date(1619755200000)/",REASON:"FRESHCOPY"},
result = str
.split(',')
.map(key =>
obj[key
.toUpperCase()
.replace(/\s/g, '_')
.replace(/"/g,'')
])
console.log(result)
.as-console-wrapper{min-height:100%;}
Instead of looping through dataResult.Objects, loop through the str list and get the corresponding object from dataResult.Objects

Converting string to object with Javascript

I am trying to convert to object this string.
"JwtBody { user_id: 1, auth_id: 1}"
"JwtBody { user_id: 1, auth_id: 1}" is obviously not a standard json string,So you can try this.
function strToObj(str){
var obj = {};
if(str&&typeof str ==='string'){
var objStr = str.match(/\{(.)+\}/g);
eval("obj ="+objStr);
}
return obj
}
Could you use JSON.parse()?
I haven't used it myself, but it looks like create a variable and use JSON.parse("string") to have it converted into an object.
So, for your example it would be something like:
var object = JSON.parse("JwtBody { user_id: 1, auth_id: 1}");
Not exactly sure what you're trying to do.
You could try something like this:
var str = '{"user_id": "1", "auth_id": "1"}';
var obj = $.parseJSON(str);
Be sure to have jquery like this:
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
If you can't change data from example:
var parsedData = {};
var str = "JwtBody { user_id: 1, auth_id: 1}";
function getRawJSON(str){
return str.split(' ').map((el, index)=>{return index>0 ? el : ''}).join('');
}
function formatingValidJSON(str){
// From https://stackoverflow.com/questions/9637517/parsing-relaxed-json-without-eval
return str
.replace(/:\s*"([^"]*)"/g, function(match, p1) {
return ': "' + p1.replace(/:/g, '#colon#') + '"';
})
.replace(/:\s*'([^']*)'/g, function(match, p1) {
return ': "' + p1.replace(/:/g, '#colon#') + '"';
})
.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?\s*:/g, '"$2": ')
.replace(/#colon#/g, ':')
}
str = formatingValidJSON(getRawJSON(str));
try{
parsedData = JSON.parse(str);
console.log('Your parsed data:', parsedData);
}
catch(e){
console.log('Your data is wrong');
}
This JSON-like string can be parsed using vanilla JavaScript and regex by:
Reducing string to only characters that String.match() JSON-like object string
String.replace() property names to enclose matched names with quotations
parsing object with JSON.parse
var jwtBodyString = "JwtBody { user_id: 1, auth_id: 1}";
`//1 match on only JSON within string
jwtBody = jwtBodyString.match(/{[^}]+}/).toString();`
//2 enclose property names to prevent errors with JSON.parse()
jwtBody = jwtBody.replace(/([a-zA-Z]+):/g,'"$1":'));
//3 obtain object
var myJwtBodyObject = JSON.parse(jwtBody);
Use JSON.parse()
Also, you're javascript string is invalid JSON which means it's invalid javascript. It should look like this:
JSON.parse('{"jwtbody" : { "user_id" : 1, "auth_id" : 1}}');
This will give you the corresponding javascript object you want.

Easiest way to convert random string to an actual JSON object

I have the following string that almost looks like valid json:
"Url: localhost/2.0/facebook,User Name: ted,User Value: 4"
How can I turn it to valid json so that if I do str.Url I get "localhost/2.0/facebook" for example?
you can do it in the following way
let str = "Url: localhost/2.0/facebook,User Name: ted,User Value: 4";
let result = {}
str.replace(/([^:]+):\s*([^,]+),?/g, function(a, b, c){
result[b] = c;
})
console.log(result);
If you are sure about your pattern, and any key or value will not contain , and : then you can try splitting first by , to get each key value pair and then split each pair by : to get key and value of each pair.
var str = "Url: localhost/2.0/facebook,User Name: ted,User Value: 4";
var obj = str.split(",").reduce((i,e)=>{
var kv = e.split(":"),
v = kv[1].trim();
i[kv[0]] = isNaN(v) ? v : parseFloat(v) ;
return i;
}, {})
console.log(obj)
You can simply use string replace with the help of regular expression to put the key and value inside quotation (") and then use JSON.parse to covert the string into the JSON Object.
let url = "Url: localhost/2.0/facebook,User Name: ted,User Value: 4";
url = url.replace(/(.*?):\s?(.*?),/g, '"$1": "$2",\n').replace(/(.*):\s?(.*)$/, '"$1": "$2"');
console.log(JSON.parse(`{ ${url} }`));
```

Remove empty brackets from a JSON object

I would like to remove the matching elements {}, and {} from a JSON string.
Input : "test": [{},{},{},{},{},{},{}],
Output : "test": [],
To do so, I tried :
var jsonConfig = JSON.stringify(jsonObj);
var jsonFinal = jsonConfig.replace(/[{},]/g, ''); // Remove global
var jsonFinal = jsonConfig.replace(/[{},]/, ''); // Remove brackets
console.log(jsonFinal);
and many more.
How can I remove only those set of elements from my JSON without impacting the other brackets and comma?
Do NOT attempt to modify JSON with string manipulation functions.
ALWAYS parse the JSON, transform the data, and re-stringify to JSON.
EDIT: this answer addresses your comment that the input data object will contain other potential keys that should be present in the output.
// a couple of procedures to help us transform the data
const isEmptyObject = x => Object.keys(x).length === 0;
const not = x => ! x;
const comp = f => g => x => f (g (x));
const remove = f => xs => xs.filter (comp (not) (f));
// your input json
let json = '{"test": [{},{},{"x": 1}], "test2": [{},{}], "a": 1, "b": 2}';
// parsed json
let data = JSON.parse(json);
// transform data
let output = JSON.stringify(Object.assign({}, data, {
// remove all empty objects from `test`
test: remove (isEmptyObject) (data.test),
// remove all empty objects from `test2`
test2: remove (isEmptyObject) (data.test2),
}));
// display output
console.log(output); // '{"test":[{"x":1}],"test2":[],"a":1,"b":2}'
I like the ES2015 answer of #naomik.
This is another alternative:
/**
* Remove empty objects or arrays
* #param {Object, Array} obj: the object to which remove empty objects or arrays
* #return {Any}
*/
const removeEmptyObject = (function() {
const isNotObject = v => v === null || typeof v !== "object";
const isEmpty = o => Object.keys(o).length === 0;
return function(obj) {
if (isNotObject(obj)) return obj;
if (obj instanceof Array) {
for (let i = 0; i < obj.length; i += 1) {
if (isNotObject(obj[i])) continue;
if (isEmpty(obj[i])) obj.splice(i--, 1);
else obj[i] = removeEmptyObject(obj[i]);
}
}
else {
for (let p in obj) {
if (isNotObject(obj[p])) continue;
if (!isEmpty(obj[p])) obj[p] = removeEmptyObject(obj[p]);
if (isEmpty(obj[p])) delete obj[p];
}
}
return obj;
}
}());
Now lets test the code:
var json = '{"test": [{},{},{"x": 1}], "test2": [{},{}], "test3":[[],[1,2,3],[]], "a": 1, "b": 2}';
var data = JSON.parse(json); //Object
var output = removeEmptyObject(data);
console.log(output);
console.log(removeEmptyObject(9));
console.log(removeEmptyObject(null));
console.log(removeEmptyObject({}));
You should work on the actual object not the string.
If you do, you can loop through the object and check if it has any properties. If it doesn't have any, you can remove it.
for(var prop in obj) {
if (obj.hasOwnProperty(prop)) {
//remove here
}
}
Setting aside the question of whether string manipulation is the best way to tidy up JSON data, your earlier attempts would remove all braces and commas, because [] in a regexp indicates "match any of the characters contained inside these brackets". If you were trying to treat those as literal characters, they'd need to be escaped: \[ or \]
You want something like .replace(/{},?/g,"") (which means "match all instances of the string {} or the string {}, -- the question mark makes the preceding character an optional match).
(This would, of course, remove all empty objects from the string, and has the potential to create invalid JSON given input like "foo: {}, bar: {}" -- so only use this if you're certain that your data will never include intentionally empty objects.)

Stringify an JS Object in Asc order

I have an js object like
{
a: 1,
b: 2,
c: 3
}
I wanted to stringify the above object using JSON.stringify with the same order. That means, the stringify should return me the strings as below,
"{"a":"1", "b":"2", "c":"3"}"
But it is returning me like the below one if my js object has too many properties say more than 500,
"{"b":"2", "a":"1", "c":"3"}"
Is there any option to get my js object's json string as in sorted in asc.
If the order is important for you, don't use JSON.stringify because the order is not safe using it, you can create your JSON stringify using javascript, to deal with string values we have 2 different ways, first to do it using regexp an replace invalid characters or using JSON.stringify for our values, for instance if we have a string like 'abc\d"efg', we can simply get the proper result JSON.stringify('abc\d"efg'), because the whole idea of this function is to stringify in a right order:
function sort_stringify(obj){
var sortedKeys = Object.keys(obj).sort();
var arr = [];
for(var i=0;i<sortedKeys.length;i++){
var key = sortedKeys[i];
var value = obj[key];
key = JSON.stringify(key);
value = JSON.stringify(value);
arr.push(key + ':' + value);
}
return "{" + arr.join(",\n\r") + "}";
}
var jsonString = sort_stringify(yourObj);
If we wanted to do this not using JSON.stringify to parse the keys and values, the solution would be like:
function sort_stringify(obj){
var sortedKeys = Object.keys(obj).sort();
var arr = [];
for(var i=0;i<sortedKeys.length;i++){
var key = sortedKeys[i];
var value = obj[key];
key = key.replace(/"/g, '\\"');
if(typeof value != "object")
value = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
arr.push('"' + key + '":"' + value + '"');
}
return "{" + arr.join(",\n\r") + "}";
}
The JavaScript objects are unordered by definition (you may refer to ECMAScript Language Specification under section 8.6, click here for details ).
The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you still required sorting, convert the object into Array apply any sorting algorithm on it and then do JSON.stringify() on sorted array.
Lets have an example below as:
var data = {
one: {
rank: 5
},
two: {
rank: 2
},
three: {
rank: 8
}
};
var arr = [];
Push into array and apply sort on it as :
var mappedHash = Object.keys( data ).sort(function( a, b ) {
return data[ a ].rank - data[ b ].rank;
}).map(function( sortedKey ) {
return data[ sortedKey ];
});
And then apply JSON.stringy :
var expectedJSON = JSON.stringify(mappedHash);
The output will be:
"[{"rank":2},{"rank":5},{"rank":8}]"

Categories