That was easy! - Svelte Shopping Cart
Tags: svelte, javascript
Published: 2021-02-14 12:22:55

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](https://svelte.dev/repl/f894a09732d74059b4820324dae003c1?version=3.32.3)

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.

```javascript
 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.

```javascript
 let cart = [];
```

Let's show these prodcuts along with a button.

```html
<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.

![image](https://dev-to-uploads.s3.amazonaws.com/i/9y10ercbwii8uij5w944.png)

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

```html
<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.

```javascript
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.

```javascript
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.

```javascript
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.

```html
<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}
```

![image](https://dev-to-uploads.s3.amazonaws.com/i/brx0s00mo1w72teql6i2.png)
 
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.

```html
{#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.

```javascript
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.

![image](https://dev-to-uploads.s3.amazonaws.com/i/0tp9yg7yy68apciyy0ij.png)


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:**

{% youtube Jh_12JeLtMo %}