jQuery each() breaking on null - javascript

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){
//..
}

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/

Sails.js Waterline UPDATE: How to handle multiple updates

I have an array of objects that I want to update, thus a multiple update. I am looking for the best way to implement this. Each object includes the same properties, but the properties for each object have different values.
Do I implement something like this?
var people = [
{'firstName': 'Brian', 'clockedIn': '2016-4-12', 'type': 'developer'},
{'firstName': 'Taylor', 'clockedIn': '2016-4-14', 'type': 'developer'},
{'firstName': 'Jake', 'clockedIn': '2016-4-14', 'type': 'manager'}
];
PersonModel.update({'type': 'developer'}, people, function(err, records) {
// ...
// ...
});
If I do something like the previous code, what exactly does it do? Does it automatically try to match the primary key of each record in the people array, update any of the properties that are listed, and then pass the records that were updated into the callback function?
I noticed in the Sails.js documentation here that the second argument for the update function can be an object OR an array, I am just unclear if I can use it like this. The documentation is unclear.
If I cannot use it like this and I wanted to try an iterative or recursive approach, how would you suggest I implement it?
What is your adapter ?
I had to do this with MySQL, I make the query my self, and then call PersonModel.query(myQuery)
I follow this answer to make it (example with two field) :
values = [
{
id: 1,
param_1: 'NewValueParam1',
param_2: 'NewValueParam2'
},
{
id: 2,
param_1: 'AnotherNewValueParam1',
param_2: 'AnotherNewValueParam2'
}
];
function multiValuesUpdate(values) {
var request = "UPDATE MyTable SET ";
var part_param_1 = "`param_1` = (CASE `id` ";
var part_param_2 = "`param_2` = (CASE `id` ";
var part_ids = "WHERE `id` IN (";
_.forEach(values, function (v) {
part_param_1 += "WHEN '" + v.id + "' THEN '" + v.param_1 + "' ";
part_param_2 += "WHEN '" + v.id + "' THEN '" + v.param_2 + "' ";
part_ids += v.id + ",";
});
part_param_1 += "ELSE `param_1` END), "; // Be careful with the comma !
part_param_2 += "ELSE `param_2` END) ";
part_ids = part_ids.slice(0, -1) + ");"; // Remove the last "," and add ");"
request += part_param_1 + part_param_2 + part_ids;
return request;
}
console.log(multiValuesUpdate(values));
Output :
"UPDATE MyTable
SET `param_1` = (
CASE `id`
WHEN '1' THEN 'NewValueParam1'
WHEN '2' THEN 'AnotherNewValueParam1'
ELSE `param_1`
END),
`param_2` = (
CASE `id`
WHEN '1' THEN 'NewValueParam2'
WHEN '2' THEN 'AnotherNewValueParam2'
ELSE `param_2`
END)
WHERE `id` IN (1,2);"

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.

displaying json data in javascript not working

