Aetherix
Aetherix

Reputation: 2250

Angular 2 binding: TypeError

Consider the below code, or see this plunk: https://plnkr.co/edit/mwPHfz?p=info.

Master

import {Component} from "angular2/core";
import {DetailComponent} from "./detail.component";
import {User} from "./user";
import {MOCKUSERS} from "./mock-users";

@Component({
    directives: [DetailComponent],
    selector: "master",
    template: `
        <h2>Master</h2>

        <div>
            <ul>
                <li *ngFor="#user of users" (click)="selectUser(user)">
                    {{user.firstName}} {{user.lastName}}
                </li>
            </ul>
        </div>

        <div>
            <detail [user]="selectedUser"></detail>
        </div>
    `
})
export class MasterComponent {
    users: User[] = MOCKUSERS;
    selectedUser: User;

    selectUser(user: User) {
        this.selectedUser = user;
    }
}

Detail

import {Component, Input} from "angular2/core";
import {User} from "./user";

@Component({
    selector: "detail",
    template: `
        <h2>Detail</h2>
        <div>
            <div>
                <input type="text" [(ngModel)]="user.firstName">
            </div>
            <div>
                <input type="text" [(ngModel)]="user.lastName">
            </div>
            <div>
                <button type="submit">Submit</button>
            </div>
        </div>
    `
})
export class DetailComponent {
    @Input()
    user: User;
}

User

export class User {
    firstName: string,
    lastName: string
}

When you click on a name in the list (master) the form (detail) should be updated. The first name and last name properties should appear in the firstName and lastName inputs respectively.

However, when you look in the developer tools, you can see the following error when loading the app:

EXCEPTION: TypeError: l_user0 is undefined in [user.firstName in DetailComponent@4:27]

So somehow the binding to user doesn't seem to be accepted. Can anyone tell why?

Upvotes: 0

Views: 132

Answers (3)

Yoav Schniederman
Yoav Schniederman

Reputation: 5391

you should initilize selectedUser parametes.

export class MasterComponent {
    users: User[] = MOCKUSERS;
    selectedUser: User = null;

    selectUser(user: User) {
        this.selectedUser = user;
    }
}


<div>
  <detail [user]="selectedUser"></detail>
</div>



@Component({
    selector: "detail",
    template: `
        <h2>Detail</h2>
        <div *ngIf="user !== null">
            <div>
                <input type="text" [(ngModel)]="user.firstName">
            </div>
            <div>
                <input type="text" [(ngModel)]="user.lastName">
            </div>
            <div>
                <button type="submit">Submit</button>
            </div>
        </div>
    `
})

export class DetailComponent {
    @Input() user: User = null;
}

Upvotes: 0

Mark-VII
Mark-VII

Reputation: 373

<ul class="list-group users-list">
    <li class="list-group-item"
        *ngFor="let user of users"
        (click)="selectUser(user)"
        [class.active]="user === activeUser">
        {{ user.name }} ({{ user.username }})
    </li>
</ul>

Upvotes: 0

Abdulrahman Alsoghayer
Abdulrahman Alsoghayer

Reputation: 16540

You are passing an undefined object (before selecting a user) to DetailComponent. You should only render the DetailComponent if there is a selectedUser.

<div *ngIf="selectedUser">
  <detail [user]="selectedUser"></detail>
</div>

Working plunker. In index.html, I had to replace the imported angular js file from angular.min.js to angular.dev.js to fix an unrelated issue on your plunker.

Upvotes: 3

Related Questions