'Update display for items in shopping cart with Subject/Observable
I'm creating an app where the user adds an item to their cart, and then it keeps track of these items in local storage. When the user clicks on the add button in one component, I need the navbar to update with the number of items in real time but I cannot use an Event Emitter with how my app is set up.
The functionality I'm looking for is simple, when I add an item and it goes into local storage, the number in my navbar next to the shopping cart logo should increase by 1. I know this can be handled using Observables and Subjects, I'm just having a difficult time understanding it. I've moved the code from the component to the service to begin because I figure that will allow both components to communicate with it. I can add the items to local storage properly using the service, but I'm stuck after that where I need to keep track of the number of items added with the service.
Here's the service:
@Injectable({
providedIn: 'root'
})
export class MenuService {
public apiRoot: string = `http://localhost:3000`;
orders;
constructor(private http: HttpClient) { }
order(id, name, options, price) {
//confirm the order is correct
const orderConfirmed = confirm("Add this item to your cart?");
if (orderConfirmed) {
let order = new Order(id, name, options, price)
//get and set any existing orders from local storage or set to a blank array if there are none
this.orders = localStorage.getItem('order') ? JSON.parse(localStorage.getItem('order')) : [];
//push to our orders array
this.orders.push(order)
//store in localStorage
localStorage.setItem('order', JSON.stringify(this.orders))
}
}
Then here is my navbar.ts:
export class NavbarComponent implements OnInit {
itemsInCart;
constructor() { }
getItemsInCart() {
this.itemsInCart = JSON.parse(localStorage.getItem('order'))
}
ngOnInit() {
this.getItemsInCart();
}
}
Right now I'm just pulling the items directly from local storage and displaying them, but obviously this won't work in real time if I were to add other items, basically I want to make my navbar component which is above the router-outlet to be able to subscribe to the this.orders property in the MenuService so that I can keep track of the length of this.orders in real time as the user adds items to the cart. Sorry if this seems obvious, still learning!
Solution 1:[1]
don't use localstorage store in the memory instead that way when you close the browser tab or refresh data gets destroyed, (Expert level you should use Ngrx Store)
check Unrelated Components: Sharing Data with a Service here
storage.service.ts
export class StorageService {
private foo: String;
public fooChanged$: EventEmitter<any>; // For Communication between components
constructor() {
this.fooChanged$ = new EventEmitter(); // For Communication between components
}
public emitFooChange(): void {// For Communication between components
this.fooChanged$.emit();
}
setFoo(data: String) {
this.foo = data;
}
getFoo(): Number {
return this.foo;
}
}
component.ts
constructor(private storageService: StorageService){}
ngOnInit(){
this.storageService.setFoo("Foo");
console.log('foo', this.storageService.getFoo());
}
Solution 2:[2]
I hope you are using the Angular framework, services follow the singleton pattern there, so there will be only one instance of that property too. (No need to use an observable pattern.)
Create a service with property cart_items_count, In the constructor assign the value(real count extracted from local storage) to the property. When you add to the cart increase cart_items_count too by 1.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
