Output decodeURIComponent string won't work - javascript

In my AngularJS script, I transform part of an URI using VanillaJS decodeURIComponent like this:
var someVar = decodeURIComponent(uristring); //uristring = Zao0%2B1
But when outputting someVar using alert() or placing in inside of an input field, I keep getting Zao0%2B1 instead of Zao0+B1 as an output. What is going on?

Looks like your input is incorrect for the expected result.
If we take the expected result and encode it a different value is returned than what you are using as input
var str = "Zao0+B1"// your expected output
// encode it
var encoded = encodeURIComponent(str);
console.log(encoded);// "Zao0%2BB1" - differs from your input
// decode it
var result = decodeURIComponent(encoded);
console.log(result); // "Zao0+B1" - same as original and as per expected result in question

Related

Generating fully valid JSON with client-side JavaScript

So I am trying to create a JSON explorer / editor. I am able to parse the initial JSON into the div and format it how I like.
this is the function i use to loop through the initial JSON
_iterate(_tab, raw_json){
var tab = _tab;
tab++;
for(var key1 in raw_json){
var data_type = typeof raw_json[key1];
var d = String(raw_json[key1])
if(d == String){
d = "String";
}
if(d == Number){
d= "Number"
}
if(data_type == "object" || data_type == "array"){
this.input.append(`<json-tab tab-width="${tab}"></json-tab><div class="json-editor-input-container-2 -je-${data_type}">'<span class="-je-key">${key1}</span>' :{</div></br>`)
this._iterate(tab, raw_json[key1])
}else{
this.input.append(`<div class="json-editor-row"><json-tab tab-width="${tab}"></json-tab><div class="json-editor-input-container-2">'<span class="-je-key">${key1}<span>' : '<div class="json-editor-input -je-${data_type}" contenteditable="true" for="{key: '${key1}', data: '${d}'}"></div>', </div></br></div>`)
}
}
this.input.append(`<json-tab tab-width="${tab -1}"></json-tab>},</br>`)
}
in order to save the JSON I was going to retrieve the JSON from the text of the div using
getJSON(){
var json_text = this.input.text().slice(0, -1)
return JSON.parse(`"${json_text}"`)
}
right now this is able to be parse by JSON.parse(); but when i want to console.log(getJSON()[0]) this returns {
am i not formating the JSON correctly. a live example of this can be found here
First, your console.log result doesn't make sense. A parsed JSON object is now usable in JavaScript and, if has (only) properties x and y, would result in undefined when requesting property 0 as you have. It looks like your call to console.log was to a different (earlier?) version of the getJSON() function, where it returned the raw string, and in that case it makes sense that you're just retrieving the first character of the JSON text: "{".
But then, assuming the version of getJSON() as written, it would actually throw a parse exception:
VM1511:1 Uncaught SyntaxError: Unexpected token ' in JSON at position 1
Looking at your site, I was able to do, in the console:
jsonString = $('json-editor').text()
// value: "{'partName' : '', 'partRevision' : '', ..."
That is illegal JSON. JSON specifies (only) the quotation mark " for strings (Unicode/ASCII 0x22) on page 7 of its specification.
The fact that 'partName' is legal as a JavaScript string literal is irrelevant but perhaps confusing.
As a minor style point, simplify JSON.parse(`"${json_text}"`) to JSON.parse(json_text).
#BaseZen's answer was very helpful for me to understand what was going wrong with my code. My JSON was incorrectly formatted even though online linters say its correct. Along with what BaseZen pointed out, JSON.parse() will not work with trailing commas. To fix this:
_remove_trailing_commas(json_string){
var regex = /\,(?!\s*?[\{\[\"\'\w])/g;
return json_string.replace(regex, '');
}
I found this information at SO post JSON Remove trailiing comma from last object
SO user Dima Parzhitsky's answer was what helped me also figure out this question.

Creating object from JSON and parsing JSON - different results

I am trying to use JQuery to parse some JSON being sent back from an AJAX call. It appears to be failing to parse, and JSLint also says it's invalid JSON.
However, if I create the object directly, it works and I am able to loop through it - please see below:
var json = {layers:[{layer1:[17,16,15,14,12]}]}
alert(json)// <- This works and output object Object
var somestring = "{layers:[{layer1:[17,16,15,14,12]}]}"
var parsing = JSON.parse(somestring)
alert(parsing) // <- this doesn't and breaks on parse
// The below code will work provided the parsing is commented out
json.layers.forEach(function (outerObj)
{
Object.keys(outerObj).forEach(function (key)
{
outerObj[key].forEach(function (item)
{
alert(item)
});
});
});
I'm struggling to wrap my head around why it won't parse, but appears to work.
Edit
I realise by wrapping quotes around layers and layer1 fixes it, just not sure why it works one way - but not the other.
there is a difference between javascript object and JSON object, all keys of JSON object must be quoted.
var somestring = "{layers:[{layer1:[17,16,15,14,12]}]}"// not a valid json to parse, it is a normal string, you can use JSON.stringify() to make it a valid json identifiable string.
so the correct JSON string will look like
var somestring = '{"layers":[{"layer1":[17,16,15,14,12]}]}';
var parsedJson = JSON.parse(somestring)
If you change sometring to some of the following examples, it will works.
var somestring = '{"layers":[{"layer1":[17,16,15,14,12]}]}'
var somestring = "{\"layers\":[{\"layer1\":[17,16,15,14,12]}]}"
The reason for this is, basically, that's how JSON was specified.
For further examples, take a look at w3schools
Best practice is to use JSON.stringify(Object) on one side, and JSON.parse(String) on the other. This will save you many hours of scratching your head over some niggling detail.
In your example, you could resolve the problem by
var somestring = JSON.stringify(json)
For future reference, however, JSON keys must be quoted, so your somestring should be written as:
var somestring = '{"layers":[{"layer1":[17,16,15,14,12]}]}'
Good luck!

I can not call the variable

document.getElementById("quilltext").value = '[{"insert":"12312312312312312312312312\n"}]';
var x = document.getElementById("quilltext").value;
quill.setContents(x);
doesn't work, but
quill.setContents([{"insert":"12312312312312312312312312\n"}]);
works fine.
From the question, if setContents() with array input works then you can try converting the string value with JSON.parse():
quill.setContents(JSON.parse(x));

javascript .replace() does not replace every occurence

I get the following when retrieving it.
var data = {"distinct_id"%3A "2222222222222"%2C"%24initial_referrer"%3A "%24direct"%2C"%24initial_referring_domain"%3A "%24direct"}
If I check for typeof data I get a String back.
However, when I try to make a proper object out of it by replacing "%3A" with ":" etc the above object does not replace all occurrences but only the first.
data = data.replace(/\%3A/g,":") only replaces the first "%3A".
How can I make a proper object out of this with distinct_id, $initial_referrer as well as we $initial_referring_domain ?
Testing your code proves that your replace usage is actually okay, it indeed replaces all occurrences of %3A:
var data = '{"distinct_id"%3A "2222222222222"%2C"%24initial_referrer"%3A "%24direct"%2C"%24initial_referring_domain"%3A "%24direct"}';
data = data.replace(/\%3A/g, ":");
alert(data);
However, regular expressions is not correct approach here, as you also have other encoded entities. Use decodeURIComponent function instead:
var data = '{"distinct_id"%3A "2222222222222"%2C"%24initial_referrer"%3A "%24direct"%2C"%24initial_referring_domain"%3A "%24direct"}';
data = decodeURIComponent(data);
alert(data);

Node.JS - Filename won't accept a variable

doesn't work:
console.log(obj.html_template); // outputs "myfile.html"
var html = fs.readFileSync(JSON.stringify(obj.html_template)); // file not found.
works:
console.log(obj.html_template); // "myfile.html"
var html = fs.readFileSync("myfile.html"); // Works.
I'm going crazy.
> JSON.stringify('myfile.html')
""myfile.html""
Your code is looking for the file "myfile.html" (note the superfluous quotes) in the filesystem. It doesn't exist.
Just look for it without stringification:
var html = fs.readFileSync(obj.html_template);
When you call JSON.stringify, it will convert all the Strings to the JSON format Strings, with surrounding double quotes. Quoting ECMAScript 5.1 Specification for JSON.stringify,
If Type(value) is String, then return the result of calling the abstract operation Quote with argument value.
And the Quote operation, is defined here, which basically surrounds the string with " and takes care of special characters in the String.
So JSON.stringify converts, a string, for example, abcd.txt to "abcd.txt", like this
console.log(JSON.stringify("abcd.txt"));
// "abcd.txt"
which is not equal to abcd.txt.
console.log(JSON.stringify("abcd.txt") == "abcd.txt");
// false
but equal to "abcd.txt".
console.log(JSON.stringify("abcd.txt") == '"abcd.txt"');
// true
So, your program searches for a file named "abcd.txt" instead of abcd.txt. That is why it is not able to find the file and fails.
To fix this problem, just drop the JSON.stringify and pass the string directly, like this
var html = fs.readFileSync(obj.html_template);
why are you using JSON.stringify in the first place? you should be able to just do
var html = fs.readFileSync(obj.html_template);

Categories

Resources