Search code examples
angularngrx

obtain values from ngrx store into local variable in Angular 14


I'm still new to NGRX. I have finally got records into store as can be seen from my screenshot below using the Redux Devtools.

enter image description here

I now want to obtain the basket records to allow me to remove an item from the basket.

I have declared a variable to pull the basket data into:

 basketPhoto$: Observable<Photo>[] = []; 

then I have a click event that passes the photo details that I want to remove, lets say I've passed the photo with an id 0f 3 in. I know I need to obtain the index '1' in this case before splicing it from the basket. So I first need to obtain the index value of me record.

I thought I could do something like:

RemoveFromBasket(photo: Photo) {
    this.basketPhoto$ = this.basketStore.pipe(select(basket => basket.basket));
  
  }

as my starter to get all the records from the basket, so that I can find the position of my record, but I get a red line under basketPhoto$. basketStore is defined in my constructor.

 constructor(private store: Store, private basketStore: Store<{ basket: Photo[] }>) { } 

******** Update ********

following on from @wlf answer I have created an Action:

export const getBasket = createAction('[Basket Component] getBasket', props<{ id: number}>());

extended my reducer:

export const initialBasketState: Array<Photo> = [];

export const basketReducer = createReducer(   
initialBasketState,   
on(basketDetail, (state, { basket }) => { return [...state, basket] }  ),   
on(getBasket, (state, { id }) => ({ ...state, basket: state.splice(state.findIndex(m => m.id === id)  )})   ), );

and I now call the action:

 this.basketStore.dispatch(getBasket({ id: photo.id}));

Now when make the call, I receive an error

cannot delete property '1' of [object array]


Solution

  • This removal logic belongs in your reducer rather than your component.

    1. Create an action for removing the photo:

    const removePhotoClicked = createAction('remove photo clicked', props<{id: number}>());

    1. Dispatch that action when button is clicked with relevant id
    2. Handle the removal in your reducer:
    export const designerReducer = createReducer(
      initialState,
      on(removePhotoClicked , (state, { id }) => ({
        ...state,
        basket: /* remove the basket with given id */
      })),
    );
    

    Thus there is no need to 'obtain the basket records to allow me to remove an item from the basket`. But if you do for some other reason, use a selector.