Home > database >  State management in Angular using Rxjs
State management in Angular using Rxjs

Time:11-02

I am managing my state in Angular app by using Behavior Subject. I am using two services. One to perform send and get request using web sockets and one to store the data in an observable. As soon as the data is retrieved I pass the data to the behavior subject. I am having an issue here. Everything is working perfectly except, when I delete the item and press the back button. Some of my data gets lost during this process. I don't know why is this happening. Here's my code:

cart.store.ts // for managing state

private cartItems$ = new BehaviorSubject<Product[]>(null);
private items: Product[] = [];

setCart(cartItems: Product[]) {
    this.cartItems$.next(cartItems);
}

setSingleItem(item: Product) {
    this.items.push(item);
    this.cartItems$.next(this.items);
}

deleteCart(item: Product) {
    this.cartItems$.subscribe((res) => {
      let index;
      for (let i = 0; i < res.length; i  ) {
         if (item.upc === res[i].upc) {
            index = i;
        }
      }
     res.splice(index, 1);
   });
}

cart.component.ts //calls cart service and fetches the data

getCartItems() {
if (!this.cartItems?.length) {
  const payload = this.localStorageService.getData(LOCAL_STORAGE_KEY.PHONE);
  this.cartService.getCart(payload).then((res) => {
    //after fetching storing the data
    this.cartStore.setCart(res);
    for (let x = 0; x < res.length; x  ) {
      this.totalPrice = this.totalPrice   res[x].price;
    }
    this.cartItems$ = this.cartStore.getCart();  //using async pipe to display in template
  });
}
}

cart.service.ts //for getting and removing data

getCart(payload): Promise<any> {
this.socketService.sendMessage(AUTH_EVENTS.ON_DEVICE_CONNECT, payload);
const serverRes = (async () => {
  try {
    const data = await this.socketService.receivedJustSingleValue(
      CART_EVENTS.GET_CART_ITEMS,
    );
    if (data) {
      return data;
    } else {
      throw new Error('error');
    }
  } catch (error) {
    return error;
  }
})();
return serverRes;
}   

//remove cart works the same way

When I remove an item and press the back button, my data gets lost. Can anybody tell me what's wrong?

CodePudding user response:

The problem is in the deleteCart function. You subscribe to the observable but never unsubscribe. So every time you call next(), The deleteCart runs again and deletes an item.

You can use BehaviorSubject.value to get the current items. The result should see like this:

private cartItems$ = new BehaviorSubject<Product[]>(null);
// private items: Product[] = [];

setCart(cartItems: Product[]) {
    this.cartItems$.next(cartItems);
}

setSingleItem(item: Product) {
    this.cartItems$.next([...this.cartItems$.value, item]);
}

deleteCart(item: Product) {
    const items = this.cartItems$.value;
    let index;
    for (let i = 0; i < items.length; i  ) {
        if (item.upc === items[i].upc) {
            index = i;
        }
    }
    items.splice(index, 1);
    this.cartItems$.next(items);
}
  • Related