1

I have a JS object like this:

{
 promo_name: "value",
 discount_type: "value",
 discount: "value",
 products: [
 { id: 1, name: 'name'},
 { id: 2, name: 'name'}, 
 ]
}

My objective is to display the results in a view. My problem is that I do not know how to iterate over an array inside an object.

The data is coming from an Ajax request and then parsed into a JS object.

I am using jQuery $.each to iterate over the res object and display property values like this:

$.each(res, function (key, value) {
 $("#coupon_data").show();
 $("#coupon_details").html(
 '<div class="alert alert-success">' +
 '<h4>Promotion Details</h4>' +
 '<hr>' +
 '<p>Promotion: ' + res.promo_name + '</p>' +
 '<p>Discount type: ' + res.discount_type + '</p>' +
 '<p>Amount: ' + res.discount + '%</p>' +
 '</div>'
 );
});

The three properties (res.promo_name, res.discount_type, res.discount) display, but because the array length varies I cannot display its values like this:

res.products[0].name res.products[1].name

I believe that I need to loop over the array that's inside the object and display the number of elements it might contain. This is where I am stuck.

benvc
15.2k4 gold badges39 silver badges57 bronze badges
asked Oct 24, 2018 at 18:48
2
  • 1
    $.each(res.products, function(index, val) { ....... } Commented Oct 24, 2018 at 18:51
  • 1
    if you just need a count, no need to loop: res.products.length Commented Oct 24, 2018 at 18:54

7 Answers 7

1

If you need to get the count, use the attribute length from Array

var count = res.products ? res.products.length : 0;

Something like this:

var res = {
 promo_name: "value",
 discount_type: "value",
 discount: "value",
 products: [{id: 1,name: 'name'},
 {id: 2,name: 'name'}]
};
$.each(res, function(key, value) {
 $("#coupon_data").show();
 $("#coupon_details").html(
 '<div class="alert alert-success">' +
 '<h4>Promotion Details</h4>' +
 '<hr>' +
 '<p>Promotion: ' + res.promo_name + '</p>' +
 '<p>Discount type: ' + res.discount_type + '</p>' +
 '<p>Amount: ' + res.discount + '%</p>' +
 '<p>Products: ' + (res.products ? res.products.length : 0) + '</p>' +
 '</div>'
 );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='coupon_details'></div>

If you need to show the count + product details:

var res = {
 promo_name: "value",
 discount_type: "value",
 discount: "value",
 products: [{id: 1,name: 'name1'},
 {id: 2,name: 'name2'}]
};
$.each(res, function(key, value) {
 $("#coupon_data").show();
 var html = '<div class="alert alert-success">' +
 '<h4>Promotion Details</h4>' +
 '<hr>' +
 '<p>Promotion: ' + res.promo_name + '</p>' +
 '<p>Discount type: ' + res.discount_type + '</p>' +
 '<p>Amount: ' + res.discount + '%</p>' +
 '<p>Products: ' + (res.products ? res.products.length : 0) + '</p><p>Details:</p>';
 
 if (res.products) {
 for (var i = 0, {length} = res.products; i < length; i++) {
 html += '<p><b>Name:</b>' + res.products[i].name + '</p>';
 }
 }
 
 $("#coupon_details").html(html);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='coupon_details'></div>

answered Oct 24, 2018 at 18:54

2 Comments

wouldn't [].map() make more sense to transform the data?
Thank you very much Ele. Great work! Yes, I wanted to display the products as a list. Your code looks great. I especially like how you created an html variable. Thanks for your help!
0

Outside of a regular for loop, you can also use Array.forEach

var products = [
 { id: 123, name: 'name1',
 { id: 456, name: 'name2'
]
products.forEach(function(product) {
 // do something with each product...
})

answered Oct 24, 2018 at 18:55

Comments

0

There are some typos with your object.

{
 promo_name: "value",
 discount_type: "value",
 discount: "value",
 products: [
 { id: 1, name: 'name'},
 { id: 2, name: 'name'}, 
 ]
}

Example on how to get the length of the array within the object:

var myObj = {
 promo_name: "value",
 discount_type: "value",
 discount: "value",
 products: [
 { id: 1, name: 'name'},
 { id: 2, name: 'name'}, 
 ]
};
//length of products
myObj.products.length;
//one product
myObj.products[0];
//id of one product:
myObj.products[0].id;
answered Oct 24, 2018 at 18:55

Comments

0

First, you can get this to be a little more performant by using a JS-equivalent of a StringBuilder, which is an array, like:

var h = [
 '<div class="alert alert-success">',
 '<h4>Promotion Details</h4>',
 ...
];
$("#coupon_details").html(h.join(''));

Second, rather than call $.each() where you have, you need to just call $.each on the property, which is an array, like:

$.each(res.products, function(i, product) {
 h.push('<div class=product>', product.name, '</div>');
});
answered Oct 24, 2018 at 18:58

Comments

0

You do not need to iterate through res object, because there is nothing to iterate and it's not iterable, instead you should iterate your res.products array

 $("#coupon_data").show();
 $("#coupon_details").html(
 '<div class="alert alert-success">' +
 '<h4>Promotion Details</h4>' +
 '<hr>' +
 '<p>Promotion: ' + res.promo_name + '</p>' +
 '<p>Discount type: ' + res.discount_type + '</p>' +
 '<p>Amount: ' + res.discount + '%</p>' 
 );
 $.each(res.products, function (key, value) {
 $("#coupon_details").append('<p>Product name: ' + value.name + '</p>');
 });
 $("#coupon_details").append('</div>');
answered Oct 24, 2018 at 18:58

Comments

0

You can do something like below:

$.each(res, function (key, value) {
 $("#coupon_data").show();
 var productElements = '' // to store product elements
 // iterate product elements, you can use for loop also 
 res.products.map((product) => {
 var {id, name} = product;
 productElements += `<p> *any thing you want to use(${id} or ${name})* </p>\n` // html element for product items as string
 })
 $("#coupon_details").html(
 '<div class="alert alert-success">' +
 '<h4>Promotion Details</h4>' +
 '<hr>' +
 '<p>Promotion: ' + res.promo_name + '</p>' +
 '<p>Discount type: ' + res.discount_type + '</p>' +
 '<p>Amount: ' + res.discount + '%</p>' +
 `${productElements}` //final product items
 '</div>'
 );
});
answered Oct 24, 2018 at 19:04

Comments

0

Given your starting point, I'd reduce the array into a string representation of all the elements.

I'm also using ES6 an arrow function and template syntax to make things a little more concise. Also, as others have noted, you don't need $.each to iterate an object, so I've removed that.

const res = {
 promo_name: "value",
 discount_type: "value",
 discount: "value",
 products: [
 { id: 1, name: 'name'},
 { id: 2, name: 'name'}, 
 ]
}
$("#coupon_data").show();
$("#coupon_details").html(
 '<div class="alert alert-success">' +
 '<h4>Promotion Details</h4>' +
 '<hr>' +
 '<p>Promotion: ' + res.promo_name + '</p>' +
 '<p>Discount type: ' + res.discount_type + '</p>' +
 '<p>Amount: ' + res.discount + '%</p>' +
 '<p>Products: <ul>' +
 res.products.reduce((accum,curVal) => `${accum}<li>${curVal.id}: ${curVal.name}</li>`,'') +
 '</ul></p>' +
 '</div>'
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="coupon_data">
 <div id="coupon_details">
 
 </div>
</div>

Ele
33.8k7 gold badges43 silver badges80 bronze badges
answered Oct 24, 2018 at 18:59

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.