This is going to sound really ghetto, but I need to print some Javascript to the browser screen so that it can be cut and pasted into another program.
I'm using JSON.stringify() from json2.js, however, its not escaping characters such as quotes and new lines (",\n) which are actually control parts of a JSON object and need to be escaped.
For example, I'd get strings like this that cause problems when importing into the other program:
{
string_property_01 : "He said "HI""; // The string terminates after "He said "
}
Are there any libraries that I can use to escape all the characters that I need to escape here?
Thanks!
Option #2
var g = {
sampleFunc2 : function (data) {
var dataAsText = JSON.stringify(data);
// w jquery
$('#debugArea').text(dataAsText);
}
}
// usage...
g.sampleFunc2({ id: "4", name: "John Smith" });
In markup:
<textarea id='debugArea' rows='10' cols='50'></textarea>
I do the following, its a beautiful hack.
var g = {
sampleFunc : function (data) {
var dataAsText = JSON.stringify(data);
var response = prompt('you can copy and paste this', dataAsText);
}
}
// usage...
g.sampleFunc({ id: "4", name: "John Smith" });
JavaScript prompt... gotta love it.
Are you sure this isn't just a browser rendering thing playing tricks on you? A JSON library is going to escape chars properly to give you a valid JSON string. Have you tried comparing the output of json2.js to the native JSON.stringify some browsers (like chrome) have?
Related
I discovered Javascript ES6 Template Literals today. Just one word: Awesome!
Question: How to store and load Template Literals as JSON? I load some files via XHR, followed by some JSON.parse() which doesn't support ` instead of ", so it seems one can't save Template Literals directly in the files.
Goal: To use this for dynamic strings and translation and to get rid of confusing stuff like ("Hello " + username + "! How are you?") which requires multiple strings to be stored for just one message, and instead save my stuff beautifully and simple as
`Hello, ${username}! How are you?`
where username points to the dynamic variable with the same name. Is that possible? If yes, how to achieve this? It's okay if i have to use a function to somehow convert the strings into Template Literals as long as it doesn't hit hard on the overall performance, but I would like to at least avoid eval.
You can create your own function to parse template literal,
function stringTemplateParser(expression, valueObj) {
const templateMatcher = /{{\s?([^{}\s]*)\s?}}/g;
let text = expression.replace(templateMatcher, (substring, value, index) => {
value = valueObj[value];
return value;
});
return text
}
console.log(stringTemplateParser('my name is {{name}} and age is {{age}}', {name: 'Tom', age:100}));
// output 'my name is Tom and age is 100'
You could always use JSON.stringify to enclose dynamic data:
const data = 'some value';
JSON.stringify({
data,
});
// expected: "{\"data\": \"some value\"}"
I found it easier to separate the problem in a few substrings of JSON. Create the key "message" and this key stores parts of the message. It also works well for i18n.
{
"message" : {
"_0": "first part ",
"_1": "after first variable. ",
"_2": "after another variable"
}
}
And then, after decoding it, you can access it like
${message._0}${variable}${message._1}${var2}${message._2}
Try json-templates. Looks like exactly what you're looking for.
I have this javascript file which looks like below:
var abc= {
"a" : {
"label": "Monthly",
"URL": "xyz.com",
"ArchTag": "M",
"archData": {
"Feb 2016":"20160229",
"Jan 2016":"20160129",
"Dec 2015":"20151231"
}}};
so I want a way to edit this and say add a new month detail. I guess its a json inside javascript. So how can one edit it in a standard way.
If you can rely on the data looking exactly like this every time then you can just hack off the bit that stops it being JSON:
json_data = json.loads('{' + json_file.read().partition('{')[2])
(or use a regex, or whatever you prefer for string manipulation)
You should still beware that JavaScript is not the same as JSON, so you need some confidence that what you're given will always be an assignment of a valid JSON associative array to a variable.
If, on the other hand, you're being passed arbitrary JavaScript and you're expected to evaluate it, then you have a much bigger problem to solve. What if someone gives you var xyz = "Monthly"; var abc = {"label" : xyz, "URL" : "xyz" + "." + "com"}?
You need a JavaScript engine to solve that more general problem, not just a JSON parser. For example, js2py claims to be a complete JavaScript engine written in Python, but I've never used it so I can't recommend or dis-recommend it.
There are also security issues to consider in executing code from untrusted sources, beyond those you consider if all you're doing is parsing JSON from an untrusted source. So if you need to use a JavaScript engine, make sure you properly understand how it is sandboxed.
Your code is Javascript, not JSON...
With this code in JS you just create a new Object.
But JSON IS NOT A LANGUAGE!!.!
Json is a solution to efficiency store/transmit datas (as assiocative arrays).
Just try to do not define abc:
Your JSON file:
{
"a" :
{
"label": "Monthly",
"URL": "xyz.com",
"ArchTag": "M",
"archData":
{
"Feb 2016":"20160229",
"Jan 2016":"20160129",
"Dec 2015":"20151231"
}
}
}
If you can not remove var abc of your file, read the file in a string, remove the first characters of the string and load the new string.
try:
with open(file) as json_file:
data = file.read()
json_data = json.loads(data[9:])
pprint(json_data)
except Exception as e:
print(e)
if it is not always written var abc then start your string at the first { index.
Actually the file content is not json because of the var you mentioned. you should remove that part dynamically:
json_text = json_file.read().replace('var abc=','')
json_data = json.dumps(json_text)
pprint(json_data)
You can use regex to replace the var assignment piece:
with open('file.txt') as json_file:
data = json_file.read()
data = re.sub(r'^var\s*\S*\s*=\s*', '', data)
json_data = json.loads(data)
I have some data in the form
[
{
"name": "alex",
"fullname": "Alessandro Magno"
},
{
"name": "alex",
"fullname": "Alessandro Magno"
}
]
but (name and fullname) are not fixed, they may be "key"/"value", or whatever.
I'm also given a template to follow, e.g.:
var template = "<span>data.fullname (data.name)</span>".
My problem is the following:
I have to look for all the "data." in the string,
obtain the value following it (in this case, fullname and name),
and replace data. with my external source. E.g.
str.replace("data.<value>", source[value]);
In Javascript.
Thanks!
EDIT: I probably explained it wrongly. My source is defined (in this case, a name/fullname list in JSON format). I also have a template to follow. I have to replace the syntax used in the template (which is "data." ['data.' is fixed]) with the correspondent value of the source. Hope this is clearer now!
Re-thanks!
A simple replace call using a string will only replace a single instance of a substring. You'll have to use a regular expression.
Looking at what you're trying to do, I'd say you're probably looking for something like:
var s = "<span>data.fullname (data.name)</span>";
var replacements = {name: 'alex', fullname: 'alessandro'};//example
s.replace(/(data\.)([a-z]+)/g, function(a,b,c)
{
return b + (repl[c] || 'none');
});
This results in "data.alessandro (data.alex)"
How it works? Central to this approach is the regular expression:
/(data\.)([a-z]+)/g, which is quite basic:
(data\.): match and capture the literal string "data."
([a-z]+): again: match & capture 1 or more chars fater data. -> "data."
g: is the global flag, apply this patter to the entire string.
Now, for each match for this pattern that is found, instead of providing a replacement string, I provide a function, that is passed the matched substring (and the captured groups as separate arguments), and use the function construct a replacement string:
function(a, b, c)
{//a -> entire substring, b-> data., c-> string after data.
return b + (replacements[c] || 'none');// logical || to provide default string replacement
}
It's as simple as that, really. Given that your values are contained by objects, that are in an array, you could opt to code the following:
var vals = [{name: 'alex', fullname: 'alessandro'},{name: 'alex2', fullname: 'alessandro2'}],
results =[],
template = "<span>data.fullname (data.name)</span>";
for (var i=0;i<vals.length;++i)
results[i] = template.replace(/(data\.)([a-z]+)/g, function(a,b,c)
{
return b + (vals[i][c] || 'default');
});
Edit:
To remove data. substring, too, change the callback function (and pattern) to:
s.replace(/data\.([a-z]+)/function(a,c)
{
return replacements[c] || 'none';
});
In case of the code above:
for (var i=0;i<vals.length;++i)
results[i] = template.replace(/data\.([a-z]+)/g, function(a,c)
{
return vals[i][c] || 'default';
});
Is what you're after
If you need to use a template you could use template engine. Basically it will allow you to bind an object to a template. Behind the scene the template is parsed using regex. Pseudo-code:
var template = "<span>{fullname} ({name})</span>";
var html = template({ fullname: data.fullname, name: data.name });
To name a few:
http://handlebarsjs.com/
http://mustache.github.io/
http://underscorejs.org/
Underscore is more a library tool belt, but it provides a simple templating engine that works well for common use.
It is not clear what the transformation you are trying to achieve is, but I can tell you that you should not be using regex to achieve it! Transform your JSON into JavaScript objects using JSON.parse, transform the objects directly, then convert back to JSON via JSON.stringify.
I'm trying to parse a JSON string and I can't get it to work because of illegal chracters - which I cannot find...
Here is what I have:
make = function (el) {
var config = el.getAttribute("data-config");
console.log(config);
var dyn = $.parseJSON(config)
console.log(dyn);
}
var a= document.createElement("Star Icon");
console.log(a);
make(a);
I'm not really sure how to correctly unescape the JSON in my original string "a", so that it works.
Question_:
Which quotation marks do I need to escape to get this to work?
Thanks!
EDIT:
Ok. I figured it out using Jquery (I'd prefer Javascript-only though). This works:
make = function (el) {
var config = el.attr("data-config");
console.log(config);
var dyn = $.parseJSON(config)
console.log(dyn);
}
var c = $('<a href="#" class="template" data-config=\'{"role":"button","iconpos":"left","icon":"star","corners":"false","shadow":"false", "iconshadow":"false", "theme":"a","class":"test", "href":"index.html","text":"Star Icon", "mini":"true", "inline":"true"}\'>Star Icon</a>')
console.log(c);
make(c);
So escaping the start/end quotations of the JSON string seems to do the trick. The actual problem was that I can not use document.createElement with a full string. I can only create the element document.createElement(a) and then set innerHTML. Need to look into this some more.
If someone can tell me a Javascript-only way how to do this, please let me know.
Thanks!
Strings and object keys in JSON must be double quoted. Double quotes in attributes are not valid, so you'll need to escape them with ".
Also, you probably want to use booleans true/false instead of strings "true"/"false".
var a = document.createElement('Star Icon');
Notice this is completely unreadable and #millimoose's suggestion about just setting the attribute afterwards will make this much easier to deal with in the long run.
So basically I have this code:
var string = '{name: "bob", height: 4, weight: 145}';
I would like to know if it is possible to convert that string into an object.
so that I can use
string.name, string.height, and string.weight
(I am retrieving the string variable from a database so I cannot just remove the quotes and make it an object in the first place)
eval, as suggested by Igor, will certainly work but is vulnerable to attack.
Instead you could use a library to parse it for you. There are options in the following link:
Eval is evil... So what should I use instead?
It seems that your string is malformed. In order to work with JSON.parse or even jQuery.parseJSON methods, your keys must have speech marks (" ) around them, like so:
var str = '{"name": "bob", "height": 4, "weight": 145}';
var obj = JSON.parse(str);
You can test this by adding console.log(obj); as the final line. Here is my jsFiddle example.
So try to see if you can pull down the data from the server in the format I have suggested and it can then easily be parsed into a JavaScript object.
I would not use string for a variable name, but:
var obj = eval(string);
alert(obj.name);
or you can use jQuery.parseJSON: api.jquery.com/jQuery.parseJSON.