Exceptions are not thrown when frozen objects are changed by an Angular template
See original GitHub issueI realise this is more than likely going to be an issue on the side of Object.freeze() rather than this module but I was hoping by posting here there might be something that the module could do to compensate.
Unfortunately I was caught in a bad way by the freezing of action payloads (I’ve opened a separate issue to make this clearer for others) and spent a long couple of hours debugging this.
I have an object with 2 properties which are bound to 2 separate ngModels. I pass this object directly as the payload for an action and it then becomes frozen by this module, so any further changes in the view no longer affect the frozen object in the controller and there are no exceptions thrown so no indication that the bug is caused by the object being frozen.
Using Object.assign to return a new object to use as the payload resolves the issue easily, but knowing where the issue arose from in the first place is the tricky part.
Template:
<input [(ngModel)]="credentials.email">
<input [(ngModel)]="credentials.password">
Controller:
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
@Component({
selector: 'login',
template: require('./login.component.html')
})
export class LoginComponent {
public credentials: any = {};
constructor(
private store: Store<any>
) { }
/*
* once this function is called,
* updates to the view are no longer reflected in the controller
*/
public submit = () => {
this.store.dispatch({
type: 'login',
payload: this.credentials
});
}
}
/*
* using Object.assign() like this fixes the issue
*/
public submit = () => {
this.store.dispatch({
type: 'login',
payload: Object.assign({}, this.credentials)
});
}
Issue Analytics
- State:
- Created 7 years ago
- Reactions:2
- Comments:18 (4 by maintainers)
Yes, I’m suggesting you not use ngModel because its not geared towards immutability and its easy to mutate your state accidentally. If you have to use ngModel instead of something like reactive forms, you’ll have to use the method mentioned above of assigning the value of the payload to a new object before dispatching. I would also suggest looking into using Reactive Forms, as they provide you the same access to form inputs, a model to which can mutate without mutating your store, and a stream of the form values.
Ok, I see. If you could open a new issue with a small reproduction that would help. I don’t want this issue to get derailed if possible.