Package.JSON
Package.JSON

Reputation: 301

State management in Angular using Rxjs

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('some shit happened');
    }
  } 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?

Upvotes: 3

Views: 3370

Answers (1)

Shalom Peles
Shalom Peles

Reputation: 2632

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);
}

Upvotes: 1

Related Questions