'for' loop not looping through object array properly - javascript

When I run the very simple following code, for some reason I get the following result in the browser console: "6 You have not watched undefined undefined." Can anyone point out my error please?
var movies = [{
title: "The Mummy",
hasWatched: true,
stars: "5 stars"
},
{
title: "About A Boy",
hasWatched: true,
stars: "5 stars"
},
{
title: "It",
hasWatched: false,
stars: "5 stars"
},
{
title: "Cleopatra",
hasWatched: false,
stars: "5 stars"
}
];
for (var i = 0; i <= movies.length; i++) {
if (movies.hasWatched) {
console.log("You have watched " + movies.title + " " + movies.stars + ".");
} else {
console.log("You have not watched " + movies.title + " " + movies.stars + ".");
}
}

You have an array of objects so you need to reference the index of each array element. You also need to reduce your loop by one since array indexes are zero-based but the length is not.
var movies = [{
title: "The Mummy",
hasWatched: true,
stars: "5 stars"
},
{
title: "About A Boy",
hasWatched: true,
stars: "5 stars"
},
{
title: "It",
hasWatched: false,
stars: "5 stars"
},
{
title: "Cleopatra",
hasWatched: false,
stars: "5 stars"
}
];
for (var i = 0; i < movies.length; i++) {
if (movies[i].hasWatched) {
console.log("You have watched " + movies[i].title + " " + movies[i].stars + ".");
} else {
console.log("You have not watched " + movies[i].title + " " + movies[i].stars + ".");
}
}

Change the for condition to i < movies.length; you have one extra iteration.
And you also need to references movies[i] to get the actual movie, for example, movies[i].title.
In the above example, the last index is 3 (items are numbered 0, 1, 2, 3), but your loop is going until 4 and will attempt to find movies[4].title and return undefined.

for (var i = 0; i <= movies.length; i++) {
if (movies[i].hasWatched) {
console.log("You have watched " + movies[i].title + " " + movies[i].stars + ".");
} else {
console.log("You have not watched " + movies[i].title + " " + movies[i].stars + ".");
}
}
you were just missing the index identifier while accessing

Related

Is there a way to display JSON data while updating a DOM from the list?

