Click here to Skip to main content
15,881,089 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Hi everyone! my question is how to reslove this error?
code is in html:
HTML
<!DOCTYPE html>
<html>
    <head>
      
        <title>UKI COMPUTERS</title>
        <meta name="description" content="Store from UKI COMPUTERS.">
        <link rel="stylesheet" href="styles.css" />
        <script src="https://checkout.stripe.com/checkout.js" defer></script>
        <script>
            var stripePublicKey = '<%= stripePublicKey %>'
        </script>
        <script src="store.js" defer></script>
    </head>
    <body>
        <header class="main-header">
            <nav class="main-nav nav">
                <ul>
                    <li><a href="https://uki-computers.github.io/home">HOME</a></li>
                    <li><a href="store">STORE</a></li>

                </ul>
            </nav>
            <h1 class="band-name band-name-large">UKI COMPUTERS</h1>
        </header>
        <section class="container content-section">
            <h2 class="section-header">MUSIC</h2>
            <div class="shop-items">
                <% items.music.forEach(function(item) { %>
                <div class="shop-item" data-item-id="<%= item.id %>">
                    <%= item.name %> 
                    <img class="shop-item-image" src="Images/<%= item.imgName %>">
                    <div class="shop-item-details">
                        $<%= item.price / 100 %>
                        <button class="btn btn-primary shop-item-button" type="button">ADD TO CART</button>
                    </div>
                </div>
            <% }) %> 
        
        </section>
        <section class="container content-section">
            <h2 class="section-header">MERCH</h2>
            <div class="shop-items">
                    <%  items.merch.forEach(function(item){  %>
                        <div class="shop-item" data-item-id="<%= item.id %>">
                            <%= item.name %> 
                            <img class="shop-item-image" src="Images/<%= item.imgName %>">
                            <div class="shop-item-details">
                                $<%= item.price / 100 %>
                                <button class="btn btn-primary shop-item-button" type="button">ADD TO CART</button>
                    
                </div>
            </div>
        <% }) %> 
        </section>
        <section class="container content-section">
            <h2 class="section-header">CART</h2>
            <div class="cart-row">
                ITEM
                PRICE
                QUANTITY
            </div>
            <div class="cart-items">
            </div>
            <div class="cart-total">
                Total
                $0
            </div>
            <button class="btn btn-primary btn-purchase" type="button">PURCHASE</button>
        </section>
        <footer class="main-footer">
 
                <h3 class="band-name">(C) UKI COMPUTERS</h3>
               
            </div>
        </footer>
    </body>
</html>


code in javascript-file:
JavaScript
if (document.readyState == 'loading') {
    document.addEventListener('DOMContentLoaded', ready)
} else {
    ready()
}


function ready() {
    var removeCartItemButtons = document.getElementsByClassName('btn-danger')
    for (var i = 0; i < removeCartItemButtons.length; i++) {
        var button = removeCartItemButtons[i]
        button.addEventListener('click', removeCartItem)
    }

    var quantityInputs = document.getElementsByClassName('cart-quantity-input')
    for (var i = 0; i < quantityInputs.length; i++) {
        var input = quantityInputs[i]
        input.addEventListener('change', quantityChanged)
    }

    var addToCartButtons = document.getElementsByClassName('shop-item-button')
    for (var i = 0; i < addToCartButtons.length; i++) {
        var button = addToCartButtons[i]
        button.addEventListener('click', addToCartClicked)
    }

    document.getElementsByClassName('btn-purchase')[0].addEventListener('click', purchaseClicked)
}

var stripeHandler = StripeCheckout.configure({
    key : stripePublicKey,
    locale: 'en',
    token: function(token){
               var items = []
               var cartItemContainer = document.getElementsByClassName('cart-items')[0]
               var cartRows = cartItemContainer.getElementsByClassName('cart-row')
               for (var i = 0; i < cartRows.length; i++) {
                   var cartRows = cartRows[i]
                   var quantityElement = cartRow.getElementsByClassName('cart-quantity-input')[0]
                   var quantity = quantityElement.value
                   var id = cartRow.dataset.itemId
                   items.push({
                       id: id,
                       quantity: quantity
                   })
               }

               fetch('/purchase', {
                   method: 'POST',
                   headers: {
                       'Content-Type': 'aplication/json',
                       'Accept': 'application/json'
                   },
                   body: JSON.stringify({
                       stripeTokenId: token.id,
                       items: items
                   })
               }).then(function(res){
                   return res.json()
               }).then(function(data){
                   alert('data.message')
                       
        var cartItems = document.getElementsByClassName('cart-items')[0]
          while (cartItems.hasChildNodes()) {
                     artItems.removeChild(cartItems.firstChild)
                }
                    updateCartTotal()

        }).catch(function(error){
            console.error(error)
        }
        )}

})

