Save javascript object into file with break words - javascript

I have a big array of objects that contains a string property. When I save my object called data to a file in json, the string property came with breaks words like "getElementsByTagName(\"track\")". I need to get like that: "getElementsByTagName("track")" without \.
my code:
var jsonobj = JSON.stringify(data,null,'\t');
fs.write('final8.json', jsonobj, 'w');

You can avoid escaping by using single quotes. For example you can replace " with ' using custom serializer.
var data = {test: 'getElementByTagName("track")'}
JSON.stringify(data, function(key,value) {
if(typeof value === 'string') {
return value.replace(/"/g, '\'')
}
return value
}, '\t');
"{
"test": "getElementByTagName('track')"
}"

Related

How to decode in JavaScript/Node.js a string of combined UTF16 and normal characters?

I have a huge JSON stringified into a string like this one:
"\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022}"
I need to JSON.parse it to use as an object. Do you know any way to decode it?
I tried decodeURIComponent(), unescape(), different variants of .replace( /\\u/g, "\u" ) and I can not get it into the needed form.
You can convert UTF-16 to text using the following function:
function utf16ToText(s) {
return s.replace(/\\u[0-9a-fA-F]{4}/gi, match => {
return String.fromCharCode(parseInt(match.replace(/\\u/g, ""), 16));
});
}
Demo:
const r = utf16ToText("\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022\\u007d");
console.log("As text: ", r);
const j = JSON.parse(r);
console.log("As JSON: ", j);
console.log("JSON Prop: ", j.name);
function utf16ToText(s) {
return s.replace(/\\u[0-9a-fA-F]{4}/gi, match => {
return String.fromCharCode(parseInt(match.replace(/\\u/g, ""), 16));
});
}
If your string is valid JSON, then you can use JSON.parse() to process the UTF16 for you. To make what you have valid JSON, you have to add double quotes to each end (inside the actual string) as all strings must be enclosed in double quotes in the JSON format. Here's an example:
let data = "\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022\\u007d";
// to make this legal JSON so we can let the JSON parser parse it for us and
// handle the UTF16 for us, we need to put double quotes in the actual string at each end
// Then, it's legal JSON and we can parse it
let str = JSON.parse('"' + data + '"');
console.log(str);
console.log("type is", typeof str);
This gives you a result in string form:
{"name":"Test"}
This result is now legal JSON on its own. If you then wanted to parse that as JSON, could just call JSON.parse() on it again to turn it into an actual Javascript object:
let data = "\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022\\u007d";
let str = JSON.parse('"' + data + '"'); // decoded string here
// now take the string and actually parse it into a Javascript object
let obj = JSON.parse(str);
console.log(obj); // Javascript object here
console.log("type is", typeof obj);
This gives you a resulting live Javascript object:
{name:"Test"}
The first call to JSON.parse() just takes your JSON string and decodes it into a Javascript string. Since that Javascript string is now also legal JSON for an object definition, you can call JSON.parse() on it again to turn it into a Javascript object.
Thank you for your input. Because of that, I got the solution:
let a = "\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022}" original string
let b = '"' + a + '"' adding " in order to make a valid stringified JSON
let c = JSON.parse(b) that will produce a partially decoded string (partially because some of the \uXXXX characters can stay in the string)
let solution = JSON.parse(c) that will create an object with all the characters decoded
Big thanks to #jfriend00

Replace double quotes with graves in a string without creating a new string

I have a json in which I store a property with a link. I want to write this to a .txt file so I can copy the content and use it in a resource object which has a serverUrl variable that I want to inject using template literals. Before I can do that I need to change the string value of the JSON a bit so I can use the template literals.
The json object has the following format:
{
"products": [
{
"image": "http://test.test.com/images/imageName.jpg"
},
{
"image": "http://test.test.com/images/imageName2.jpg"
}
]
}
What I am trying to achieve is to change every image value to the following format for each product object:
`http://${serverUrl}/images/imagename`
I managed to replace the url using a simple string.replace() during the json creation, but I am struggling with the following steps:
Change the double quotes to graves ("" => ``) and keep the url.
Do it globaly, I don't want to extract the values, the object should be overwritten.
I've tried writing some regexes, but I can't seem to figure out how I can replace both the double quotes and keep the url in one regex.
Is this the right way to go about this? Or should I try something completely different
Edit
My code so far
let dataImport = [];
// Code to convert excel to JSON
// Contains the following line for the image property
case "image":
value = value.replace("https://test.test.com", "${serverUrl}");
rowData["image"] = value;
break;
// Convert object
let json = JSON.stringify(dataImport, null, 2);
fs.writeFileSync("data.txt", json);
var json = JSON.stringify({
"products": [
{
"image": "http://test.test.com/images/imageName.jpg"
},
{
"image": "http://test.test.com/images/imageName2.jpg"
}
]
}, null, ' ');
var domain = "test.test.com";
console.log(convertJsonUrls(json, domain));
/**
* Converts any strings containing urls for the specified domain into template-strings,
* and replaces the domain with '${serverUrl}'
*/
function convertJsonUrls(json, domain) {
var stringRE = /"((?:\\.|[^\\"])*)"/g;
var urlRE = new RegExp("^(https?://)" + escapeRegExp(domain) + "(/.*)$");
var template = json.replace(stringRE, function (raw, content) {
var urlMatch = urlRE.exec(content);
if (!urlMatch) return raw; // no change, keep double-quotes
return "`" + urlMatch[1] + "${serverUrl}" + urlMatch[2] + "`";
});
return template;
}
/**
* Escapes any RegExp special characters.
* Copied from https://stackoverflow.com/a/6969486/22364
*/
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

