Reputation: 35
I am having a lot of trouble solving the issue of monitoring changes to my Shopping Cart via Local Storage with my Shopping Cart Service. How do I subscribe to changes made like adding qty or deleting an item, so that the page will display the new data upon event?
Is there a way to constantly monitor the localStorage and update my getItems() when a change is made from my other methods to the localStorage?
My mind is a little slow from going at this all day, any help is awesome!
CartComponent.ts ---
import { Component, OnInit } from '@angular/core';
import { CartService } from '../services/cart.service';
import { Products } from '../models/products';
import { Item } from '../models/item';
@Component({
selector: 'app-cart',
templateUrl: './cart.component.html',
styleUrls: ['./cart.component.css']
})
export class CartComponent implements OnInit {
product: Products;
public items: Item = new Item();
item;
constructor(private cartService: CartService) { }
ngOnInit(): void {
this.items = this.cartService.getItems();
//this.items = this.cartService.getItems();
}
deleteItem(item){
this.cartService.deleteItem(item);
let domItem = document.getElementById(`cart-item`+item.product.id);
setTimeout(() =>{
domItem.classList.add('delete-style');
domItem.parentNode.removeChild(domItem);
},1000);
}
addQty(item){
this.cartService.addQty(item);
}
}
CartService.ts ---
import { Injectable } from '@angular/core';
import { Products } from '../models/products';
import { Item } from '../models/item';
import { Observable, of } from 'rxjs';
import { StorageService } from '../services/storage.service';
let itemsInCart = [];
let cart = [];
//console.log("itemsInCart: ", itemsInCart);
@Injectable({
providedIn: 'root'
})
export class CartService {
product: Products;
items: Item;
constructor() { }
addToCart(product: Products) {
let local_storage;
let itemsInCart = []
this.items = {
product: product,
quantity: 1,
}
if(localStorage.getItem('cart') == null){
local_storage =[];
console.log("LOCALSTORAGE NULL",JSON.parse(localStorage.getItem('cart')));
itemsInCart.push(this.items);
localStorage.setItem('cart', JSON.stringify(itemsInCart));
console.log('Pushed first Item: ', itemsInCart);
}
else
{
local_storage = JSON.parse(localStorage.getItem('cart'));
console.log("LOCAL STORAGE HAS ITEMS",JSON.parse(localStorage.getItem('cart')));
for(var i in local_storage)
{
console.log(local_storage[i].product.id);
if(this.items.product.id == local_storage[i].product.id)
{
local_storage[i].quantity += 1;
console.log("Quantity for "+i+" : "+ local_storage[i].quantity);
console.log('same product! index is ', i);
this.items=null;
break;
}
}
if(this.items){
itemsInCart.push(this.items);
}
local_storage.forEach(function (item){
itemsInCart.push(item);
})
localStorage.setItem('cart', JSON.stringify(itemsInCart));
}
}
getItems(){
console.log("Cart: ", JSON.parse(localStorage.getItem('cart')));
return this.items = JSON.parse(localStorage.getItem('cart'));
//return this.items =
}
deleteItem(item){
item = item;
console.log("Deleting : ",item);
let shopping_cart;
let index;
shopping_cart = JSON.parse(localStorage.getItem('cart'));
for(let i in shopping_cart){
if (item.product.name == shopping_cart[i].product.name)
{
index = i;
console.log(index);
}
}
shopping_cart.splice(index, 1);
console.log("shopping_cart ", shopping_cart);
localStorage.setItem('cart', JSON.stringify(shopping_cart));
}
addQty(item: Item)
{
item = item;
let shopping_cart;
shopping_cart = JSON.parse(localStorage.getItem('cart'));
for(let i in shopping_cart){
if(item.product.name == shopping_cart[i].product.name){
shopping_cart[i].quantity +=1;
item = null;
break;
}
}
localStorage.setItem('cart', JSON.stringify(shopping_cart));
}
numberOfItems(){
let itemsInCart = JSON.parse(localStorage.getItem('cart'));
return itemsInCart.length;
}
clearCart(){
localStorage.clear();
}
}
Upvotes: 2
Views: 5577
Reputation: 2420
According to MDN there is an event you can listen for
window.addEventListener('storage', function(e) {
document.querySelector('.my-key').textContent = e.key;
document.querySelector('.my-old').textContent = e.oldValue;
document.querySelector('.my-new').textContent = e.newValue;
document.querySelector('.my-url').textContent = e.url;
document.querySelector('.my-storage').textContent = JSON.stringify(e.storageArea);
});
but if I were you I'd keep track of items inside the singleton service https://angular.io/guide/singleton-services
Upvotes: 1
Reputation: 10662
You can use rxjs Subjects for this:
In your service:
subject = new Subject<any>();
when you are updating the value stored in localStorage
use .next
example:
localStorage.setItem('cart', JSON.stringify(itemsInCart));
subject.next('changed');
and subscribe to it inside your component, you can subscribe inside a lifecycle hook:
ngOnInit() {
this.cartService.subscribe((status) => {
//..you will reach here when you use `.next` because this callback function gets
// executed
this.items = this.cartService.getItems();
})
}
Upvotes: 4