This is my JS code
add = document.getElementById("add");
add.addEventListener("click", () => {
console.log("Updating List...");
tit = document.getElementById("title").value;
desc = document.getElementById("description").value;
if (localStorage.getItem("itemsJson") == null) {
itemJsonArray = [];
itemJsonArray.push([tit, desc]);
localStorage.setItem("itemsJson", JSON.stringify(itemJsonArray));
}
});
The data should be [ABCD, XYZ]
but it is showing "[[\"\",\"\"]]".
The back slashes are supposed to be there. What you are looking at is a JSON encoded value. They are escaping the double-quotes that are inside the double-quoted string. eg: "This \"string\" value contains quotes".
JavaScript knows how to build the original data structure from that string (using the values shown from the screenshot in your comments)..
var items = localStorage.getItem("itemsJson");
\\ items[0] value is "s"
\\ items[1] value is "d"
I could write the following line of code and get the same result:
var items = "[[\"s\",\"d\"]]";
the JSON string value, eg "[[\"s\",\"d\"]]", starts and ends with quotes and the array that is being serialized contains the string values "s" and "d". If the array contained a number value, eg: 1, as well then the JSON encoded string would look like this:
"[[\"s\",\"d\",1]]"
If you run the following line of code:
alert("This \"string\" value contains quotes");
You would see this message: This "String" value contains quotes and illustrates the same concept of what the backslashes are doing.
Related
I have some poorly formatted JSON which has newlines in the keys.
The raw JSON looks like:
{
"Some\\nKey": "Some\\nvalue",
"Some nice key": "Some nice value"
}
I have a matching data source which, for keys without newlines works very happily to convert "Some nice key" into "Some nice value". However, when the matching data source contains newlines, the lookup fails. My code looks something like:
const translations = JSON.parse(fileContents);
var value = translations[key];
if (value == null) {
const fixedKey = JSON.stringify(key).replace(/\\n/g, "\\\\n");
value = translations[fixedKey];
if (value == null) {
console.log(`Translation missing for key: ${fixedKey}`);
}
}
The console output is Translation missing for key: Some\\nKey
So, my question is: In Javascript, how do I look up a value of a JSON key with new lines in the key?
Edit:
So, there were two problems with my code - one external to the post, and one internal. The external problem is that the keys coming from the external data source were somehow malformed when doing lookups with newlines - no idea what, but they were. The second issue was with creating fixedKey - JSON.stringify adds " characters to the start and end, so my console output that I originally put was a lie because I wasn't copy/pasting but recreating by hand - I had missed that the output was actually Translation missing for key: "Some\\nKey". The resulting fix was const fixedKey = JSON.stringify(key).replace(/^"/, "").replace(/"$/,""); - using Stringify and stripping the leading and trailing " characters.
This works for me. Not sure what your issue is
const key = "Some Key";
const jsonString = `{ "Some\\nKey": "Some\\nvalue", "Some nice key": "Some nice value" }`
const obj = JSON.parse(jsonString.replaceAll(/\\n/g," "))
console.log(obj[key])
This also works but shows the value with a newline
const key = "Some\nKey";
const jsonString = `{ "Some\\nKey": "Some\\nvalue", "Some nice key": "Some nice value" }`
const obj = JSON.parse(jsonString)
console.log(obj[key])
If your keys and values are the same, it shouldn't matter that there's a \n in the key or not.
const translations = {
"test\n1": 1,
"test\\n2": 2
};
console.log(translations["test\n1"]);
console.log(translations["test\\n2"]);
I have a function in Javascript to match text between curly braces (including the braces) in order to extract a JSON string from different posts. The function is below:
function eventObject(value) {
var json = text.match(/{([^}]+)}/)[0]; // matches content between curly braces
return json;
}
The input looks like this:
{
"host": "Host link..",
"info": "Info text...",
"links": [ {"title": "link_title", "url": "link_url"}, {"title": "link_title_2", "url": "link_url_2"} ],
"category": "campfire"
}
The problem is this text contains a nested string with more curly brackets. The output cuts as soon as it gets to the first occurrence of a closing bracket in the links. How can I prevent this from happening in order to get the full string?
Update
I realised I left out some important information to simplify my question: the API response is a string of raw html that contains the string I would like to parse as an object. The typical raw HTML looks like this:
"cooked":"<pre><code class=\"lang-auto\">{\n\"host\": \"host_link\",\n\"info\": \"event_info\",\n\"links\": [{\"title\": \"link_title \", \"url\": \"link_url"},{\"title\": \"link_two_title \", \"url\": \"link_two_url\"} ],\n\"category\": \"category\"\n}\n</code></pre>"}
The challenge is extracting the entire string between <code></code> and parsing it into an object. I have updated the title of the question to reflect this.
The following function successfully extracts the string and strips the html tags and line breaks, but it does not correctly parse it as an object:
function eventObject(value){
const doc = new DOMParser().parseFromString(value, "text/html");
var json = [...doc.querySelectorAll('code')].map(code => code.textContent); // DOMParser extracts text between <code> tags
var final = String(json).replace(/\n/g, " ").replace(/[\u2018\u2019]/g, "'").replace(/[\u201C\u201D]/g, '"'); // removes line breaks and replaces curly quotes with straight quotes
var string = JSON.stringify(final);
var obj = JSON.parse("'" + string + "'");
return obj;
}
Your function eventObject looks ok, but you don't need JSON.stringify because it is intended for serializing JavaScript objects, whereas you pass a string to it. Try this:
function eventObject(value){
const doc = new DOMParser().parseFromString(value, "text/html");
var json = [...doc.querySelectorAll('code')].map(code => code.textContent); // DOMParser extracts text between <code> tags
var final = String(json).replace(/\n/g, " ").replace(/[\u2018\u2019]/g, "'").replace(/[\u201C\u201D]/g, '"'); // removes line breaks and replaces curly quotes with straight quotes
// var string = JSON.stringify(final);
var obj = JSON.parse(final);
return obj;
}
var value = '"cooked":"<pre><code class=\"lang-auto\">{\n\"host\": \"host_link\",\n\"info\": \"event_info\",\n\"links\": [{\"title\": \"link_title \", \"url\": \"link_url"},{\"title\": \"link_two_title \", \"url\": \"link_two_url\"} ],\n\"category\": \"category\"\n}\n</code></pre>"}';
console.log(eventObject(value))
I have cookie value stored in following format
{stamp:'HMzWoJn8V4ZkdRN1DduMHLhS3dKiDDr6VoXCjjeuDMO2w6V+n2CcOg==',necessary:true,preferences:true,statistics:true,marketing:false,ver:1}
and i need to read following values of
necessary
preferences
statistics
marketing
Not sure how to to read values correctly, i tried following code assuming it is jSON format
Cookies.get('CookieConsent')
//Parse the cookie to Object
cookieval = Cookies.get('CookieConsent');
console.log(cookieval);
console.log("Necessary: " + Boolean(cookieval.necessary));
console.log("Prefrences: " + Boolean(cookieval.preferences));
console.log("Statistics: " + Boolean(cookieval.statistics));
console.log("Marketing: " + Boolean(cookieval.marketing));
But this code always returns false.
I use following Jquery to read Cookie values https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js
You do not have JSON format - you have something closer to JS object literal notation, except that it's a string rather than JS code, so can't use JSON.parse unfortunately.
If the values don't have commas or colons, you can split the string by commas and reduce into an object:
const input = `{stamp:'HMzWoJn8V4ZkdRN1DduMHLhS3dKiDDr6VoXCjjeuDMO2w6V+n2CcOg==',necessary:true,preferences:true,statistics:true,marketing:false,ver:1}`;
const obj = input
.slice(1, input.length - 1)
.split(',')
.reduce((obj, str) => {
const [key, val] = str.split(':');
obj[key] = val;
return obj;
}, {});
console.log(obj);
eval is another option, but that's unsafe.
Wrap this string by ( and ). Then parse like as display follow
Attention! But you need be ensure input string (which received from cookie) not contains bad code. Such as unknown injected function. In this case, the function will be executed on client browser, with access to private data (cookie, localStorage, data from html-forms).
const input = "{stamp:'HMzWoJn8V4ZkdRN1DduMHLhS3dKiDDr6VoXCjjeuDMO2w6V+n2CcOg==',necessary:true,preferences:true,statistics:true,marketing:false,ver:1}"
const object = eval("(" + input + ")");
alert(object.necessary);
What about massaging the string into proper JSON, parsing it into a JSON Object, and using the fields from there?
It's less stable in that changes to the input string may break the function, but it is secure in that it's calling JSON.parse() rather than eval().
function reformatCookieInput(inputString) {
inputString = inputString.replace(/'/g, ""); //global strip out single quotes currently wrapping stamp
inputString = inputString.replace(/,/g, `", "`); //global replace commas with wrapped commas
inputString = inputString.replace(/:/g, `":"`); //same idea with colons
inputString = inputString.replace("{", `{"`); //rewrap start of JSON string
inputString = inputString.replace("}", `"}`); //rewrap end of JSON string
return inputString;
}
const input = `{stamp:'HMzWoJn8V4ZkdRN1DduMHLhS3dKiDDr6VoXCjjeuDMO2w6V+n2CcOg==',necessary:true,preferences:true,statistics:true,marketing:false,ver:1}`;
const properJSONObject = JSON.parse(reformatCookieInput(input));
console.log(properJSONObject);
var data = this.state.registerMobile;
//My data will be like +91 345 45-567
data.replace('-','');
It is not removing '-' and i am trying to remove spaces also in between.It's not working.
For that, you need to assign the result of replace to some variable, replace will not do the changes in same variable, it will return the modified value. So use it like this:
var data = this.state.registerMobile;
data = data.replace('-', '');
console.log('updated data', data);
Check the example:
a = '+91 12345678';
b = a.replace('+', '');
console.log('a', a );
console.log('b', b );
String.prototype.replace() does not change the original string but returns a new one. Its first argument is either of the following:
regexp (pattern)
A RegExp object or literal. The match or matches are replaced with newSubStr or the value returned by the specified function.
substr (pattern)
A String that is to be replaced by newSubStr. It is treated as a verbatim string and is not interpreted as a regular expression. Only the first occurrence will be replaced.
So if you want to replace hypens and whitespaces, you have to use the following:
var data = this.state.registerMobile;
data = data.replace(/\s|-/g, '');
$('#groupnamesearch').blur(function () {
str = $('#groupnamesearch').val()
$.get("injectgroup.php", {
name: str
}, function (data) {
//here i guess str.replace data
$('#aspecforgroup').val(data);
});
});
This gives me results like: ["45054","55905","42306"]
I'd like to strip all []" of them, so I have only numbers and the , character.
How can I manipulate the data that came over the ajax request before it's getting populated in an input field?
Thanks :)
If the result that you are getting back in data is an actual string - and I assume it must be if the square brackets are getting displayed in your "aspecforgroup" field - then you can remove those characters as follows:
data = data.replace(/[\[\]"]/g, "");
Or you can tell jQuery (that is jQuery that you're using?) to treat the response as JSON in which case it should be automatically parsed into an array by the time it ends up in the data parameter and then you can use the array .join() method to turn that into a string:
$.get("injectgroup.php", {
name: str
}, function (data) {
$('#aspecforgroup').val(data.join(","));
}, "json");
The parameter to .join() is the string to join the individual elements with. If you leave it out it will be a comma by default, but you might want to use a comma plus a space: .join(", ").
You can do this with array join
if your data is string, you have to first parse the string to convert an array and then do a join like this -
var newData = JSON.parse(data).join();
if data is a string:
data = '["45054","55905","42306"]';
var output = JSON.parse(data).join(', ');
alert(output);
if data is already an array:
data = ["45054","55905","42306"];
var output = data.join(', ');
alert(output);
both output this:
45054, 55905, 42306