Converting JSON to have a new top-level wrapper - javascript

I suspect I am using the wrong terminology, so please bear with me.
I have been using mustache.js very effectively to work with the JSON output of an API. I am working with a sibling API that has outlook that looks mostly similar, excepting that there is no top-level name. I am trying to figure out how to adjust the new JSON output into the other format, such that I can continue using my mustache.js approach (this seems like the easier of the options, the other being using something other than mustache.js, which I am seeking to avoid).
I can use mustache.js to iterate very easily over the following JSON body using the top-level name 'records':
{"records":
[{"dt_created":"08/23/2013 04:49:13 PM","created_by":"x, x","dt_updated":"08/23/2013 04:49:13 PM","updated_by":"x, x","field_60374": ["Project 67"],"field_60331":["Ability to adjust the number of lines dynamically based on the mood of the person 3 rows down, 4th cube, 11th building. A breakthrough in mind-control data processing."],"field_60333": [{"id":"x","first":"x","last":"x"}],"field_60394": [{"id":"x","first":"x","last":"x"}],"field_60414":["11"],"field_60375": ["22"],"field_60395":["A"],"record_id":"1920704","form_id":"10898"},
{"dt_created":"08/23/2013 04:47:45 PM","created_by":"x, x","dt_updated":"08/23/2013 04:47:45 PM","updated_by":"x, x","field_60374":["Project 2"],"field_60331":["Very cool project to allow more than a single invoice to be in an ERP at any one time. Quite a big leap forward."],"field_60333": [{"id":"x","first":"x","last":"x"}],"field_60394": [{"id":"x","first":"x","last":"x"}],"field_60414":["x, x"],"field_60375":["60"],"field_60395": ["A"],"record_id":"1920703","form_id":"10898"}],
"meta":{"total":2,"count":2}
}
The format that I can't iterate through, since it is missing a top-level name, is:
[{"id":"x","user": {"id":"x","first_name":"x","last_name":"x"},"title":"Test Post 3","text":"This is an equally cool and enthralling post.","created_at":"2013-08-29T17:46:04.801Z","updated_at":"2013-08-29T17:46:04.804Z","num_comments":0,"num_likes":0},
{"id":"y","user": {"id":"212342277","first_name":"x","last_name":"x"},"title":"Test Post 1","text":"Super cool content you want to read!","created_at":"2013-08- 29T17:44:58.188Z","updated_at":"2013-08-29T17:44:58.190Z","num_comments":0,"num_likes":0}]
I tried the following to massage the second JSON example into the format of the first:
$.ajax({
[…….],
success: function(json_data){
alert("success");
var template=$('#listPosts').html();
var stuff = {"records":json_data}; //here
var stuff = JSON.stringify(stuff); //here
alert(stuff);
//var html = Mustache.to_html(template, json_data);
var html = Mustache.to_html(template, stuff);
//$('.content-pane').empty();
$('#listOfPostsContainer').html(html);
}
}
I have an alert that pops up with what is in var 'stuff', and it seems to be formatted like the first JSON example, but mustache.js doesn't parse it (I have verified mustache.js executes). Before trying to address any other issues, I wanted to understand if how I am adding a top-level name to the JSON array in the above AJAX call success attribute is correct, or if I have to do it differently.
If I am missing something to help explain this, let me know, so I can add it.

Related

HTML Formatting in json data that comes out raw

I imported json data from this website that provides open data for garbage retrieval. On my website I have a search bar that searches through that to provide the relevant data from the garbage data. Each piece of data has a title and has details about that piece of garbage.
The problem I have is that when I try to output the details part of it, it comes embedded with html formatting stuff it is all properly escaped for display in html. When I try to output it from js by changing a text element on my page using innerhtml, it comes out with all the escape formatting still there. I have copy pasted it and displayed it separately and it displays properly so I know there isn't a problem with the json text.
var garbageInfo = JSON.parse(ourRequest.responseText);
...
for (j = 0;j<garbageInfo.length;j++){
var dataTitle = garbageInfo[j].title.toUpperCase()
if((dataTitle.indexOf(input)!=-1)){
body = garbageInfo[j].body;
document.getElementById("info").innerHTML = body
}
};
For example the output will come out as <ul> <li>Place item in the <strong>Garbage Bin.</strong></li> </ul>
Where it should be the same but with the proper formatting.
Sorry I am quite new to this so I imagine I am doing something wrong I am sorry if this is some repetitive question but I searched around and I couldn't find anyone with a similar problem.
Thank you

Decoding/reading json part of complex text file

I am starting to develop a desktop application using Electron. This app will parse some files and datas will be shown from these files. These files are containing complex data.
Now, I am trying to get json data from a complex text file. This text file contains some string and json objects. Sample file looks like that:
...strings that I'm not interested in...
{
"partOneA":0,
"partOneB":7,
....
}
...randomly strings may stand between json sections...
{
"partTwoA":7,
"partTwoB":4,
"partTwoC":4,
...
}
{
"differentPartA":3,
"differentPartB":5,
"differentPartC":6,
...
}
...somemoretext....
The problem is that, how can I get the json parts from this complex file using javascript? Performance of the solution should be considered.
Additionaly, Consider that json structure is nested like that:
{
"partOneA":0,
"partOneB" :{
"partOneBnode1":0,
"partOneBnode2":7,
}
}
Resolving with regular expressions is not applicable for this issue.
Now, I am trying to find a javascript based solution.
As long as you can rely on { and } as starting and closing tags you could use a regex like:
var jsonRegex = new RegExp(/({(?:(.|\n)*?(?:[^\\])){0,1}?})/g);
var result = jsonRegex.exec(text);
var firstMatch= result[1];
As a result you should get the first piece with the subsequent matches at the subsequent indexes. You can read the docs here on mdn.
You can play around with regex on sites like http://regexr.com/
Note
This approach does not work with nested JSON because you would require to match the same amount of opening and closing brackets (see this answer).

"Fixing" JSON coming out of MySQL

I'm fetching JSON code stored in MySQL and it has extra slashes, which I have to remove in order to parse it in JavaScript, after I print it on the page. Right now I'm doing the following:
$save = str_replace("\n", "<br>", $save); // Replace new line characters with <br>
$save = str_replace('\\"', '"', $save); // top-level JSON
$save = str_replace('\\\\"', '\"', $save); // HTML inside top level JSON
$save = str_replace('\\\\\\\\\\"', '\\\\\"', $save); // HTML inside second level JSON
Here is an example JSON code, as it comes out from MySQL:
{\"id\":2335,\"editor\":{\"selected_shape\":\"spot-7488\"},\"general\":{\"name\":\"HTML Test\",\"shortcode\":\"html-test\",\"width\":1280,\"height\":776},\"spots\":[{\"id\":\"spot-7488\",\"x\":9.9,\"y\":22.6,\"default_style\":{\"use_icon\":1},\"tooltip_content\":{\"content_type\":\"content-builder\",\"plain_text\":\"<p class=\\\"test\\\">Test</p>\",\"squares_json\":\"{\\\"containers\\\":[{\\\"id\\\":\\\"sq-container-293021\\\",\\\"settings\\\":{\\\"elements\\\":[{\\\"settings\\\":{\\\"name\\\":\\\"Paragraph\\\",\\\"iconClass\\\":\\\"fa fa-paragraph\\\"},\\\"options\\\":{\\\"text\\\":{\\\"text\\\":\\\"<p class=\\\\\\\"test\\\\\\\">Test</p>\\\"}}}]}}]}\"}}]}
And here is how it's supposed to look in order to get parsed correctly (using jsonlint.com to test):
{"id":2335,"editor":{"selected_shape":"spot-7488"},"general":{"name":"HTML Test","shortcode":"html-test","width":1280,"height":776},"spots":[{"id":"spot-7488","x":9.9,"y":22.6,"default_style":{"use_icon":1},"tooltip_content":{"content_type":"content-builder","plain_text":"<p class=\"test\">Test</p>","squares_json":"{\"containers\":[{\"id\":\"sq-container-293021\",\"settings\":{\"elements\":[{\"settings\":{\"name\":\"Paragraph\",\"iconClass\":\"fa fa-paragraph\"},\"options\":{\"text\":{\"text\":\"<p class=\\\"test\\\">Test</p>\"}}}]}}]}"}}]}
Please note that I have HTML code inside JSON, which is inside another JSON and this is where it gets a bit messy.
My question - is there a function or library for PHP (for JS will work too) which covers all those corner cases, because I'm sure someone will find a way to break the script.
Thanks!
The short answer, which is woefully inadequate, is for you to use stripslashes. The reason this answer is not adequate is that your JSON string might have been escaped or had addslashes called on it multiple times and you would have to call stripslashes precisely once for each time this had happened.
The proper solution is to find out where the slashes are being added and either a) avoid adding the slashes or b) understand why the slashes are there and respond accordingly. I strongly believe that the process that creates that broken JSON is where the problem lies.
Slashes are typically added in PHP in a few cases:
magic_quotes are turned on. This is an old PHP feature which has been removed. The basic idea is that PHP used to auto-escape quotes in incoming requests to let you just cram incoming strings into a db. Guess what? NOT SAFE.
add_slashes has been called. Why call this? Some folks use it as an incorrect means of escaping data before sticking stuff in a db. Others use it to keep HTML from breaking when echoing variables out (htmlspecialchars should probably be used instead). It can also come in handy in a variety of other meta situations when you are defining code in a string.
When escaping data input. The most common escaping function is mysqli_real_escape_string. It's very important to escape values before inserting them in a db to prevent sql injection and other exploits but you should never escape things twice.
So there's a possibility that your code is double-escaping things or that addslashes is getting called or something like magic_quotes is causing the problem, but I suspect it is another problem: some JS code might be supplying this JSON not as a proper JSON string, but one that has been escaped so to define a string within javascript.
If you take your example JSON string above, and slap some quotes around it:
var myJSON = "<put your string here>";
then SURPRISE your javascript is not broken and the var myJSON contains a string that is actually valid JSON and can be parsed into an a valid JSON object:
var myJSON = "{\"id\":2335,\"editor\":{\"selected_shape\":\"spot-7488\"},\"general\":{\"name\":\"HTML Test\",\"shortcode\":\"html-test\",\"width\":1280,\"height\":776},\"spots\":[{\"id\":\"spot-7488\",\"x\":9.9,\"y\":22.6,\"default_style\":{\"use_icon\":1},\"tooltip_content\":{\"content_type\":\"content-builder\",\"plain_text\":\"<p class=\\\"test\\\">Test</p>\",\"squares_json\":\"{\\\"containers\\\":[{\\\"id\\\":\\\"sq-container-293021\\\",\\\"settings\\\":{\\\"elements\\\":[{\\\"settings\\\":{\\\"name\\\":\\\"Paragraph\\\",\\\"iconClass\\\":\\\"fa fa-paragraph\\\"},\\\"options\\\":{\\\"text\\\":{\\\"text\\\":\\\"<p class=\\\\\\\"test\\\\\\\">Test</p>\\\"}}}]}}]}\"}}]}";
console.log(JSON.parse(myJSON)); // this is an actual object
The key here is to examine the point of entry where this JSON arrives in your system. I suspect some AJAX request has created some object and rather than sending valid JSON Of that object, it is sending instead an escaped string of a JSON object.
EDIT:
Here's a simple example of what happens when you have too many encodings. Try running this JS in your browser and observe the console output:
var myObj = {"key":"here is my value"};
console.log(myObj);
var myJSON = JSON.stringify(myObj);
console.log(myJSON);
var doubleEncoded = JSON.stringify(myJSON);
console.log(doubleEncoded);

