Search code examples
angularngrx

NgRx strange behavior


I'm coming from React/Redux, am I missing something really stupid ?

Changes are in the AddItem dispatch part, only that. CASE 1: not working as expected, every new item keeps updating with the successors uuid and remains bound to the NgModel input

export class AppComponent implements OnInit {
  shoppingItems$: Observable<Array<ShoppingItem>>;
  newShoppingItem: ShoppingItem = {
    id: uuid(),
    name: ''
  };

  constructor(private store: Store<AppState>) {}

  ngOnInit() {
    this.shoppingItems$ = this.store.select(store => store.shopping);
  }

  addItem(name: string) {
    this.newShoppingItem.id = uuid();
    this.store.dispatch(new AddItemAction(this.newShoppingItem));
  }

  removeItem(id: string) {
    this.store.dispatch(new RemoveItemAction(id));
  }
}

Html part (remains the same for the second case as well)

<form (ngSubmit)="addItem()">
  <input
    type="text"
    [(ngModel)]="newShoppingItem.name"
    placeholder="name"
    name="itemName"
  />
  <button type="submit">SUBMIT</button>
</form>

<ul>
  <li *ngFor="let item of shoppingItems$ | async" (click)="removeItem(item.id)">
    {{ item.id }} - {{ item.name }}
  </li>
</ul>
import {
  ShoppingAction,
  ShoppingActionsTypes
} from '../actions/shopping.actions';
import { ShoppingItem } from './../models/shopping-item.model';
const initialState: Array<ShoppingItem> = [
  {
    id: 'Ok Bro',
    name: 'Mauro'
  }
];

export function ShoppingReducer(
  state: Array<ShoppingItem> = initialState,
  action: ShoppingAction
) {
  switch (action.type) {
    case ShoppingActionsTypes.ADD_ITEM:
      return [...state, action.payload];
    case ShoppingActionsTypes.REMOVE_ITEM:
      return state.filter(item => item.id !== action.payload);
    default:
      return state;
  }
}

CASE 2: working correctly

addItem(name: string) {
    this.newShoppingItem.id = uuid();
    this.store.dispatch(new AddItemAction(this.newShoppingItem));
    this.newShoppingItem = {
      id: '',
      name: ''
    }
  }

Solution

  • When you dispatch the action, you keep a reference to the form model.

    The following should work:

     this.store.dispatch(new AddItemAction({...this.newShoppingItem}));