How to get JSON data after button click

Viewed 67

const Sheet = [
        {
            "Code": "A-0-1", 
            "UPC": "Photos/4009803054728.jpg",
            "Title": "U.S.S. Constitution",
            "Price": "$34",
            "InStock": "7"
        },
        {
            "Code": "A-0-2",
            "UPC": "Photos/4009803073996.jpg",
            "Title": "Revell 07399 VW Samba Bus Model Kit",
            "Price": "$38",
            "InStock": "8"
        },
    ]
const productsEl = document.querySelector(".Sheet");

function getProducts() {
    Sheet.forEach((product) => {
        productsEl.innerHTML += `<div class="productContainer">
            <div class="img">
                <img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
            </div>
            <div class="itemdesc">
                <h2 class="itemName" id="itemName">${product.Title}</h2>
                <h4 class="price"><span id="price">${product.Price}</span></h4>
                <div class="desc">
                    <p id="desc">${product.Code}</p>
                </div>
                <div class="stock">
                    <p> ${product.InStock} Units</p>
            </div>
            <div class="addToCart" onclick="addToCart();">
                <button id="addToCart" > Add to Cart</button>
            </div>
    </div>`; 
    })
}
getProducts(); 

function addToCart() {
    console.log(document.getElementById("itemName").innerText)
}
<div class="Sheet">
    </div>

All right, the add to cart button only logs the first data in my object. No matter which one I press it's always the first one. I tried .val and no luck. How can I log the item that was pressed instead?

4 Answers

You can pass the name of product as an argument to the addToCart() function like below

const Sheet = [
        {
            "Code": "A-0-1", 
            "UPC": "Photos/4009803054728.jpg",
            "Title": "U.S.S. Constitution",
            "Price": "$34",
            "InStock": "7"
        },
        {
            "Code": "A-0-2",
            "UPC": "Photos/4009803073996.jpg",
            "Title": "Revell 07399 VW Samba Bus Model Kit",
            "Price": "$38",
            "InStock": "8"
        },
    ]
const productsEl = document.querySelector(".Sheet");

function getProducts() {
    Sheet.forEach((product) => {
        productsEl.innerHTML += `<div class="productContainer">
            <div class="img">
                <img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
            </div>
            <div class="itemdesc">
                <h2 class="itemName" id="itemName">${product.Title}</h2>
                <h4 class="price"><span id="price">${product.Price}</span></h4>
                <div class="desc">
                    <p id="desc">${product.Code}</p>
                </div>
                <div class="stock">
                    <p> ${product.InStock} Units</p>
            </div>
            <div class="addToCart" onclick="addToCart(product.Title);">
                <button id="addToCart" > Add to Cart</button>
            </div>
    </div>`; 
    })
}
getProducts(); 

function addToCart(productTitle) {
    console.log(productTitle)
}

You have to pass the product's index as a parameter to the AddToCart() function.

Advantages of this implementation

  1. Allows you to access other properties of the product's object like Price, InStock, etc.
  2. If you change the property name of "Title" to something else, you only need to update the AddToCart function code, not the getProducts()'s AddToCart call-to-action.

Advice: You should try to avoid fetching items via html id or innerText (this was a norm a decade or more ago, not anymore). Try using more of data attributes

const Sheet = [
        {
            "Code": "A-0-1", 
            "UPC": "Photos/4009803054728.jpg",
            "Title": "U.S.S. Constitution",
            "Price": "$34",
            "InStock": "7"
        },
        {
            "Code": "A-0-2",
            "UPC": "Photos/4009803073996.jpg",
            "Title": "Revell 07399 VW Samba Bus Model Kit",
            "Price": "$38",
            "InStock": "8"
        },
    ]
const productsEl = document.querySelector(".Sheet");

