Angular2: no se puede leer la propiedad ‘nombre’ de indefinido

Estoy empezando a aprender Angular2. He estado siguiendo el Tutorial de Héroes proporcionado en angular.io. Todo funcionaba bien hasta que, molesto por el desorden de HTML usando la plantilla, utilicé la URL de la plantilla en su lugar y moví el HTML a un archivo llamado hero.html. El error que se genera es “No se puede leer la propiedad ‘nombre’ de indefinido”. Extrañamente, se puede acceder a la variable héroes que apunta a una matriz de objetos para que ngFor produzca la cantidad correcta de tags “li” según la cantidad de objetos en la matriz. Sin embargo, no se puede acceder a los datos de los objetos de la matriz. Además, incluso una variable simple que contiene algo de texto, no se mostrará con {{}} corchetes en el código HTML (ver el código provisto).

app.component.ts

import { Component } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './hero.html', styleUrls:['./styles.css'] }) export class AppComponent { title = 'Tour of Heroes'; heroes = HEROES; selectedHero:Hero; onSelect(hero: Hero):void{ this.selectedHero = hero; } } export class Hero{ id: number; name: string; } const HEROES: Hero[] = [ { id: 1, name: 'Mr. Nice' }, { id: 2, name: 'Narco' }, { id: 3, name: 'Bombasto' }, { id: 4, name: 'Celeritas' }, { id: 5, name: 'Magneta' }, { id: 6, name: 'RubberMan' }, { id: 7, name: 'Dynama' }, { id: 8, name: 'Dr IQ' }, { id: 9, name: 'Magma' }, { id: 10, name: 'Tornado' } ]; 

hero.html

 

{{title}}

My Heroes

  • {{hero.id}} {{hero.name}}

{{hero.name}} details!

{{hero.id}}

Aquí hay una foto:

enter image description here

La variable selectedHero es nula en la plantilla, por lo que no puede enlazar selectedHero.name como está. Debe usar el operador elvis para este caso:

  

La separación de [[ngModel)] en [ngModel] y (ngModelChange) también es necesaria porque no se puede asignar a una expresión que utiliza el operador elvis.

También creo que quieres usar:

 

{{selectedHero?.name}} details!

en lugar de:

 

{{hero.name}} details!

Solo necesitaba leer un poco más y se le habría presentado la directiva estructural * ngIf.

selectedHero.name todavía no existe porque el usuario aún tiene que seleccionar un héroe por lo que no está definido.

 

{{selectedHero.name}} details!

{{selectedHero.id}}

La directiva * ngIf mantiene selectedHero fuera del DOM hasta que se selecciona y, por lo tanto, se convierte en verdad.

Este documento me ayudó a entender las directivas estructurales.

Obtuvo este error porque siguió las instrucciones mal escritas en el tutorial de Heroes. Me encontré con lo mismo.

Específicamente, debajo del encabezado Mostrar nombres de héroe en una plantilla , indica:

Para mostrar los nombres de los héroes en una lista desordenada, inserte el siguiente fragmento de HTML debajo del título y encima de los detalles del héroe.

seguido por este bloque de código:

 

My Heroes

No le indica que reemplace el código de detalle anterior, y debería hacerlo. Es por eso que nos quedamos con:

 

{{hero.name}} details!

fuera de nuestro *ngFor .

Sin embargo, si se desplaza hacia abajo en la página, encontrará lo siguiente:

La plantilla para mostrar héroes debería verse así:

 

My Heroes

  • {{hero.id}} {{hero.name}}

Tenga en cuenta la ausencia de los elementos de detalle de los esfuerzos anteriores.

Un error como este por parte del autor puede resultar en una gran búsqueda de ganso. Con suerte, esta publicación ayuda a otros a evitar eso.

Esta línea

 

{{hero.name}} details!

está fuera *ngFor y no hay hero por hero.name tanto hero.name falla.

Para evitar esto, también podría inicializar el miembro seleccionado de su componente en un objeto vacío (en lugar de dejarlo indefinido).

En su código de ejemplo, eso daría algo como esto:

 export class AppComponent { title = 'Tour of Heroes'; heroes = HEROES; selectedHero:Hero = new Hero(); onSelect(hero: Hero):void{ this.selectedHero = hero; } }