skip to Main Content

I have an array of objects with

  1. image
  2. title
  3. price
  4. vendor

I am trying to set each data on a card. I think I’m not accessing the array correctly.

I have an undefined error, how can I solve it? I appreciate your help

const products = '[ { "user_id": "666", "products": [ { "id": "7109593301197", "name": "Product1", "img": "https://www.kasandbox.org/programming-images/avatars/spunky-sam.png", "handle": "handle1", "price": "111.0", "vendor": "Vendor1" }, { "id": "7076369957069", "name": "Product2", "img": "https://www.kasandbox.org/programming-images/avatars/purple-pi-pink.png", "handle": "handle2", "price": "85.0", "vendor": "Vendor2" }, { "id": "7182779154637", "name": "Product3", "img": "https://www.kasandbox.org/programming-images/avatars/mr-pants.png", "handle": "handle3", "price": "435.0", "vendor": "Vendor3" }] } ]';
const data = JSON.parse(products);
const cardElements = document.getElementsByClassName("related-prod-wrapper");

for (var i = 0; i < data.length; i++) {
  const currentCardElement = cardElements.item(i);
  const cardImage = currentCardElement.getElementsByClassName("image").item(0);
  cardImage.setAttribute("src", data[i].img);
}

const cardElements2 = document.getElementsByClassName("related-prod-detail");

for (var i = 0; i < data.length; i++) {
  const currentCardElement2 = cardElements2.item(i);

  const cardVendor = currentCardElement2.getElementsByClassName("vendor").item(0);
  cardVendor.innerHTML = data[i].vendor;

  const cardTitle = currentCardElement2.getElementsByClassName("title").item(0);
  cardTitle.innerHTML = data[i].name;

  const cardPrice = currentCardElement2.getElementsByClassName("precio").item(0);
  cardPrice.innerHTML = data[i].price;

}
<div class="med-product-card">
  <div class="related-prod-wrapper">
    <img class="image">
  </div>
  <div class="related-prod-detail">
    <h3 class="vendor">Vendor</h3>
    <h3 class="title">Card 1</h3>
    <h3 class="precio">Precio</h3>
  </div>
</div>

<div class="med-product-card">
  <div class="related-prod-wrapper">
    <img class="image">
  </div>
  <div class="related-prod-detail">
    <h3 class="vendor">Vendor</h3>
    <h3 class="title">Card 1</h3>
    <h3 class="precio">Precio</h3>
  </div>
</div>

<div class="med-product-card">
  <div class="related-prod-wrapper">
    <img class="image">
  </div>
  <div class="related-prod-detail">
    <h3 class="vendor">Vendor</h3>
    <h3 class="title">Card 1</h3>
    <h3 class="precio">Precio</h3>
  </div>
</div>

2