XML to HTML function for Refreshing Information

I am making a real time train board that pulls XML data from a website, populates it and animates it in. I have laid it out and got the animation set, but now I need help getting the XML data in the right spots.
Codepen of the animation: http://codepen.io/Spiderian/pen/FBjhk
The XML I'm trying to populate and recheck it every so often.
<trains>
<line><name>2</name><status>GOOD</status><text/><Date/><Time/></line>
<line><name>3</name><status>DELAYS</status><text/><Date/><Time/></line>
<line><name>4</name><status>WORK</status><text/><Date/><Time/></line>
<line><name>5</name><status>GOOD</status><text/><Date/><Time/></line>
</trains>
Will I have to use something different for the .append function to get it to work with the XML?
jQuery will work fine with XML, too. I will focus on the parsing of it in this answer, since I assume you're already familiar with fetching the XML from whatever web service you use with AJAX.
Create a new jQuery object with the XML, and then use the typical selectors to parse it. For example, to get the service on the first line, you can use the following:
var stats = xml.find('line:first status').text();
Here's how you can create a new jQuery object from XML:
var xml = $('<trains>\
<line><name>2</name><status>GOOD</status><text/><Date/><Time/></line>\
<line><name>3</name><status>DELAYS</status><text/><Date/><Time/></line>\
<line><name>4</name><status>WORK</status><text/><Date/><Time/></line>\
<line><name>5</name><status>GOOD</status><text/><Date/><Time/></line>\
</trains>');
Once you have the value from the XML, you can use either text() or html() to add it to your existing markup.
jsFiddle Demo

