rgvassar
rgvassar

Reputation: 5811

Why Does Using a ViewChild in ngIf Cause Console Errors?

I get a bunch of console errors with the code below that say 'child in AppComponent@0:4' has changed after it was checked. Previous value: 'undefined'. Current value: '[object Object]'.

The problem is in the h1 element in the app.component. If I take the *ngIf out, the console errors go away, but I get an undefined error because child.header hasn't been initialized yet.

The application works just fine though. Should I just ignore the console errors? Is this a bug that might be fixed in a later version. Maybe there's a better/correct way to do what I'm trying to do without receiving console errors?

Here's the app component:

app/app.component.ts

import {Component, ViewChild} from 'angular2/core';
import {ChildComponent}from "./child.component";

@Component({
  directives: [ChildComponent],
    selector: 'my-app',
    template: `<h1 *ngIf="child">{{child.header}}</h1>
    <child></child>`
})
export class AppComponent { 
  @ViewChild(ChildComponent) child: ChildComponent;
}

Here's the child component:

app/child.component.ts

import {Component} from "angular2/core";

@Component({
    selector: "child",
    template: "<p>I'm the child</p>"
})

export class ChildComponent {
    public header: string = "Child Header!!";
}

app/main.ts just bootstraps the app:

import {bootstrap}    from 'angular2/platform/browser';
import {AppComponent} from './app.component';

bootstrap(AppComponent);

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">    
    <link rel="stylesheet" href="styles.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
    <script src="https://npmcdn.com/[email protected]/es6/dev/src/testing/shims_for_IE.js"></script>   

    <script src="https://code.angularjs.org/2.0.0-beta.13/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://npmcdn.com/[email protected]/lib/typescript.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.13/Rx.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.13/angular2.dev.js"></script>

    <script>
      System.config({
        transpiler: 'typescript', 
        typescriptOptions: { emitDecoratorMetadata: true }, 
        packages: {'app': {defaultExtension: 'ts'}} 
      });
      System.import('app/main')
            .then(null, console.error.bind(console));
    </script>
  </head>

  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

Here's a plunk.

Upvotes: 1

Views: 1855

Answers (1)

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

Reputation: 657821

Angular2 doesn't like binding to results of @ViewChild() because the result is updated by change detection and Angular produces the error mentioned when bindings change during change detection. In your case you don't need @ViewChile() though. You can use a template variable instead

template: `<h1 *ngIf="child">{{child.header}}</h1>
<child #child></child>

Your code of the AppComponent looks pretty weird anyway. How do you expect this to work? <child> should only be shown when it's shown?

Upvotes: 2

Related Questions