Svelte Shopping Cart

Feb 13, 2021 - sharathdt

While learning JavaScript, I started building this simple e-commerce shopping cart which had some basic functionalities,

  1. Add products.
  2. Show products in the cart.
  3. Update product quantity in the cart.

It seems really simple but I had a hard time doing it. But when I tried the same in Svelte, it felt like a breeze.

Check out this REPL: Svelte shopping cart

I will show you - with snippets - how I did it.

Create an array of products. Each products usually will have details like id, name, image, price etc.

 let products = [
  {id: 1, name: "Apple", image: "/path/to/apple.png", price: 10, quantity: 1},
  {id: 2, name: "Orange", image: "/path/to/apple.png", price: 11, quantity: 1},
  {id: 3, name: "Grapes", image: "/path/to/apple.png", price: 12, quantity: 1},
]

Create an empty array called cart. The idea is to add items from products to the cart whenever Add to cart is clicked.

 let cart = [];

Let’s show these prodcuts along with a button.

<div class="product-list">
 {#each products as product}
   <div>
    <div class="image" style="background-image: url({product.image})"></div>
    <h4>{product.name}</h4>
    <p>₹{product.price}</p>
    <button>Add to cart</button>
   </div>
 {/each}
</div>

<style>
 .product-list {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
 }
</style>

That should display it in a grid with add a non-functional button.

Now, let’s add a function addToCart() to buttons. We will have to send the prodcut along with this function as shown below.

  <button on:click={() => addToCart(product)}>Add to cart</button>

We can create this function to receive the sent product and push it to the cart.

const addToCart = (product) => {
 cart.push(product)
}

Now, in Svelte this will not be reactive because there is not assignment used. We can rewite this usig spread operator as shown below.

  const addToCart = (product) => {
    cart = [...cart, product]
  }

The problem with this is that when you add the same item multiple times, it keeps on adding to the cart array. We don’t want that. We would like only the quantity of the cart item to increase if it is already present.

When Add to cart is clicked, we can go through all the cart items to see whether the item just added is already in the cart, if so then we increment the quantity as shown below.

const addToCart = (product) => {
  for(let item of cart) {
    if(item.id === product.id) {
	product.quantity += 1
	cart = cart;
	return;
     }
   }
  cart = [...cart, product]
}

We can display the cart a better way as shown below.

<div class="cart-list">
 {#each cart as item }
   <div class="cart-item">
     <img width="50" src={item.image} alt={item.name}/>
     <div>{item.quantity}</div>
     <p>₹{item.price * item.quantity}</p>
   </div>
 {/each}

We can also add buttons besides quantity to add or remove the items added to the cart. This function is pretty much same as the addToCart() function that we already discussed.

Let’s add those buttons with functions sending product as parameter.

  {#each cart as item }
  <div class="cart-item">
    <img width="50" src={item.image} alt={item.name}/>
    <div>{item.quantity}
      
      <button on:click={() => minusItem(item)}>-</button>
      <button on:click={() => plusItem(item)}>+</button>

    </div>
    <p>₹{item.price * item.quantity}</p>
  </div>
  {/each}

We can define those functions to add or remove items from the cart array as shown here.

const minusItem = (product) => {
 for(let item of cart) {
   if(item.id === product.id) {
     product.quantity -= 1
     cart = cart;
     return;
   }
 }
 cart = [...cart, product]
}
	
const plusItem = (product) => {
 for(let item of cart) {
   if(item.id === product.id) {
     product.quantity += 1
     cart = cart;
     return;
    }
  }
 cart = [...cart, product]
}

That should take care of the button functions in the cart.

Now this is almost complete. But I have used a single component. In the next article I will be doing the following,

  1. Use components to simplify the app.
  2. Use writable store to maintain state across the app.
  3. Use session store to persist the cart even on browser refresh.

Thanks

Watch the vide here:

Comment