Cart Model

  • Create a new separate model cart.js under models.
  • Instead putting constructor, we’ll just put static methods since cart instance is not being added or deleted every time we add or edit the product, but it could just be there.

We’re importing file system and path so that we can save the cart data in cart.json and access to its path.

models/cart.js

const fs = require('fs');const path = require('path');const p = path.join(
path.dirname(process.mainModule.filename),
'data',
'cart.json'
);

Then we check if there’s a cart or not using parameter err and fileContent. If there’s no error, it means the cart already exists, so the cart would be reassigned with the parsed json data.

module.exports = class Cart {
static addProduct(id) {
// Fetch the previous cart fs.readFile(p, (err, fileContent) => {
let cart = {products: [], totalPrice: 0};
if (!err) {
cart = JSON.parse(fileContent);
}
});
};
};

Now we loop over the cart products to see if any product in the cart matches the id passed in.

const existingProduct = cart.products.find(prod => prod.id === id);
let updatedProduct;

If the product id already exists in the cart, we’ll just copy over the existingProduct object to the updatedProduct and just add 1 to the qty. Otherwise, create a new object with id and qty keys.

Make sure to add product price to the cart’s total price and don’t forget to convert string type productPrice to number by adding ‘+’ in front of it.

if (existingProduct) {
updatedProduct = {...existingProduct};
updatedProduct.qty = updatedProduct.qty + 1;
} else {
updatedProduct = { id: id, qty: 1};
}
cart.totalPrice = cart.totalPrice + +productPrice;

We need to access the specific index of product array in the cart object. So instead using find method, we’ll use findIndex to get the index.

// Analyze the cart => Find existing productconst existingProductIndex = cart.products.findIndex(prod => prod.id === id);
const existingProduct = cart.products[existingProductIndex];
let updatedProduct;
// Add new product or increase quantityif (existingProduct) {
updatedProduct = {...existingProduct};
updatedProduct.qty = updatedProduct.qty + 1;
cart.products = [...cart.products];
cart.products[existingProductIndex] = updatedProduct;
} else {
updatedProduct = { id: id, qty: 1};
cart.products = [...cart.products, updatedProduct];
}
cart.totalPrice = cart.totalPrice + productPrice;
fs.writeFile(p, JSON.stringify(cart), err => {
console.log(err);
})

Import cart.js in controllers and call the adding product method with passing parameters.

controllers/shop.js

exports.postCart = (req, res, next) => {
const prodId = req.body.productId;
Product.findById(prodId, (product) => {
Cart.addProduct(prodId, product.price);
});
res.redirect('/cart');
};