question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Exceptions are not thrown when frozen objects are changed by an Angular template

See original GitHub issue

I 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:open
  • Created 7 years ago
  • Reactions:2
  • Comments:18 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
brandonrobertscommented, Sep 25, 2017

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.

1reaction
brandonrobertscommented, Sep 28, 2017

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Object.freeze() - JavaScript - MDN Web Docs
A frozen object can no longer be changed: new properties cannot be added, existing properties cannot be removed, their enumerability, ...
Read more >
Object.freeze not throwing exception in strict mode when ...
When using Object.freeze() in strict mode it's not throwing an exception when I attempt to modify a property of a frozen object.
Read more >
NG0100: Expression has changed after it was checked - Angular
Angular throws an ExpressionChangedAfterItHasBeenCheckedError when an expression value has been changed after change detection has completed. Angular only ...
Read more >
Ngrx store freeze reveals problems with shared state
Unfortunately without all scripts that modify the object properties being in a 'use strict' block, no exception is thrown by the frozen object....
Read more >
Top 18 Most Common AngularJS Developer Mistakes - Toptal
Common Mistake #16: Not Running The Unit Tests In TDD Mode​​ Tests will not make your code free of AngularJS error messages. What...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found