Parse JSON with JavaScript to build a HTML string - javascript

I currently have built an API which posts JSON strings of objects. A simple example of the JSON is:
[ {
"id" : 0,
"name" : "test SAMPLE Att1 name",
"attributes" : [ {
"id" : -1,
"name" : "AttKey1",
"value" : "AttValue1"
}, {
"id" : -1,
"name" : "AttKey2",
"value" : "AttValue2"
} ]
} ]
My issue lies in my client code here:
function loadSamples() {
$("#content").children().remove();
$.getJSON("/api/samples", function (data) {
$.each(data, function (key, val) {
$("<tr><td>" + val.id + "</td><td>" + val.name + "</td><td>" + val.attributes + "</td>" +
"</tr>").appendTo("#content");
});
initCallbacks();
});
}
I am iterating through each sample I send (in this case only one, and appending the field values to the HTML string. How can I iterate through attributes and append each attribute.key and attribute.value to the string?
A picture of the current problem:

You can try to use this code instead of val.attributes
$.map(val.attributes, function(item){
return item.key + ':' +item.value;
}).join(',')

Use another loop, iterate through all attributes, build an array of attributes in format "property: value" and then append joined array to HTML:
$.each(data, function (key, val) {
var attributes = [];
for (var prop in val.attributes) {
var value = val.attributes[prop];
attributes.push(prop + ": " + value);
}
$("<tr><td>" + val.id + "</td><td>" + val.name +
"</td><td>" + attributes.join(",") + "</td>" + "</tr>").appendTo("#content");
});

If you feel nerdy you can just serialize the object back into a JSON string like this:
... + JSON.stringify(val.attributes) + ...
It is recursive, has a standard syntax (JSON) and doesn't require any support function or additional code at all.

Related

Loop after Grouped JSON properties

https://jsfiddle.net/MauroBros/f1j0qepm/28/#&togetherjs=qedN5gf7SF
I have a JSON object as follows:
var values = [
{"aname":"account1", "pname":"pname1", "vname":"vname1", "vid":"xxx"},
{"aname":"account2", "pname":"pname2", "vname":"vname2", "vid":"xxx"},
{"aname":"account2", "pname":"pname2", "vname":"vname3", "vid":"xxx"},
{"aname":"account2", "pname":"pname3", "vname":"vname1", "vid":"xxx"},
]
I grouped the "vname" by "pname"
var groups = {};
$.each(values, function(key, values) {
if (!groups.hasOwnProperty(values.pname)) {
groups[values.pname] = {
aname : values.aname,
aid : values.aname,
pname : values.pname,
pid : values.pid,
vid: [],
vname: []
};
}
groups[values.pname].vname.push({
vname: values.vname,
vid: values.vid
});
});
Now I'm trying to loop:
$.each(groups, function(key, groups) {
$('#provider-accounts')
.append($("<optgroup></optgroup>")
.attr("label"," " + groups.aname))
.append($("<optgroup></optgroup>")
.attr("label"," " + groups.pname))
.append($("<option></option>")
.attr("value",groups.vid)
.text(" " + groups.vname[0].vname));
});
ISSUE
The output doesn't return all the options "vname" but only the first one.
How can I insert a loop in the loop. Something like this:
$.each(groups, function(key, groups) {
$('#provider-accounts')
.append($("<optgroup></optgroup>")
.attr("label"," " + groups.aname))
.append($("<optgroup></optgroup>")
.attr("label"," " + groups.pname))
for (var i = 0; i < groups.vname[0].vname.length; i++) {
.append($("<option></option>")
.attr("value",groups.vid)
.text(" " + groups.vname[0].vname[i]));
}
});
Any help?
Thanks
Instead of trying to chain it all into one chain I would create a separate object for the groups first. Then loop through the array and append the various options to the second group and finally append the groups to the select.
This seems to be easier to read also than the chained appends you are currently using
$.each(groups, function(key, groups) {
var $group1 = $("<optgroup>").attr("label", " " + groups.aname);
var $group2 = $("<optgroup>").attr("label", " " + groups.pname);
groups.vname.forEach(function(el) {
$group2.append(new Option(el.vname, el.vid));
});
$('#provider-accounts').append($group1, $group2);
});
#charlietfl's answer does it, and I agree that it would make your code more readable. But if you're still interested if such looping is possible - yes it is. You can use Array .map() for this and append the resulting array of Option elements.
.append(
groups.vname.map( vItem =>
$("<option></option>")
.attr("value",groups.vid)
.text(" " + vItem.vname)
));
I tried to fork your fiddle here: https://jsfiddle.net/b2yg5jvm/

How can I retrieve the JSON Object Array Value using JavaScript

My JSON Object Array is something like this:
var country = [{ id: "1", name:"ajith", country:"india"},
{ id: "2", name:"chandru", country:"india"},
{ id: "3", name:"gane", country:"india"}]
How can I retrieve these key and values?
And how can I display them in an html table?
Like so, just replace <tableIdHere> with your table's id
document.getElementById('<tableIdHere>').getElementsByTagName('tbody')[0].innerHTML =
country.map(v => `<tr><td>${v.id}</td><td>${v.name}</td><td>${v.country}</td></tr>`)
.join('');
Please note that arrow functions and template strings as used above are only available in modern browsers like latest chrome and firefox. You might want to use
document.getElementById('<tableIdHere>').getElementsByTagName('tbody')[0].innerHTML =
country.map(function(v) {
return '<tr><td>' + v.id + '</td><td>' + v.name + '</td><td>' + v.country + '</td></tr>';
}).join('');
if you need support for older browsers!

How to pass JSON value into a variable / function?

I am currently parsing a json file and appending the data to an HTML table. I need to create a few variables that equal 3 of the properties within my JSON object. And I need to include those variables in a function that I am appending to one of the td elements within the table for each of my JSON objects.
Here is my function to append the data...
function createPatientTable(json) {
$.each(json.LIST, function(i, COPD_QUAL) {
$('.footable > tbody:last').append('<tr><td>' + COPD_QUAL.PATIENT + '</td><td>' + COPD_QUAL.FIN + '</td><td>' + COPD_QUAL.NURSE_UNIT + '</td><td>' + COPD_QUAL.ROOM + '</td><td>' + COPD_QUAL.BED +'</td><td>' + COPD_QUAL.ATTENDING_PHYS + '</td><td>' + COPD_QUAL.LENGTH_OF_STAY + '</td><td class="assessment ' + getSeverity(COPD_QUAL.MED_ASSESS) + '" onclick="openPowerform">' + COPD_QUAL.MED_ASSESS + '</td></tr>');
});
$('.footable').footable();
};
Here is one of my JSON objects (formatted for readability):
{
"COPD_QUAL":15,
"LIST":[
{
"PATIENT": "TEST, TRICKLE",
"FIN": "70100905",
"NURSE_UNIT": "TIC",
"ROOM": "C219",
"BED": "A",
"ATTENDING_PHYS": "LEVITEN , DANIEL L",
"LENGTH_OF_STAY": "171days 02:14:15",
"MED_ASSESS": "Mild exacerbation",
"ACTIVITY_ID": "305675472.0000",
"PERSON_ID": 8986122.000000,
"ENCNTR_ID": 14150574.000000
}
]
}
I need to plug COPD_QUAL.PERSON_ID, COPD_QUAL.ENCNTR_ID, and COPD_QUAL.ACTIVITY_ID into my below function so when the td element is clicked, the below function triggers with the personid, encntrid, and activityid of the JSON object that has been appended to that row:
function openPowerform() {
var dPersonId = "COPD_QUAL.PERSON_ID";
var dEncounterId = "COPD_QUAL.ENCNTR_ID";
var formId = 0.0;
var activityId = "COPD_QUAL.ACTIVITY_ID";
var chartMode = 1;
var mpObj = window.external.DiscernObjectFactory("POWERFORM");
mpObj.OpenForm(dPersonId, dEncounterId, formId, activityId, chartMode);
};
How can I successfully make these variables "dynamically" equal my JSON values? (since the values are different per object/string within my JSON file).
Thanks in advance!
Your JSON is mal-formed. Here is a valid object:
{
"COPD_QUAL": 15,
"LIST": [
{
"PATIENT": "TEST, TRICKLE",
"FIN": "70100905",
"NURSE_UNIT": "TIC",
"ROOM": "C219",
"BED": "A",
"ATTENDING_PHYS": "LEVITEN , DANIEL L",
"LENGTH_OF_STAY": "171days 02:14:15",
"MED_ASSESS": "Mild exacerbation",
"ACTIVITY_ID": "305675472.0000",
"PERSON_ID": 8986122,
"ENCNTR_ID": 14150574
}
]
}
Each object within the LIST array has to be addressed by its array position. With this object, your object property references would be:
LIST[0].PERSON_ID, LIST[0].ENCNTR_ID, and LIST[0].ACTIVITY_ID
I don't know if this is how you want to structure your JSON in the end, but this is what you have now. Also, there is no absolute need to run this through JSON.parse(). It can be treated like a JavaScript Object Literal and accessed the same way.

Ajax and json issue

I have a little ajax call to load json data into the DOM but it's not working. When I look at the net tab I see that its loaded but no data is on the actual page. It just says [object Object]
$.getJSON('json/redstone.json', function(data) {
var items = [];
$.each(data, function(key, val) {
items.push('<li id="' + key + '">' + val + '</li>');
});
$('<ul/>', {
'class': 'my-new-list',
html: items.join('')
}).appendTo('body');
});
Here is my JSON
{
"allconfig": {
"card.inserted": {
"value": "Not Inserted",
"type": "enum",
"range": "",
"clone": false,
"archive": false,
"access": "R"
},
"card.cisproc": {
"value": "Processed",
"type": "string",
"range": "",
"clone": false,
"archive": false,
"access": "R"
},
"card.mfgid": {
"value": "",
"type": "string",
"range": "",
"clone": false,
"archive": false,
"access": "R"
}
}
}
val is actually an object in your JSON data. And if you do $.each over the data, you will only get the allconfig element. So you might want to enumerate over data.allconfig instead.
So you might want to display the val's value property instead, like this:
$.getJSON('json/redstone.json', function(data) {
var items = [];
$.each(data.allconfig, function(key, val) {
items.push('<li id="' + key + '">' + val.value + '</li>');
});
$('<ul/>', {
'class': 'my-new-list',
html: items.join('')
}).appendTo('body');
});
Here is a working jsFiddle
Another method you can try is iterating over the JSON object using regular javascript iteration, like so:
for(var key in data){
var value = data[key];
items.push('<li id="' + key + '">' + value + '</li>');
}
Edit: I just realized your data structure, as someone pointed out in the comments, has sub, or nested objects. My method, by itself, will only work for the first level of key:value pairs. If you'd like to make your iteration function a little more generic, you can use recursion to properly dive through your structure, like so:
function buildData(data){
for(var key in data){
var value = data[key];
if(typeof(value) == "object"){
nestedData = buildData(value);
items.push('<li id="' + key + '">' + nested + '</li>');
// I'm not sure how you want to handle your nested objects, so place
// here what you need and whatever else you need to do to handle
// your nested object situation.
}else{
items.push('<li id="' + key + '">' + value + '</li>');
}
}
}

jQuery each() breaking on null

I have a JSON object that I am looping over with each() to add table rows to a table. I can't ensure the completeness of the data presented in the JSON arrays and I occasionally run into some NULLs.
For instance:
// A GOOD ARRAY
{
id: "193",
location: {
city: "Atlanta",
state: "GA"
},
name: "John"
},
// NOW WE STUMBLE UPON A BAD ARRAY WITH A NULL
{
id: "194",
location: {
city: "Boise",
state: null
},
name: "Frank"
},
{...}
Now, when I am dealing with JSON objects that have no NULL values, the each() loops over with no problems. As soon as I encounter a member with NULL anywhere in the array, the looping breaks.
This is how I am looping over this:
$.getJSON("/getstuff/jsonprovider.php", function (data) {
var results = data.parentnode;
var tableThing = $(".myTable tbody");
var i = 0;
$.each(results, function () {
tableThing.append('<tr><td></td><td>' + results[i].id + '</td><td>' + results[i].name + '</td><td>' + results[i].location.city + ', ' + results[i].location.state + '</td></tr>');
i++;
});
});
Should I be investigating something other than each() here, or should I be using a completely different method?
Thank you
Since your data may have nulls, you need to make sure that the data exists before you attempt to use it. It is also more efficient to only use .append once. Below i'm using a default empty object and $.extend deep copy to ensure that the object we are pulling data from always has all data values defined, even if the value isn't in the json. I'm still not sure how null's will be handled at this point.
var emptyObj = {
id: "",
name: "",
location: {
city: "",
state: ""
}
},htmlToAppend = "";
$.each(results, function (i,obj) {
var newObj = $.extend(true,{},emptyObj,obj);
htmlToAppend += '<tr><td></td><td>' + newObj.id + '</td><td>' + newObj.name + '</td><td>' + newObj.location.city + ', ' + newObj.location.state + '</td></tr>';
});
tableThing.append(htmlToAppend);
The proper way to do a $.each is like this:
var myObj = {...};
$.each(myObj, function(k, v){
//..
});
You need two parameters above:
k holds the index or the key
v holds the value at that index or key
If you were going to use a counter variable like i you might as well use JavaScripts for in loop:
for(var i in myObj){
//..
}

Categories

Resources