Angular2: Não é possível ler a propriedade ‘name’ de undefined

Eu estou começando a aprender Angular2. Eu tenho seguido o Tutorial Heroes fornecido em angular.io. Tudo estava funcionando bem até que, incomodado com a confusão de HTML usando o modelo, usei o URL do modelo em seu lugar e movi o HTML para um arquivo chamado hero.html. O erro gerado é “Não é possível ler a propriedade ‘name’ de undefined”. Estranhamente, a variável heroes que aponta para um array de objects pode ser acessada de modo que ngFor produza a quantidade correta de tags “li” de acordo com o número de objects no array. No entanto, os dados dos objects da matriz não podem ser acessados. Além disso, mesmo uma variável simples contendo algum texto, não será exibida usando colchetes {{}} no HTML (veja o código fornecido).

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}}

Aqui está uma foto:

insira a descrição da imagem aqui

    A variável selectedHero é nula no template, então você não pode vincular o selectedHero.name como está. Você precisa usar o operador Elvis para este caso:

      

    A separação do [(ngModel)] em [ngModel] e (ngModelChange) também é necessária porque você não pode atribuir a uma expressão que usa o operador elvis.

    Eu também acho que você pretende usar:

     

    {{selectedHero?.name}} details!

    ao invés de:

     

    {{hero.name}} details!

    Você só precisava ler um pouco mais e teria sido apresentado à diretiva estrutural.

    selectedHero.name ainda não existe porque o usuário ainda não selecionou um herói para que ele retorne indefinido.

     

    {{selectedHero.name}} details!

    {{selectedHero.id}}

    A diretiva * ngIf mantém selecionado o Hero fora do DOM até que ele seja selecionado e, portanto, se torna vital.

    Este documento me ajudou a entender as diretrizes estruturais.

    Você estava recebendo este erro porque seguiu as instruções mal escritas no tutorial Heroes. Eu corri para a mesma coisa.

    Especificamente, sob o título Exibir nomes de heróis em um modelo , ele afirma:

    Para exibir os nomes dos heróis em uma lista não ordenada, insira o seguinte fragment de HTML abaixo do título e acima dos detalhes do herói.

    seguido por este bloco de código:

     

    My Heroes

    Ele não instrui você a replace o código de detalhe anterior, e deveria. É por isso que ficamos com:

     

    {{hero.name}} details!

    fora do nosso *ngFor .

    No entanto, se você rolar mais abaixo na página, você encontrará o seguinte:

    O modelo para exibir os heróis deve ficar assim:

     

    My Heroes

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

    Observe a ausência dos elementos de detalhe de esforços anteriores.

    Um erro como este pelo autor pode resultar em uma perseguição bastante selvagem. Espero que este post ajude os outros a evitar isso.

    Está linha

     

    {{hero.name}} details!

    está fora *ngFor e não há hero portanto hero.name falha.

    Isso evita isso, você também pode inicializar o membro selectedHero do seu componente para um object vazio (em vez de deixá-lo indefinido).

    Em seu código de exemplo, isso daria algo assim:

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