function getProducts() {
    Sheet.forEach((product, productIndex) => {
        productsEl.innerHTML += `<div class="productContainer">
            <div class="img">
                <img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
            </div>
            <div class="itemdesc">
                <h2 class="itemName" id="itemName">${product.Title}</h2>
                <h4 class="price"><span id="price">${product.Price}</span></h4>
                <div class="desc">
                    <p id="desc">${product.Code}</p>
                </div>
                <div class="stock">
                    <p> ${product.InStock} Units</p>
            </div>
            <div class="addToCart" onclick="addToCart(`+productIndex+`);">
                <button id="addToCart" > Add to Cart</button>
            </div>
    </div>`; 
    })
}
getProducts(); 

function addToCart(productIndex) {
    var product = Sheet[productIndex];
    console.log(product.Title);
}
<div class="Sheet">
    </div>

Explanation

The parameters of a forEach function allows for the index of the current iteration. read more here

Try like this

   const Sheet = [
        {
            "Code": "A-0-1",
            "UPC": "Photos/4009803054728.jpg",
            "Title": "U.S.S. Constitution",
            "Price": "$34",
            "InStock": "7"
        },
        {
            "Code": "A-0-2",
            "UPC": "Photos/4009803073996.jpg",
            "Title": "Revell 07399 VW Samba Bus Model Kit",
            "Price": "$38",
            "InStock": "8"
        },
    ]
    const productsEl = document.querySelector(".Sheet");

    function getProducts() {
        Sheet.forEach((product) => {
            productsEl.innerHTML += `<div class="productContainer">
            <div class="img">
                <img src=${product.UPC} alt="Image Unavailable" height="170px;" width="170px">
            </div>
            <div class="itemdesc" >
                <h2 class="itemName" id="itemName">${product.Title}</h2>
                <h4 class="price"><span id="price">${product.Price}</span></h4>
                <div class="desc">
                    <p id="desc">${product.Code}</p>
                </div>
                <div class="stock">
                    <p> ${product.InStock} Units</p>
            </div>
            <div class="addToCart" onclick="">
                <button class="addToCartBtn" id="${product.Code}"> Add to Cart</button>
            </div>
    </div>`;
        })
    }
    getProducts();

    var elements = document.querySelectorAll(".addToCartBtn");
    elements.forEach(element => {
        element.addEventListener("click", function (e) {
            console.log(e.target.id);
            //other function
        });
    });
<div class="Sheet">
</div>

Use this instead...

const productsEl = document.querySelector(".Sheet");
const Sheet = [
        {
            "Code": "A-0-1", 
            "UPC": "Photos/4009803054728.jpg",
            "Title": "U.S.S. Constitution",
            "Price": "$34",
            "InStock": "7"
        },
        {
            "Code": "A-0-2",
            "UPC": "Photos/4009803073996.jpg",
            "Title": "Revell 07399 VW Samba Bus Model Kit",
            "Price": "$38",
            "InStock": "8"
        },
    ];

(function getProducts() {
    Sheet.forEach(product => {
        productsEl.innerHTML += `<!-- ${product.Title} -->
        <div class="productContainer">
            <div class="img">
                <img src="${product.UPC}" alt="${product.Title}" height="170px" width="170px">
            </div>
            <div class="itemDesc">
                <h2 class="name">${product.Title}</h2>
                <h4 class="price">${product.Price}</h4>
                <div class="desc">
                    <p>${product.Code}</p>
                </div>
                <div class="stock">
                    <p> ${product.InStock} Units</p>
            </div>
            <div class="addToCart">
                <!-- This will ensure you're only getting the current product (via the button) -->
                <button onclick="addToCart(this)"> Add to Cart</button>
            </div>
        </div>`; 
    })
})();

function addToCart(button) {
    const parent = button.closest('.productContainer');
        // This will travel up the DOM chain from the button to the nearest element with `class="... productContainer ..."`
    const element = parent.querySelector('.name');
        // This will travel back down the DOMchain to the element with `class="... name ..."`

    console.log(element.innerText);
}
<div class="Sheet"></div>

Related