Felipe Micali
Felipe Micali

Reputation: 847

Angular Ngrx Store and two-way data binding

I'm learning how to use the ngrx/store library in Angular 5 and I noticed an unexpected behavior... Please, help me understand if this is the default behavior for this library, because I really wasn't expecting this at all...

Well, my objective is to create a singleton store for storing application config and multiple states for all my components, so when a component updates the store, all subscribed components receives the updated store.

In one of my components I'm using the following constructor:

newItems: any

constructor (
private _store: Store<State>
) {

_store.select('operations').subscribe(state => {
  console.log(state)
  this.newItems = state.newItems
})

}

So I grab the current state of my store and set "this.newItems" variable to "state.newItems". I have some inputs in my template binded with some properties of "newItems", like this:

itemProperties: any = [
{
  name: 'Description',
  key: 'desc'
},
{
  name: 'Manufacturer',
  key: 'manufacturer'
},
{
  name: 'Model',
  key: 'model'
},
{
  name: 'Observation',
  key: 'genObs'
}
]

<div *ngFor="let prop of itemProperties" class="gen-label-input" [ngClass]="{'filled': newItems[prop.key]}">
    <label>{{prop.name}}</label>
    <input [(ngModel)]="newItems[prop.key]">
</div>

I was expecting to need to dispatch an action in my component to actually modify my store, but it seems that the two-way data binding through [(ngModel)] is doing this automatically, without the need of any actions at all! I just modify my input and my store is updated, and the updated version is automagically available through my entire application.

Is this the expected behavior of ngrx/store when I assing one store property to a component variable and combine it with [(ngModel)]?

If yes, this is really good in some cases, as I don't have to create inumerous actions to modify my store properties. But I'm worried this is some kind of error that I'm not being able to identify.

Thanks in advance!

Upvotes: 4

Views: 6533

Answers (2)

Oleksandr Poshtaruk
Oleksandr Poshtaruk

Reputation: 2146

You should create a copy of items from store when you receive them

 this.newItems = state.newItems.map((item) => Object.assign({}, item))

And yes, it is expected behavior if value is array or object

Upvotes: 4

ibenjelloun
ibenjelloun

Reputation: 7713

Yes it is the expected behavior and you are right the state should be immutable.

You can use ngrx-store-freeze in dev mode to help you detect when you do something you should not be doing.

Upvotes: 0

Related Questions