Convert string (looking like array) to multidimensional array

I have a string:
[[-3.9,-160.1,34.7],[-0.4,16.3,18.0],[236,236,231],'SMTH 123',35]
How I can convert it to a multidimensional array?
You can use JSON.parse() to convert a string into an object, assuming it's valid JSON to begin with. Your data has strings delimited by single quotes, which is not valid JSON. If you replace them with double quotes then it will work...
var s = "[[-3.9,-160.1,34.7],[-0.4,16.3,18.0],[236,236,231],'SMTH 123',35]";
var ar = JSON.parse(s.split("'").join("\""));
console.log(ar);
How about doing something like this:
function stringToObject(data) {
var converted = {};
try {
converted = JSON.parse(data);
} catch(err) {
console.log('Provided data is not valid', err);
}
return converted;
}
console.log(stringToObject('[[-3.9,-160.1,34.7],[-0.4,16.3,18.0],[236,236,231],"SMTH 123",35]'));
console.log(stringToObject('[[-3.9,-160.1,34.7],[-0.4,16.3,18.0],[236,236,231')); // invalid string
Notice that I have changed ' into " in my sample if that is a problem you may take a look at conversion done in another answer for that question.
Assuming JQuery is also okay:
var arr = $.parseJSON('[[-3.9,-160.1,34.7],[-0.4,16.3,18.0],[236,236,231],'SMTH 123',35]')

Parse string having key=value pairs as JSON