Is there a better way of creating elements and appending text to/around them?

I currently have a bunch of lines that look like:
txt = "Can't print the value for <span class='keyword'>"+arguments[1]+"</span> before it's set";
I'm then doing
$('#mydiv').append($('<div/>').html(txt));
This looks terrible and I need to escape any html inside arguments[1]
The only alternative I can think of is to make sure all the text is inside its own element:
var spans = [];
spans[0] = $('<span/>').text("Can't print the value for ");
spans[1] = $('<span/>').text(arguments[1]).className('keyword');
spans[2] = $('<span/>').text(" before it's set");
$('#mydiv').append($('<div/>').append(spans[0],spans[1],spans[2]));
This is quite a lot for just a simple line of text. Is there anything else I can do?
edit: This isn't something that should be handled by a templating engine. It's html generated by a javascript logging function.
If It's a consistent format, I'd add it as a normal string and then do a search for the keyword part.
$('<div/>')
.appendTo('#mydiv')
.html("Can't print the value for <span class='keyword'></span> before it's set")
.find('.keyword').text(arguments[1]);
If you will be continuing to create lots of HTML using JS, I would suggest working with a templating library. I am a recent convert, it took me a long time to understand the point. But seeing many successful sites (twitter,github,etc.) and the great John Resig promote and/or make heavy use of templating, i'm glad I stuck with trying to understand. Now I get it. It's for separation of concerns, keeping logic out of the view.
I'm using this very bare bones templating library: http://blueimp.github.com/JavaScript-Templates/ though the templating provided by underscore.js and mustache.js are more popular.
The advantage of the library i'm using is its really small, <1kb and is basically like writing php/asp code if you are familiar with those.
you can write HTML inside <script> tags without having to escape:
using your variable, txt, the syntax looks like this:
<script>
var data={txt : "Can't print the value for <span class='keyword'>"+arguments[1]+"</span> before it's set"};
<div>{%=o.txt%}</div>
</script>

Categories

Resources