JSON.parse error for single quote in json encoded string - javascript

JSON.parse is giving error Unexpected end of Json data on this json encoded string which contain single quotes
[{"size":"20cm\/S","characters_cost":[{"characters":"~!##$%\"'","cost":"78"}]}]
const json = document.querySelector('#cCalc').textContent;
const array = JSON.parse(json);
console.log(array);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input type="hidden" id="cCalc" value="[{"size":"20cm\/S","characters_cost":[{"characters":"abcdefghijklmnopqrstuvwxyz0123456789","cost":"42"},{"characters":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","cost":"48"},{"characters":"~!##$\"'","cost":""}]},{"size":"25cm\/M","characters_cost":[{"characters":"abcdefghijklmnopqrstuvwxyz0123456789","cost":"52"},{"characters":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","cost":"60"}]},{"size":"30cm\/L","characters_cost":[{"characters":"abcdefghijklmnopqrstuvwxyz0123456789","cost":"62"},{"characters":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","cost":"71"}]},{"size":"38cm\/XL","characters_cost":[{"characters":"abcdefghijklmnopqrstuvwxyz0123456789","cost":"75"},{"characters":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","cost":"86"}]}]">
</body>
</html>

You have two major problems.
textContent gives you the text in the child nodes of an element. An input is a void element. It has no child nodes. It's value can be read with the value property.
Your HTML is invalid. You are trying to use raw " characters in the value attribute's value, but that value is delimited with " so the first one marks the end of the value. You need to express them as " instead of "
Such:
const textContent = document.querySelector('#cCalc').textContent;
const json = document.querySelector('#cCalc').value;
const array = JSON.parse(json);
console.log({textContent, json, array});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input type="hidden" id="cCalc" value="[{"size":"20cm\/S","characters_cost":[{"characters":"abcdefghijklmnopqrstuvwxyz0123456789","cost":"42"},{"characters":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","cost":"48"},{"characters":"~!##$\"'","cost":""}]},{"size":"25cm\/M","characters_cost":[{"characters":"abcdefghijklmnopqrstuvwxyz0123456789","cost":"52"},{"characters":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","cost":"60"}]},{"size":"30cm\/L","characters_cost":[{"characters":"abcdefghijklmnopqrstuvwxyz0123456789","cost":"62"},{"characters":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","cost":"71"}]},{"size":"38cm\/XL","characters_cost":[{"characters":"abcdefghijklmnopqrstuvwxyz0123456789","cost":"75"},{"characters":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","cost":"86"}]}]">
</body>
</html>

The value attribute is not correctly sanitized:
You first need to HTML-entity encode the attribute contents, and then you will be able to correctly parse the JSON on the client.

Related

The getElementByID isnt showing the value

PLeaseHelp. it wont show the Value, even for form authentication, to get username & password values,I was trying the same methods.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=<device-width>,initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 id="result">Selected movie is </h1>
<select id="movie" onchange="showmovie()">
<option value="Spiderman">Spiderman</option>
<option value="Spiderman2">Spiderman2</option>
<option value="Spiderman3">Spiderman3</option>
</select>
</body>
</html>
<script>
var movie = document.getElementById("movie").value
function showmovie(){
alert("Changed")
document.getElementById("result").innerHTML="Movie chosen is"+movie
}
</script>
Try with this function showmovie
<script>
function showmovie() {
//Selected option
var selectedMovie = document.getElementById("movie").value;
document.getElementById("result").innerHTML = "Movie chosen is " + selectedMovie;
}
</script>
The issue here is because of the line var movie = document.getElementById("movie").value being executed just one time at the beginning (you could verify that adding console.log(movie); just after the movie variable declaration)
(movie stores then the value 'Spierdaman') and it never executes again with the calls for showmovie() function, so you could just move the movie declaration line above inside the function so it executes each time the action occurs and then having the good values.
Other details : To have a compliant code i suggest moving the script bloc to part just before and dont forget to add semicolons ';' at the end of each line ! + Better approach would be to use an eventListener as suggested by #T.J. Crowder in comments section above

How to unescape JSON stringified textarea value?

I have a textarea html element and I want to save its value to a JSON file by stringifying it:
document.querySelector("#button").addEventListener("click", () => {
const rawText = document.querySelector("#textarea").value;
const jsonText = JSON.stringify(rawText);
console.log(jsonText);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<textarea id="textarea" cols="30" rows="10"></textarea>
<button id="button">log json stringified</button>
</body>
</html>
Running the snippet above, we can see two problems:
When the user types in a special character, JSON.stringify() automatically escapes it.
When the user enters a new line, JSON.stringify() adds a \n special character.
How to format the output such that it preserves any special characters that the user types and ignores new lines entered by the user?
For example when user types in:
one\ntwo\tthree\\nfour
five
I want to log:
"one\ntwo\tthree\\nfourfive"
Instead I am currently logging:
"one\\ntwo\\tthree\\\\nfour\nfive"
You could just remove the new lines:
const rawText = document.querySelector("#textarea").value.replace(/\n/g, "");;
Expanding from Eugen Sunic's answer, the solution is:
const rawText = document.querySelector("#textarea").value.replace(/\n/g, "");
const jsonText = JSON.stringify(rawText).replace(/\\\\/g, "\\");

I got unexpected value while i was building module for homework

I created an HTML file that has two script
it looks like this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src='src/moduleOne.js'></script>
<script src='src/moduleTwo.js'></script>
</body>
</html>
and the first module of javascript has simple code
(function() {
let hello = 'frank';
})();
and the second one has function inside it
(function() {
function problemIsNotOccur() {
return name === undefined;
}
console.log(problemIsNotOccur());
})();
What should happen is the name should return Error name is undefind or return undefined value
But
name return '' empty string (I don't why that happen)
Your question is not clear in your case name is not defined because is not declared
(function() {
let name; ///name now is undefined
function problemIsNotOccur() {
return name === undefined; /// return true
}
console.log(problemIsNotOccur());
})();
I have just copied your code but instead of using 2 separate files, I put both functions inline and the result is "false" which is what is to be expected. The functions don't make much sense though. The first one only assigns a value to a variable and the other one returns "false" every time because you didn't define "name".
For reference, here is how I tested it:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
(function() {
let hello = 'frank';
})();
(function() {
function problemIsNotOccur() {
return name === undefined;
}
console.log(problemIsNotOccur());
})();
</script
</body>
</html>

How can I copy to clipboard specific part of paragraph?

I want to make the method or only copy to clipboard the "syntax" part of a paragraph.
I've done the logic to get the specific part of content I want and stored it in variable "syntaxClean". Now I just need to copy it somehow.
document.execCommand("copy"); would be awesome, but I just can't seem to make it work.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test</title>
</head>
<body>
<pre id="test"></pre>
<script>
const message = "====== Executor details =======\nathena#21.109.21.25 (tunneled:39516)\n====== Request details ========\nClass....................: com.ericsson.athena.taf.os.linux.commands.common.SimpleCmdRequest\nThread : ................: main\nExpected prompt..........: ^((?![<?]|\\\\.{3}|(\\\\S+\\\\s){6,}).)*[>#$%]+(\\\\\\\\u001B\\\\[(\\\\d;?)*[m|n|K])*\\\\s(\\\\\\\\u001B\\\\[(\\\\d;?)*[m|n|K])*$|#\\\\s\\\\u001B\\\\[6n\nPrompt forced............: false\nTimeout..................: 20000ms\nSyntax...................: lsb_release -i\n"
document.getElementById("test").append(message);
var res = message.split("\n");
for (var i in res) {
if (res[i].indexOf("Syntax") != -1) {
var syntax = res[i].split(':');
var syntaxClean = syntax[1].slice(1);
console.log(syntaxClean);
}
}
</script>
</body>
</html>
In this example I would like to copy to clipboard "lsb_release -i" and I have it stored in variable syntaxClean as I've already said above.
Any help is appreciated!
You can achieve this by creating a dummy textarea like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test</title>
</head>
<body>
<pre id="test"></pre>
<button onclick="copy()">Copy</button>
<script>
const message = "====== Executor details =======\nathena#21.109.21.25 (tunneled:39516)\n====== Request details ========\nClass....................: com.ericsson.athena.taf.os.linux.commands.common.SimpleCmdRequest\nThread : ................: main\nExpected prompt..........: ^((?![<?]|\\\\.{3}|(\\\\S+\\\\s){6,}).)*[>#$%]+(\\\\\\\\u001B\\\\[(\\\\d;?)*[m|n|K])*\\\\s(\\\\\\\\u001B\\\\[(\\\\d;?)*[m|n|K])*$|#\\\\s\\\\u001B\\\\[6n\nPrompt forced............: false\nTimeout..................: 20000ms\nSyntax...................: lsb_release -i\n"
document.getElementById("test").append(message);
function copy() {
var res = message.split("\n");
for (var i in res) {
if (res[i].indexOf("Syntax") != -1) {
var syntax = res[i].split(':');
var syntaxClean = syntax[1].slice(1);
console.log(syntaxClean);
copyToClipboard(syntaxClean);
}
}
}
function copyToClipboard(text) {
var dummyElm = document.createElement("textarea");
document.body.appendChild(dummyElm);
dummyElm.value = text;
dummyElm.select();
document.execCommand("copy");
document.body.removeChild(dummyElm);
}
</script>
</body>
</html>

Selecting specific part of an HTML text

I have a function that returns some HTML fragment that I store in a variable called data, with its whole structure. What I want is to extract from it some of those parts.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script id="hello">
</script>
</head>
<body>
</body>
</html>
For example, I want to get the body and save it in a new variable:
var body = data.split("<body")[1].split(">").slice(1).join(">").split("</body>")[0];
Where data is the HTML text as a string that the original function is returning.
Is there any way I could save an specific script, from its ID (in this case with id = hello), and save it in another variable??
Thank you very much
var newVar = $("#hello").html();
Let's suppose you have an HTML string in a variable, for example
var foo = '<body><span>bar</span></body>';
Now, let's initialize a parser, to convert this into HTML:
var parser = new DOMParser();
var doc = parser.parseFromString(foo, "text/html");
Now, you can read anything from foo, as it is converted into HTML:
document.getElementsByTagName("body")[0].innerHTML = doc.querySelectorAll("body")[0].innerHTML;
$html = document.querySelector("body").innerHTML;
$hello = document.getElementById("hello").innerHTML;
console.log($html);
console.log($hello);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script id="hello">
// script data
</script>
</head>
<body>
</body>
</html>

Categories

Resources