I have created a var and passed JSON data(comma seperated values) to it, but when I want to display json data - it only returns null. Here's the code:
<script type="text/javascript">
var data1 = [
{order:"145",country:"Dubai",employee:"permanent",customer:"self"}
];
document.write(data1);
</script>
You can either do it like this:
var data1 = [{order:"145",country:"Dubai",employee:"permanent",customer:"self"} ];
data1.forEach(function(data){
document.write(data.order);
document.write(data.country);
document.write(data.employee);
document.write(data.customer);
});
or you can do it like this
var data1 = [
{order:"145",country:"Dubai",employee:"permanent",customer:"self"}
];
$.each(data1[0], function(key, value){
document.write(key + " " + value);
});
Either way, storing just one object in the list makes this answer a bit redundant unless I show you how to loop over multiple objects.
var data1 = [
{order:"145",country:"Dubai",employee:"permanent",customer:"self"},
{order:"212",country:"Abu-Dhabi",employee:"permanent",customer:"Tom"}
];
data1.forEach(function(data){
$.each(data, function(key, value){
document.write(key+" "+value);
});
});
I'm using a mix of jQuery here aswell, which might not be optimal but atleast it serves to show that there are multiple ways to accomplishing what you need.
Also, the forEach() method on arrays is a MDN developed method so it might not be crossbrowser compliant, just a heads up!
If you want pure JS this is one of the ways to go
var data1 = [
{order:"145",country:"Dubai",employee:"permanent",customer:"self"},
{order:"212",country:"Abu-Dhabi",employee:"permanent",customer:"Tom"}
];
for(json in data1){
for(objs in data1[json]){
document.write(objs + " : " + data1[json][objs]);
}
}
For simple and quick printing of JSON, one can do something like below and pretty much same goes for objects as well;
var json = {
"title" : "something",
"status" : true,
"socialMedia": [{
"facebook": 'http://facebook.com/something'
}, {
"twitter": 'http://twitter.com/something'
}, {
"flickr": 'http://flickr.com/something'
}, {
"youtube": 'http://youtube.com/something'
}]
};
and now to print on screen, a simple for in loop is enough, but please not e, it won't print array instead will print [object Object]. for simplicity of answer, i won't go in deep to print arrays key and value in screen.
Hope that this will be usefull for someone. Cheers!
for(var i in json) {
document.writeln('<strong>' + i + '</strong>' +json[i] + '<br>');
console.log(i + ' ' + json[i])
}

Get key and value of object in JavaScript?

Given a JavaScript array of objects, how can I get the key and value of each object?
The code below shows what I'd like to do, but obviously doesn't work:
var top_brands = [ { 'Adidas' : 100 }, { 'Nike' : 50 }];
var brand_options = $("#top-brands");
$.each(top_brands, function() {
brand_options.append($("<option />").val(this.key).text(this.key + " " + this.value));
});
So, how can I get this.key and this.value for each entry in the array?
Change your object.
var top_brands = [
{ key: 'Adidas', value: 100 },
{ key: 'Nike', value: 50 }
];
var $brand_options = $("#top-brands");
$.each(top_brands, function(brand) {
$brand_options.append(
$("<option />").val(brand.key).text(brand.key + " " + brand.value)
);
});
As a rule of thumb:
An object has data and structure.
'Adidas', 'Nike', 100 and 50 are data.
Object keys are structure. Using data as the object key is semantically wrong. Avoid it.
There are no semantics in {Nike: 50}. What's "Nike"? What's 50?
{key: 'Nike', value: 50} is a little better, since now you can iterate an array of these objects and values are at predictable places. This makes it easy to write code that handles them.
Better still would be {vendor: 'Nike', itemsSold: 50}, because now values are not only at predictable places, they also have meaningful names. Technically that's the same thing as above, but now a person would also understand what the values are supposed to mean.
$.each(top_brands, function() {
var key = Object.keys(this)[0];
var value = this[key];
brand_options.append($("<option />").val(key).text(key + " " + value));
});
If this is all the object is going to store, then best literal would be
var top_brands = {
'Adidas' : 100,
'Nike' : 50
};
Then all you need is a for...in loop.
for (var key in top_brands){
console.log(key, top_brands[key]);
}
$.each(top_brands, function(index, el) {
for (var key in el) {
if (el.hasOwnProperty(key)) {
brand_options.append($("<option />").val(key).text(key+ " " + el[key]));
}
}
});
But if your data structure is var top_brands = {'Adidas': 100, 'Nike': 50};, then thing will be much more simple.
for (var key in top_brands) {
if (top_brands.hasOwnProperty(key)) {
brand_options.append($("<option />").val(key).text(key+ " " + el[key]));
}
}
Or use the jquery each:
$.each(top_brands, function(key, value) {
brand_options.append($("<option />").val(key).text(key + " " + value));
});
for (var i in a) {
console.log(a[i],i)
}
Object.keys(top_brands).forEach(function(key) {
var value = top_brands[key];
// use "key" and "value" here...
});
Btw, note that Object.keys and forEach are not available in ancient browsers, but you should use some polyfill anyway.

Categories

Resources