Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngrx store subscription not called when state changes

I am creating an application with dummy data defined in my service.

In one component, I have the following function that deletes a product:

  removeItem(productId: string) {
      this.cartService.removeItem(productId);
  }

and the service as follows:

  removeItem(productId: string) {
    const itemIndex = this.cart.products.findIndex(el => el.id === productId);
    if (itemIndex > -1) {
      this.cart.products.splice(itemIndex, 1);
      return Observable.of(this.cart)
        .subscribe((cartResponse: Cart) => {
          this.store.dispatch({ type: CART_UPDATE, payload: cartResponse });
        });
    }
  }

(this.cart is the data I have hard coded in the service).

My reducer looks like:

export const cartReducer = (state: Cart = {} as Cart, {type, payload}) => {
  switch (type) {

    case CART_UPDATE:
      // update categories state
      return payload;
    default:
      return state;
  }
};

Then I am subscribing to the cart in one component like:

  ngOnInit() {
    this.store.select('cart').subscribe((cart: Cart) => {
      console.log('here');
      this.numberOfItems = cart.products.length;
    });
  }

I also have in app.module

StoreModule.provideStore({
  cart: cartReducer
}),

The remove function works fine, and the code reaches the reducer function with the correct payload.

The issue is that the subscription callback in the component is called only the first time the component is loaded.

When I call the remove function, the product is indeed removed and the reducer function is called and returning the correct data, but the callback is not called.

Am I missing something?

like image 859
callback Avatar asked Sep 07 '17 14:09

callback


1 Answers

I think the issue is that the payload you are returning in the reducer has the same object reference as the existing state. Try returning a new object and see if that causes your subscription to be invoked. Like so:

export const cartReducer = (state: Cart = {} as Cart, {type, payload}) => {
  switch (type) {    
    case CART_UPDATE:
      // update categories state
      return { ...payload }; // equivalent to Object.assign({}, payload);
    default:
      return state;
  }
};
like image 197
Teddy Sterne Avatar answered Sep 21 '22 14:09

Teddy Sterne