DEV Community

Cover image for That was easy! - Svelte Shopping Cart
sharath Kumar
sharath Kumar

Posted on • Edited on • Originally published at blog.webjeda.com

That was easy! - Svelte Shopping Cart

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},
]
Enter fullscreen mode Exit fullscreen mode

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 = [];
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

image

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>
Enter fullscreen mode Exit fullscreen mode

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

const addToCart = (product) => {
 cart.push(product)
}
Enter fullscreen mode Exit fullscreen mode

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]
}
Enter fullscreen mode Exit fullscreen mode

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]
}
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

image

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}
Enter fullscreen mode Exit fullscreen mode

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]
}

Enter fullscreen mode Exit fullscreen mode

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

image

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:

Top comments (0)