Answers


  1. The issue is because you’re attempting to loop over the data array. The information you’re looking for is actually in the products array in the 0th element of data. Therefore instead of data[i] you need to use data[0].products[i], like this:

    const products = '[ { "user_id": "666", "products": [ { "id": "7109593301197", "name": "Product1", "img": "https://www.kasandbox.org/programming-images/avatars/spunky-sam.png", "handle": "handle1", "price": "111.0", "vendor": "Vendor1" }, { "id": "7076369957069", "name": "Product2", "img": "https://www.kasandbox.org/programming-images/avatars/purple-pi-pink.png", "handle": "handle2", "price": "85.0", "vendor": "Vendor2" }, { "id": "7182779154637", "name": "Product3", "img": "https://www.kasandbox.org/programming-images/avatars/mr-pants.png", "handle": "handle3", "price": "435.0", "vendor": "Vendor3" }] } ]';
    const data = JSON.parse(products);
    const cardElements = document.getElementsByClassName("related-prod-wrapper");
    
    for (var i = 0; i < data[0].products.length; i++) {
      const currentCardElement = cardElements.item(i);
      const cardImage = currentCardElement.getElementsByClassName("image").item(0);
      cardImage.setAttribute("src", data[0].products[i].img);
    }
    
    const cardElements2 = document.getElementsByClassName("related-prod-detail");
    
    for (var i = 0; i < data[0].products.length; i++) {
      const currentCardElement2 = cardElements2.item(i);
    
      const cardVendor = currentCardElement2.getElementsByClassName("vendor").item(0);
      cardVendor.innerHTML = data[0].products[i].vendor;
    
      const cardTitle = currentCardElement2.getElementsByClassName("title").item(0);
      cardTitle.innerHTML = data[0].products[i].name;
    
      const cardPrice = currentCardElement2.getElementsByClassName("precio").item(0);
      cardPrice.innerHTML = data[0].products[i].price;
    
    }
    <div class="med-product-card">
      <div class="related-prod-wrapper">
        <img class="image">
      </div>
      <div class="related-prod-detail">
        <h3 class="vendor">Vendor</h3>
        <h3 class="title">Card 1</h3>
        <h3 class="precio">Precio</h3>
      </div>
    </div>
    
    <div class="med-product-card">
      <div class="related-prod-wrapper">
        <img class="image">
      </div>
      <div class="related-prod-detail">
        <h3 class="vendor">Vendor</h3>
        <h3 class="title">Card 1</h3>
        <h3 class="precio">Precio</h3>
      </div>
    </div>
    
    <div class="med-product-card">
      <div class="related-prod-wrapper">
        <img class="image">
      </div>
      <div class="related-prod-detail">
        <h3 class="vendor">Vendor</h3>
        <h3 class="title">Card 1</h3>
        <h3 class="precio">Precio</h3>
      </div>
    </div>

    Note however, that this could be further simplified in to a single loop and improved by using a <template> element to hold each ‘Card’ HTML structure which you create and update as part of the loop. This way the number of items contained within the JSON can be completely dynamic without you needing to change any of your HTML or JS logic:

    const json = '[{"user_id":"666","products":[{"id":"7109593301197","name":"Product1","img":"https://www.kasandbox.org/programming-images/avatars/spunky-sam.png","handle":"handle1","price":"111.0","vendor":"Vendor1"},{"id":"7076369957069","name":"Product2","img":"https://www.kasandbox.org/programming-images/avatars/purple-pi-pink.png","handle":"handle2","price":"85.0","vendor":"Vendor2"},{"id":"7182779154637","name":"Product3","img":"https://www.kasandbox.org/programming-images/avatars/mr-pants.png","handle":"handle3","price":"435.0","vendor":"Vendor3"}]}]';
    const data = JSON.parse(json);
    const cardContainer = document.querySelector('#card-container');
    const cardTemplate = document.querySelector('#card-template');
    
    data[0].products.forEach(product => {
      const card = cardTemplate.content.cloneNode(true).firstElementChild;
      card.querySelector('.related-prod-wrapper img').src = product.img;
      card.querySelector('.vendor').textContent = product.vendor;
      card.querySelector('.title').textContent = product.name;
      card.querySelector('.precio').textContent = product.price;
      cardContainer.appendChild(card);
    });
    <div id="card-container"></div>
    
    <template id="card-template">
      <div class="med-product-card">
        <div class="related-prod-wrapper">
          <img class="image">
        </div>
        <div class="related-prod-detail">
          <h3 class="vendor"></h3>
          <h3 class="title"></h3>
          <h3 class="precio"></h3>
        </div>
      </div>
    </template>
    Login or Signup to reply.
  2. Your code is parsing the JSON into data and then you are iterating over data.length. But the JSON is an array with only 1 element in it…therefore data.length is always going to be 1.

    I suspect what you want to be iterating over is data.products.

    You could resolve this a few ways. The least-invasive change could be:

    const data = JSON.parse(products).products;
    

    (notice the .products at the end of the line)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search