My node app receives a series of strings in the format "a=x b=y c=z" (i.e. a string containing several space-separated key=value pairs).
What is the neatest way of converting such a string into a JSON object of the form {a: x, b: y, c: z}?
I'm betting that there's a one-line solution, but haven't managed to find it yet.
Thanks.
One way would be to replace the with a , and an = with a ::
var jsonStr = '{' + str.replace(/ /g, ', ').replace(/=/g, ': ') + '}';
Or if you need quotes around the keys and values:
var jsonStr2 = '{"' + str.replace(/ /g, '", "').replace(/=/g, '": "') + '"}';
JSON.parse() it if you need.
Sample output:
str: a=x b=y c=z
jsonStr: {a: x, b: y, c: z}
jsonStr2: {"a": "x", "b": "y", "c": "z"}
Building on John Bupit's excellent answer, I have made a couple of further enhancements to end up with the following (the string being parsed being in message):
var json = JSON.parse(('{"' + message.replace(/^\s+|\s+$/g,'').replace(/=(?=\s|$)/g, '="" ').replace(/\s+(?=([^"]*"[^"]*")*[^"]*$)/g, '", "').replace(/=/g, '": "') + '"}').replace(/""/g, '"'));
Basically the scheme is as follows:
First replace(): trim off any leading or trailing whitespace -- equivalent to trim()
Second replace(): add double quotes (empty string) for any value that is completely missing (e.g. key1= key2=val goes to key1="" key2=val).
Third replace(): replace each space (which acts as a delimiter) with ", ", but not where the space is within double quotes (i.e. part of a string value).
Fourth replace(): replace each = with ": "
Wrap the entire string up as follows: {"..."}
Finally, replace any double quotes "" created by the above steps (because the value string was already wrapped in quotes in message) with single quotes "
Even more finally, run JSON.parse() over the result.
The above scheme should cope with missing values, with some values being quoted and some unquoted, and with spaces within value strings, e.g. something like a= b="x" c="y y" d=z.
Assuming that you don't get nested objects in that format :
var sample = 'a=x b=y c=z';
var newobj = {};
sample.split(' ').forEach(function (value) {
var keypair = value.split('=');
newobj[keypair[0]] = keypair[1];
});
console.dir(newobj);
What this does is split on every white-space and push to an array, and the array is looped and each item in array is split again to get each key-value pair which is assigned to the newobj.
Here's a simple function that will do the trick
function stringToObj (string) {
var obj = {};
var stringArray = string.split(' ');
for(var i = 0; i < stringArray.length; i++){
var kvp = stringArray[i].split('=');
if(kvp[1]){
obj[kvp[0]] = kvp[1]
}
}
return obj;
}
newstr = ""
for kvp in #value.split(" ")
newstr += kvp.replace(/=/,'":"').replace(/^/, '"').replace(/$/, '"').replace(/\"\"/,'" "')
newstr = newstr.replace(/\"\"/g, '","')
jsn = JSON.parse('{' + newstr + '}')
I created a simple online tool for similar need: https://superal.github.io/online-tools/
Use cases:
To transfer key:value pairs copied from chrome network requests(form data or query string parameters) or postman headers key-value(in bulk edit style) to json format.
For example:
key:value pairs
platform:2
limit:10
start_time:1521561600
end_time:1522080000
offset:0
to json format
{
"platform": "2",
"limit": "10",
"start_time": "1521561600",
"end_time": "1522080000",
"offset": "0"
}
It can be parsed (converted to json) using the help of this npm athena-struct-parser package.
For more information about the package -- https://www.npmjs.com/package/athena-struct-parser
Sample Nodejs Code
var parseStruct =require('athena-struct-parser') ;
var str = '{description=Check the Primary key count of TXN_EVENT table in Oracle, datastore_order=1, zone=yellow, aggregation_type=count, updatedcount=0, updatedat=[2021-06-09T02:03:20.243Z]}'
var parseObj = parseStruct(str)
console.log(parseObj);
Sample string with key=value format taken
{description=Check the Primary key count of TXN_EVENT table in Oracle, datastore_order=1, zone=yellow, aggregation_type=count, updatedcount=0, updatedat=[2021-06-09T02:03:20.243Z]}
Result Parsed output
{
description: 'Check the Primary key count of TXN_EVENT table in Oracle',
datastore_order: '1',
zone: 'yellow',
aggregation_type: 'count',
updatedcount: '0',
updatedat: [ '2021-06-09T02:03:20.004Z' ]
}
I would use an approach leveraging URLSearchParams and Object.fromEntries() like so:
const input = "a=x b=y c=z";
const queryString = input.replaceAll(" ", "&");
const query = new URLSearchParams(queryString);
const output = Object.fromEntries(query);
console.log(output);
Breakdown:
The URLSearchParams constructor takes a string of key-value pairs joined by "&" as it's argument, and parses it into a URLSearchParams object instance. So to use this, the space separators in the original input need to be replaced with a "&" character.
The URLSearchParams instance we have after parsing is an iterable, so we can transform it into a plain Object with Object.fromEntries().
It's not too bad as a one-liner either:
const input = "a=x b=y c=z";
const output = Object.fromEntries(new URLSearchParams(input.replaceAll(" ", "&")));

Decoding URL parameters with JavaScript

This should be a simple task, but I can't seem to find a solution.
I have a basic string that is being passed through as a query string parameter like this one: This+is+a+message+with+spaces. I would like to decode that parameter using JavaScript to This is a message with spaces, but I cannot seem to get it to decode.
I've tried decodeURI('This+is+a+message+with+spaces') but the result still contains the + signs.
Yes it is true that decodeURIComponent function doesn't convert + to space. So you have to replace the + using replace function.
Ideally the below solution works.
var str_name = 'This+is+a+message+with+spaces';
decodeURIComponent((str_name + '').replace(/\+/g, '%20'));
Like it was pointed out already, decodeURI function doesn't convert + to space, but there are some things worth to realize here:
decodeURI is meant to be used for whole URI, i.e. it doesn't decode separators like ?, &, =, +, etc.
for decoding parameters decodeURIComponent should be used
(worth to have a look at: What is the difference between decodeURIComponent and decodeURI? )
string that you are trying to decode might actually contain + encoded as %2B, thus you should not replace + after the conversion since you might lost + signs that you actually want there, e.g. something?num=%2B632+905+123+4567 should become:
something?num=+632 905 123 4567
since you are probably going to extract the number: +632 905 123 4567
So the correct way to do this is:
var str = 'something?num=%2B632+905+123+4567';
decodeURIComponent( str.replace(/\+/g, '%20') );
The plus sign is not encoded/decoded. To see the decode function working, you need to pass a encoded URI first. Take a look:
encodeURI( "http://www.foo.com/bar?foo=foo bar jar" )
Will generate: http://www.foo.com/bar?foo=foo%20bar%20jar, i.e., the encoded URI.
decodeURI( "http://www.foo.com/bar?foo=foo%20bar%20jar" )
Will generate: http://www.foo.com/bar?foo=foo bar jar, i.e., the decoded URI.
The below code will decode and gives you the params in form of objects
export function getParamsFromUrl(url) {
url = decodeURI(url);
if (typeof url === 'string') {
let params = url.split('?');
let eachParamsArr = params[1].split('&');
let obj = {};
if (eachParamsArr && eachParamsArr.length) {
eachParamsArr.map(param => {
let keyValuePair = param.split('=')
let key = keyValuePair[0];
let value = keyValuePair[1];
obj[key] = value;
})
}
return obj;
}
}
I created my own string methods to support the needed encoding/decoding. These methods will handle the + encoding and decoding properly, allowing you to have plusses (+) in your string and still have the original spaces be encoded as +'s.
String.prototype.plusEncode = function() {
return encodeURIComponent(this).replace(/\%20/gm,"+");
}
String.prototype.plusDecode = function() {
return decodeURIComponent(this.replace(/\+/gm,"%20"));
}

Categories

Resources