I have JSON data that I would like to display one record after the other. Displaying one record as shown below then after say 5 seconds, the next record is displayed on DOM update.
How can I achieve this? Something like when using Carousel.
That is:
A Centre 0 Then next B Centre 2
A Centre 0 B Centre 0
let data = [
{
"facility_name_lims":"A Center",
"process_delay":0,
"lost_misplaced":0
},
{
"facility_name_lims":"B Center",
"process_delay":2,
"lost_misplaced":0
},
{
"facility_name_lims":"C Clinic",
"process_delay":55,
"lost_misplaced":0
},
{
"facility_name_lims":"D Center",
"process_delay":5,
"lost_misplaced":0
},
{
"facility_name_lims":"E Centre",
"process_delay":1,
"lost_misplaced":0
}
];
$.each(data, function (i, item) {
$("#ProcessingDelay").html(item.facility_name_lims + " " + item.process_delay);
$("#LostMisplaced").html(item.facility_name_lims + " " + item.lost_misplaced);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Display one record from the JSON then update the next from the records.</p>
<div id="ProcessingDelay"> Processing Delay</div>
<div id="LostMisplaced"> Lost Misplaced</div>
Google: js settimeout vs setinterval.
let data = [{
"facility_name_lims": "A Center",
"process_delay": 0,
"lost_misplaced": 0
},
{
"facility_name_lims": "B Center",
"process_delay": 2,
"lost_misplaced": 0
},
{
"facility_name_lims": "C Clinic",
"process_delay": 55,
"lost_misplaced": 0
},
{
"facility_name_lims": "D Center",
"process_delay": 5,
"lost_misplaced": 0
},
{
"facility_name_lims": "E Centre",
"process_delay": 1,
"lost_misplaced": 0
}
];
var i = 0;
var intervalID = setInterval(function() {
$("#ProcessingDelay").html(data[i].facility_name_lims + " " + data[i].process_delay);
$("#LostMisplaced").html(data[i].facility_name_lims + " " + data[i].lost_misplaced);
i++;
if (i === data.length) {
clearInterval(intervalID);
}
}, 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="ProcessingDelay"> Processing Delay</div>
<div id="LostMisplaced"> Lost Misplaced</div>

How to display nested JSON object in the form of table and rest JSON value as simple text

I want to display nested JSON objects.
This is what I have done so far:
orders = [
{ "custname": "Jack Smith", "mobile": "425361434", "location": "Sector 14", "slot": "12PM2PM", "value": 72.6, "items": [{ "prodcode": "PEP122", "quantity": 2 }, { "prodcode": "COK238", "quantity": 4 }] },
{ "custname": "Mary Gomes", "mobile": "723476123", "location": "Sector 22", "slot": "4PM6PM", "value": 130.60, "items": [{ "prodcode": "SUN677", "quantity": 2 }, { "prodcode": "LUX831", "quantity": 4 }, { "prodcode": "DET810", "quantity": 1 }] },
{ "custname": "Tim May", "mobile": "835099614", "location": "Pioneer Chowk", "slot": "Before 10AM", "value": 705, "items": [{ "prodcode": "GAR004", "quantity": 6 }, { "prodcode": "RB0277", "quantity": 3 }, { "prodcode": "MIR411", "quantity": 2 }] }
];
function showAllOrder() {
showtable();
}
function showtable() {
for (var i = 0; i < orders.length; i++) {
order = orders[i];
var str = "<div><div class='cell22' onclick=clicked(0)>Product</div>";
str = str + "<div class='cell22' onclick=clicked(1)>Qantity</div>";
var len = orders[i].items.length;
for (var j = 0; j < len; j++) {
for (var x = 0; x <)
//this value as simple text form above the table
var cost = ("Coustomer Name :" + order.custname);
var mob = (" Mobile :" + order.mobile);
var loc = (" Location :" + order.location);
var del = (" Delivery Slot :" + order.slot);
//this value in the form of table
var prod1 = "<div class='cell11'>" + orders[i].items[j].prodcode + "</div>";
var qty1 = "<div class='cell11'>" + orders[i].items[j].quantity + "</div>";
var row = "<div>" + cost + mob + loc + del + prod1 + qty1 + "</div>";
str = str + row;
}
}
var element = document.getElementById("mytable01");
element.innerHTML = str;
}

Parse JSON dynamically and print key values on html with input checkbox and get a new JSON of selected keys

I am trying to parse an unknown JSON whose format could be anything. So, I dont know the keys to access it. I want to access every key in JSON and print out all keys and values on screen using HTML. So I made a recursive function to access every key in JSON and used a variable name html to print the keys.
here`s the code:
JSON String:
{
"FetchDetails": {
"TransactionDetails": {
"ServiceName": "Airtel Mobile Bill Postpaid",
"officeID": "209",
"BillAmount": "931.00",
"ConsumerName": "Chetan Kumar Yadav",
"consumerKeysValues": "9352423664",
"partPaymentAllow": "1",
"partPaymentType": "Both",
"lookUpId": "6163298",
"officeCodeValue": "RATNC011"
},
"BillDetails": [{
"LableName": "Amount Before Due Date",
"LableValue": "931.00"
}, {
"LableName": "Due Date",
"LableValue": "NA"
}, {
"LableName": "Mobile Number",
"LableValue": "9352423664"
}, {
"LableName": "Amount After Due Date",
"LableValue": "931.00"
}, {
"LableName": "Bill Date",
"LableValue": "NA"
}, {
"LableName": "Consumer Name",
"LableValue": "Chetan Kumar Yadav"
}, {
"LableName": "Bill Cycle",
"LableValue": "NA"
}, {
"LableName": "Bill Number",
"LableValue": "NA"
}, {
"LableName": "Account Number",
"LableValue": "1116231291"
}]
}
}
Heres the code to access every key in Parsed JSON
function scan(info) {
var sub_root = [];
if (info instanceof Object) {
for (k in info) {
if (info.hasOwnProperty(k)) {
console.log('scanning property ' + k);
if (info[k] instanceof Object) {
me += "<div class='root'> <div class='sub_root'> <input class='node' name='sub_root[" + k + "]' value='" + k + "' type='checkbox' />" + k;
console.log(k);
counter++;
scan(info[k]);
me += "</div>";
me += "</div>";
} else {
me += "<div class='json_check' ><input class='node' name='sub_root[" + y + "] [" + k + "]' value='" + k + "' type='checkbox' />" + k + ": " + info[k] + " </div>";
scan(info[k]);
counter++;
}
}
}
} else {
console.log('found value : ' + info);
}
}
After this, I am able to access every key in JSON and printed every node in a nested form with checkboxes in front of them to select any node/key.
Here`s the screenshot:
[PROBLEM to be solved]
Now at the bottom, I have a submit button, when I click on it I want to form a JSON of checked values with their parent nodes. So like if I check a key with a value, I should get its parent keys along with it.
For example: I have selected ServiceName and officeID in TransactionDetails, and some array values in BillDetails, so I should get something like this
{
"FetchDetails": {
"TransactionDetails": {
"ServiceName": "Airtel Mobile Bill Postpaid",
"officeID": "209"
},
"BillDetails": [{
"LableName": "Amount Before Due Date",
"LableValue": "931.00"
}, {
"LableName": "Due Date",
"LableValue": "NA"
}, {
"LableName": "Account Number",
"LableValue": "1116231291"
}]
}
}
[EDITED]
To get this JSON format and traverse through HTML objects I am writing this code:
$('#btn_createservice').on('click', function() {
var solid = '{';
var input = $('input').is(':checked');
if(input){
input = $('input');
}
$('.node:checked').each(function(index) {
var parentEls = $(this).closest(input)
.map(function() {
solid += this.value;
return this.value;
})
.get()
.join( ", " );
console.log(parentEls);
});
solid += '}';
$( ".submit_json" ).html(solid);
});
You need to use .parents(), not .closest() so you get all the containing elements.
Then create containing properties with those names when necessary.
$("#btn_createservice").on("click", function() {
var svc_obj = {};
$(".node:checked").each(function() {
var cur_obj = svc_obj;
$(this).parents(".node").map(function () {
return this.value;
}).get().reverse().forEach(function(name) {
if (!cur_obj[name]) { // create property if it doesn't already exist
cur_obj[name] = {};
}
cur_obj = cur_obj[name]; // use this for next iteration;
});
var thisname = this.name.match(/\[([^[])+\]$/)[1]; // Get property name from name="sub_root[...]"
cur_obj[thisname] = this.value;
});
$(".submit_json").html(JSON.stringify(svc_obj));
})
You need to fix the HTML you're creating so that the checkboxes have value='" + info[k] "'.

JSON & Dynamic jQuery Mobile Listview

I have a JSON file that contains an array of 3 objects.
When I want to display an object's attribute it display the name of it, for instance if I have an object car that has an attribute called name and has the value "FIAT" when I write car.name it displays " CAR.NAME " on the the listview instead of FIAT.
Here's my code.
$.getJSON("res/jsonFile/produits.json", function(products) {
$('#productList').empty();
$.each(products, function(i, product) {
$('#productList').append(productLink(product));
});
$('#productList').listview('refresh');
});
function productLink(product) {
var link="<li>" +
"<img src=product.pic>" +
"" +
"<h2>product.name</h2>" +
"<p>product.desc</p>" +
"<p>product.price</p>" +
"</li>";
return link;
}
and here's my JSON file
[
{
"name": "Coca Cola",
"desc": "Coca Cola",
"price": 10,
"qty": 100,
"pic": "img/coca cola.jpg"
},
{
"name": "Fanta",
"desc": "Fanta mini",
"price": 10,
"qty": 100,
"pic": "img/fanta.jpg"
},
{
"name": "Salade niçoise",
"desc": "Salade",
"price": 15,
"qty": 100,
"pic": "img/nicoise.jpg"
}
]
In your function you're printing the variable names, not their values. Use it like this instead:
function productLink(product) {
var link="<li>" +
"<img src=" + product.pic + ">" +
"<h2>" + product.name + "</h2>" +
"<p>" + product.desc + "</p>" +
"<p>" + product.price + "</p>" +
"</li>";
return link;
}

Jasmine Test for Sorting Function

I have some example data:
var jasmineData = [
{
"carrierName": "Mario Bros",
"planName": "Rainbow Road",
"copay": 100,
"premium": 200,
"annualLimit": 100000
},
{
"carrierName": "Mega Man",
"planName": "Dr. Whiley",
"copay": 250,
"premium": 1000,
"annualLimit": 250000
}
]
And a function that adds this data into a table:
function addDataToTable(jasmineData) {
for(var plan in jasminenData){
var endOfTable = $('.headers').after();
endOfTable.append($('<tr class="remove_for_intial_sort"><td>' + jasminenData[plan].carrierName + '</td><td>' + jasminenData[plan].planName + '</td><td>'
+ jasminenData[plan].copay +'</td><td>' + jasminenData[plan].premium + '</td><td>' + jasminenData[plan].annualLimit + '</td></tr>'))
}
};
Does anyone know a good way to approach this for testing? I was going to test the length of $('headers') but that didn't work.

Categories

Resources