function purchaseClicked() {

    
 
   var priceElement = document.getElementsByClassName('cart-total-price')[0]
   var price = parseFloat(priceElement.innerText.replace('$', '')) * 100
    stripeHandler.open({
        amount: price
    })
}

function removeCartItem(event) {
    var buttonClicked = event.target
    buttonClicked.parentElement.parentElement.remove()
    updateCartTotal()
}

function quantityChanged(event) {
    var input = event.target
    if (isNaN(input.value) || input.value <= 0) {
        input.value = 1
    }
    updateCartTotal()
}

function addToCartClicked(event) {
    var button = event.target
    var shopItem = button.parentElement.parentElement
    var title = shopItem.getElementsByClassName('shop-item-title')[0].innerText
    var price = shopItem.getElementsByClassName('shop-item-price')[0].innerText
    var imageSrc = shopItem.getElementsByClassName('shop-item-image')[0].src
    var id = shopItem.dataset.itemId
    addItemToCart(title, price, imageSrc)
    updateCartTotal()
}

function addItemToCart(title, price, imageSrc, id) {
    var cartRow = document.createElement('div')
    cartRow.dataset.itemId = id
    cartRow.classList.add('cart-row')
    var cartItems = document.getElementsByClassName('cart-items')[0]
    var cartItemNames = cartItems.getElementsByClassName('cart-item-title')
    for (var i = 0; i < cartItemNames.length; i++) {
        if (cartItemNames[i].innerText == title) {
            alert('This item is already added to the cart')
            return
        }
    }
    var cartRowContents = `
        <div class="cart-item cart-column">
            <img class="cart-item-image" src="${imageSrc}" width="100" height="100">
            ${title}
        </div>
        ${price}
        <div class="cart-quantity cart-column">
            <input class="cart-quantity-input" type="number" value="1">
            <button class="btn btn-danger" type="button">REMOVE</button>
        </div>`
    cartRow.innerHTML = cartRowContents
    cartItems.append(cartRow)
    cartRow.getElementsByClassName('btn-danger')[0].addEventListener('click', removeCartItem)
    cartRow.getElementsByClassName('cart-quantity-input')[0].addEventListener('change', quantityChanged)
}

function updateCartTotal() {
    var cartItemContainer = document.getElementsByClassName('cart-items')[0]
    var cartRows = cartItemContainer.getElementsByClassName('cart-row')
    var total = 0
    for (var i = 0; i < cartRows.length; i++) {
        var cartRow = cartRows[i]
        var priceElement = cartRow.getElementsByClassName('cart-price')[0]
        var quantityElement = cartRow.getElementsByClassName('cart-quantity-input')[0]
        var price = parseFloat(priceElement.innerText.replace('$', ''))
        var quantity = quantityElement.value
        total = total + (price * quantity)
    }
    total = Math.round(total * 100) / 100
    document.getElementsByClassName('cart-total-price')[0].innerText = '$' + total
code in server.js:
<pre lang="Javascript">if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config()
}

const stripeSecretKey = process.env.STRIPE_SECRET_KEY
const stripePublicKey = process.env.STRIPE_PUBLIC_KEY

const express = require('express')
const app = express()
const fs = require('fs')
const stripe = require('stripe')(stripeSecretKey)

app.set('view engine', 'ejs')
app.use(express.json())
app.use(express.static('public'))

app.get('/store', function(req, res) {
  fs.readFile('items.json', function(error, data) {
    if (error) {
      res.status(500).end()
    } else {
      res.render('store.ejs', {
        stripePublicKey: stripePublicKey,
        items: JSON.parse(data)
      })
    }
  })
})

