Search code examples
javascriptangulartypescriptrxjsngrx

ngrx removing item from list when using dispatch


I have angular 8 application. And i am using ngrx for state management.

But the problem is , that if I try to remove item, it wiil redirect to other tab. and not removing item.

So I have this:

reducer:

const intialState: Tutorial = {
  name: 'initial State',
  url: 'http://google.com'
};

export function tutorialReducer(state: Tutorial[] = [intialState], action: TutorialActions.Actions) {
  switch (action.type) {
    case TutorialActions.ADD_TUTORIAL:
      return [...state, action.payload];
    case TutorialActions.DELETE_TUTORIAL:
      state.splice(action.payload, 1);
      return state;
    default:
      return state;
  }
}

actions:

export class AddTutorial implements Action {
  readonly type = ADD_TUTORIAL;

  constructor(public payload: Tutorial) {}
}

export class RemoveTutorial implements Action {
  readonly type = DELETE_TUTORIAL;

  constructor(public payload: number) {}
}

export type Actions = AddTutorial | RemoveTutorial;

and remove template:

<div class="right" *ngIf="tutorials$">
  <h3>Tutorials</h3>

  <ul>
    <li (click)="delTutorial(i)" *ngFor="let tutorial of tutorials$ | async; let i = index">
      <a [href]="tutorial.url" target="_blank">{{ tutorial.name }}</a>
    </li>
  </ul>
</div>

and ts code:

export class ReadComponent implements OnInit {

  tutorials$: Observable<Tutorial[]>;

  constructor(private store: Store<AppState>) {
  this.tutorials$ = this.store.select('tutorial');
  }

 delTutorial(index){
    this.store.dispatch(new TutorialActions.RemoveTutorial(index));
  }
  ngOnInit() {
  }

}

and app.module.ts:

 imports: [
    BrowserModule,
    StoreModule.forRoot({tutorial: tutorialReducer}),
    AppRoutingModule
  ],

But so it doesnt remove item, but acturally opens a new tab.

ANd then I get this error:

core.js:9110 ERROR TypeError: Cannot assign to read only property '5' of object '[object Array]'
    at Array.splice (<anonymous>)
    at tutorialReducer (tutorial.reducers.ts:16)
    at combination (store.js:303)
    at store.js:1213
    at store.js:38

So what I have to change? So that you can remove a item from the list?

Thank you


Solution

  • The state is immutable. So, you cannot change the state in the reducer. You have to return a new modified value without changing the current state.

    case TutorialActions.DELETE_TUTORIAL:
      let newState = [...state]; 
      newState.splice(action.payload, 1);
      return newState;