Search code examples
angulartypescriptlocal-storagee-commercecart

Local Storage using Angular


I'm developing an e-commerce and I'm trying to set local storage to hold the elements inside the cart.

All fine when i add a product to the cart and all but once i refresh the cart page, all products just disappear.

I tried set the local storage and i can't figure where i'm wrong...

My browser is fine with local storage permissions (Edge).

cart.component.ts:

    export class CartComponent {

  products = this.cartService.getProducts();

  constructor(
    private cartService: CartService
  ) { }


  totalPrice = this.cartService.getProducts().reduce((acc, product) => acc + product.PriceWithIVA, 0);




}

cart.service.ts:

  addToCart(product: ProductDTO) {
    this.products.push(product);

    let products = [];

    if (localStorage.getItem ('products')) {
        products = JSON.parse(localStorage.getItem('products'));
    }

    products.push ({
        name: product.Name,
        image: product.Attachment,
        price: product.PriceWithIVA
    })

    localStorage.setItem ('products', JSON.stringify(products));
    this.products = products;
}




getCartDetailsByUser() {
    const data = JSON.parse(localStorage.getItem ('products'));
    this.products = data;

    if (data !== null) {
        this.cartQuantity = data.length;
    }
}


getProducts() {
    return this.products;
}

clearCart() {
    localStorage.removeItem ('products');
    this.products = [];
    this.cartQuantity = 0;
}

Solution

  • In constructor of your service you should ask about "localStorage.getItem ('products')"

    constructor(){
       const products=localStorage.getItem ('products')
       this.products=products?JSON.parse(products):[];
    }
    

    Update* @Jany, you need pay attention to the name of the variables -you store the data as name, price and image but when you add to cart received an object with but received Name, Attachment and PriceWithIVA.

    Futhermore you has variable products in service and in your card, perhafs it's good use a getter.

    I forked your code

    export class CartComponent implements OnInit {
    
      totalPrice: number;
    
      //I use a getter
      get products() {
        return this.cartService.getProducts()
        //you also can use
        return this.cartService.products;
      }
      constructor(private cartService: CartService) {}
      ngOnInit() {
        this.calculeTotal();
      }
    
      add() {
    
        //well I add a "fool product"
        const date = new Date();
        this.cartService.addToCart({
          Name: 'fool ' + date.getSeconds(),
          PriceWithIVA: 100,
        });
        this.calculeTotal();
      }
    
      clear() {
        this.cartService.clearCart();
        this.calculeTotal();
      }
    
      //After any operation we should call to CalculateTotal
    
      private calculeTotal() {
        this.totalPrice = this.products.reduce(
          (acc, product) => acc + product.price,
          0
        );
      }
    }
    

    Your service

    @Injectable({
      providedIn: 'root',
    })
    export class CartService {
      products: any[] = [];
      cartQuantity = 0;
      constructor() {
        //get the "localstorage"
        const local = localStorage.getItem('products');
    
        //if exist, use JSON.parse, else return an empty array
        const products = local ? JSON.parse(local) : [];
    
       //map to be sure the "price" is a number
        this.products = products.map((x: any) => ({
          ...x,
          price: +(x.price || 0),
        }));
    
       //really it's unnecesary
        this.cartQuantity = products ? products.length : 0;
      }
      addToCart(product: any) {
        this.products.push({
          name: product.Name,
          image: product.Attachment,
          price: +product.PriceWithIVA,
        });
        
        //but we need actualize the value of qauntity
        this.cartQuantity = products ? products.length : 0;
    
        localStorage.setItem('products', JSON.stringify(this.products));
      }
    
      getProducts() {
        return this.products;
      }
    
      clearCart() {
        localStorage.removeItem('products');
        this.products = [];
        this.cartQuantity = 0;
      }
    }
    

    A simple stackblitz