garethdn
garethdn

Reputation: 12373

Change detection appears to break after encountering error

UPDATE Looks like this is an issue that will hopefully be addressed by the Angular team.

https://github.com/angular/angular/issues/2413


I have a problem where Angular's (Beta 15) change detection seems to stop working after encountering an error - I'm not sure if Zone is unsubscribing from changes after the error.

The easiest way to reproduce the error is to attempt to reference a property of null or undefined.

The issue can be seen here.

@Component({
  selector: 'shell',
  template: `
    <h3>Shell</h3>
    <p>{{dummy.myArray[0].text}}</p>
    <button (click)="getUsers()">Get users!</button>
    <button (click)="setDummyTextToNull()">Break stuff!</button>

    <ul>
      <li *ngFor="#user of users">{{user.login}}</li>
    </ul>
  `
})

export class ShellComponent implements OnInit {

  public params;
  public users;
  public dummy;

  constructor(private _router:Router, 
    public routeParams:RouteParams,
    private _ghService:GithubService) {

    this.params = this.routeParams;
    this.subscribe();
  }

  ngOnInit() {
    this.dummy = {
      myArray: [
        { text: 'Some dummy text' }  
      ]
    };
  }

  setDummyTextToNull() {
    this.dummy = null;
  }

  getUsers() {
    this.getUsers();
  }

  subscribe() {
    this._ghService.users$.subscribe(data => this.onResponse(data), err => {
      console.warn('Could not fetch', err.status)
    });
  }

  getUsers() {
    this._ghService.loadUsers();
  }

  onResponse(data) {
    console.log('Successfully fetched users', data);

    this.users = this.shuffle(data);
  }

  shuffle(array) {
    var currentIndex = array.length, temporaryValue, randomIndex;

    // While there remain elements to shuffle...
    while (0 !== currentIndex) {

      // Pick a remaining element...
      randomIndex = Math.floor(Math.random() * currentIndex);
      currentIndex -= 1;

      // And swap it with the current element.
      temporaryValue = array[currentIndex];
      array[currentIndex] = array[randomIndex];
      array[randomIndex] = temporaryValue;
    }

    return array;
  }

}

Clicking "get users" will fetch github users and shuffle the list. Doing this repeatedly you can see the list being resorted. After forcing the template to reference a property of null the change detection appears to no longer work.

What I would expect is to get that error repeatedly if I click that button but in reality any error in the template effectively crashes the app and requires a refresh.

Has anyone experienced this and know of any way around this apart from using ngIfs and "elvis operators" everywhere?

Upvotes: 1

Views: 91

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657731

I's say this is as designed.

If you change

{{dummy.myArray[0].text}}

to

{{dummy?.myArray[0].text}}

you shouldn't get an error

Upvotes: 1

Related Questions