Reputation: 2480
This is my first component in angular. Here it is:
import { Component } from '@angular/core';
export class Hero{
id:number;
name:string;
}
const HEROES: Hero[]=[
{id:11,name:'Mr. Nice'},
{id:12,name:'Arco'},
{id:13,name:'Gillette'},
{id:14,name:'Celeritas'},
{id:15,name:'Magneta'},
{id:16,name:'RubberMan'},
{id:17,name:'Dynama'},
{id:18,name:'Dr. Iq'},
{id:19,name:'Magma'},
{id:20,name:'TOrnado'}
];
@Component({
selector: 'my-app',
template: `<h1>{{title}}</h1>
<h2>My heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
<h2>Details of {{selectedHero.name}}</h2>
<div><label>Id: </label>{{selectedHero.id}}</div>
<div>
<label>Name: </label>
<input [(ngModel)]="selectedHero.name"/>
</div>
`,
styles: [`
`]
})
export class AppComponent {
title = 'Tour of Heroes';
heroes = HEROES;
selectedHero: Hero;
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
}
I deleted styles
element because its big.
My template doesn't bind heroes
array, When I use this in template
element:
<input [(ngModel)]="selectedHero.name"/>
But when I delete above input, all heroes
from array are correctly displayed in a <ul>
list.
Why is it?
Upvotes: 2
Views: 651
Reputation: 16384
It's because Angular can't read selectedHero.name
while there is no selected hero. You can (and need to) show this input only when you have selectedHero
using *ngIf
directive, like this:
<input *ngIf="selectedHero" [(ngModel)]="selectedHero.name"/>
And not only for input
- for every element where you're using selectedHero
:
<h2 *ngIf="selectedHero">Details of {{selectedHero.name}}</h2>
<div *ngIf="selectedHero"><label>Id: </label>{{selectedHero.id}}</div>
<div *ngIf="selectedHero">
<label>Name: </label>
<input [(ngModel)]="selectedHero.name"/>
</div>
Or better add a wrapper with one *ngIf
directive:
<div *ngIf="selectedHero">
<h2>Details of {{selectedHero.name}}</h2>
<div><label>Id: </label>{{selectedHero.id}}</div>
<div>
<label>Name: </label>
<input [(ngModel)]="selectedHero.name"/>
</div>
</div>
I remember, it was written somewhere in "Tour of Heroes" for Angular, it's not just my thoughts ;)
Upvotes: 1
Reputation: 3329
You do not set selectedHero
property, but still you try to display and modify it. Move hero details to section and add ngIf
to it to display it only when it's set:
<div *ngIf="selectedHero">
<h2>Details of {{selectedHero.name}}</h2>
<div><label>Id: </label>{{selectedHero.id}}</div>
<div>
<label>Name: </label>
<input [(ngModel)]="selectedHero.name"/>
</div>
</div>
Upvotes: 2