app.post('/purchase', function(req, res) {
  fs.readFile('items.json', function(error, data) {
    if (error) {
      res.status(500).end()
    } else {
      const itemsJson = JSON.parse(data)
      const itemsArray = itemsJson.music.concat(itemsJson.merch)
      let total = 0
      req.body.items.forEach(function(item) {
        const itemJson = itemsArray.find(function(i) {
          return i.id == item.id
        })
        total = total + itemJson.price * item.quantity
      })

      stripe.charges.create({
        amount: total,
        source: req.body.stripeTokenId,
        currency: 'usd'
      }).then(function() {
        console.log('Charge Successful')
        res.json({ message: 'Successfully purchased items' })
      }).catch(function() {
        console.log('Charge Fail')
        res.status(500).end()
      })
    }
  })
})

app.listen(3000)

}

and when run program in node js, purcashe items with stripe, in cmd line show that:
D:\Libaries\Desktop\Node.js\shop>node server.js
D:\Libaries\Desktop\Node.js\shop\server.js:38
      req.body.items.forEach(function(item) {
                     ^

TypeError: Cannot read property 'forEach' of undefined
    at D:\Libaries\Desktop\Node.js\shop\server.js:38:22
    at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:73:3)

D:\Libaries\Desktop\Node.js\shop>


and when open stripe in payments, no have payments. Please help me.
Sorry: here is file of server.js
if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config()
}

const stripeSecretKey = process.env.STRIPE_SECRET_KEY
const stripePublicKey = process.env.STRIPE_PUBLIC_KEY

const express = require('express')
const app = express()
const fs = require('fs')
const stripe = require('stripe')(stripeSecretKey)

app.set('view engine', 'ejs')
app.use(express.json())
app.use(express.static('public'))

app.get('/store', function(req, res) {
  fs.readFile('items.json', function(error, data) {
    if (error) {
      res.status(500).end()
    } else {
      res.render('store.ejs', {
        stripePublicKey: stripePublicKey,
        items: JSON.parse(data)
      })
    }
  })
})

app.post('/purchase', function(req, res) {
  fs.readFile('items.json', function(error, data) {
    if (error) {
      res.status(500).end()
    } else {
      const itemsJson = JSON.parse(data)
      const itemsArray = itemsJson.music.concat(itemsJson.merch)
      let total = 0
      req.body.items.forEach(function(item) {
        const itemJson = itemsArray.find(function(i) {
          return i.id == item.id
        })
        total = total + itemJson.price * item.quantity
      })

      stripe.charges.create({
        amount: total,
        source: req.body.stripeTokenId,
        currency: 'usd'
      }).then(function() {
        console.log('Charge Successful')
        res.json({ message: 'Successfully purchased items' })
      }).catch(function() {
        console.log('Charge Fail')
        res.status(500).end()
      })
    }
  })
})

app.listen(3000)


What I have tried:

Researched internet. Result: Nothing.
Posted
Updated 20-Aug-21 6:37am
v3
Comments
Afzaal Ahmad Zeeshan 20-Aug-21 15:38pm    
I would try using console.log(JSON.stringify(req.body)) to see what is the structure of the request object.

1 solution

Quote:
Problem foreach in node.js?

The problem is not on the foreach !
If you look carefully at the error message:
      req.body.items.forEach(function(item) {
                     ^
TypeError: Cannot read property 'forEach' of undefined

The problem is that req.body.items is not the object you expect. You need to backtrack where req.body.items come from and what its type, if ever it is set to something.

Your code do not behave the way you expect, or you don't understand why !

There is an almost universal solution: Run your code on debugger step by step, inspect variables.
The debugger is here to show you what your code is doing and your task is to compare with what it should do.
There is no magic in the debugger, it don't know what your code is supposed to do, it don't find bugs, it just help you to by showing you what is going on. When the code don't do what is expected, you are close to a bug.
To see what your code is doing: Just set a breakpoint and see your code performing, the debugger allow you to execute lines 1 by 1 and to inspect variables as it execute.

Debugger - Wikipedia, the free encyclopedia[^]

Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]
Basic Debugging with Visual Studio 2010 - YouTube[^]

JavaScript Debugging[^]
Chrome DevTools  |  Web  |  Google Developers[^]

The debugger is here to only show you what your code is doing and your task is to compare with what it should do.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900