web-dev-qa-db-fra.com

Angular 2: TypeError: l_thing0 n'est pas défini dans [{{thing.title}} dans AppComponent @ 4: 44]

Je reçois une erreur étrange dans mon application. Il est supposé imprimer {{thing.title}} à partir d'un objet, mais cela indique une erreur dans la console:

EXCEPTION: TypeError: l_thing0 is undefined in [{{thing.title}} in AppComponent@4:44]

Je ne sais pas d'où provient l_thing0. Si j'essaie d'afficher {{thing}}dans la page, il affiche [object Object]. Si j'essaie de JSON.stringify(this.thing) (voir la fonction showObj()), il affiche correctement l'objet stringifié. Mais si j'essaie d'accéder à un attribut tel que {{thing.title}}, j'obtiens l'erreur que l_thing0 n'est pas défini.

Voici app.component.ts:

import {Component, OnInit} from 'angular2/core';
import {Thing} from './thing';
import {ThingService} from './thing.service';
import {SubThingComponent} from "./subthing.component";

@Component({
    selector: 'thing-app',
    template: `
        <div class="container">
            <div class="row">
                <div class="col-md-12">
                    <h1>{{thing.title}} <a href="#" (click)="showObj()" class="btn btn-default">Show Stringified Obj</a></h1>
                    <subthing></subthing>
                </div>
            </div>
        </div>
    `,
    styles:[`

    `],
    directives: [SubThingComponent],
    providers: [ThingService]
})

export class AppComponent implements OnInit {

    constructor(private _thingService: ThingService) { }

    public thing: Thing;

    showObj() {
        // This correctly shows the stringified object
        alert(JSON.stringify(this.thing));
    }

    getThing() {
        this._thingService.getThing().then(thing => this.thing = thing);
        // This correctly logs the object
        setTimeout(() => {console.log('thing', this.thing)}, 5000);
    }

    ngOnInit() {
        this.getThing();
    }
}

Des idées?

24
Josh

Le problème est que la première fois que vous chargez la page, thing n'est toujours pas défini, sa valeur réelle est définie ultérieurement de manière asyncronante. Ainsi, lors de la première tentative d'accès à la propriété, une exception est émise. L'opérateur ? elvis est un raccourci vers une vérification de zéro: 

{{thing?.title}}

Mais c’est généralement une meilleure idée plus performante de ne même pas essayer de rendre le composant tant que vous n’avez pas l’objet réel en ajoutant quelque chose comme:

<h1 *ngIf="thing">

au conteneur.

50
Langley

bien que j'arrive en retard à la soirée, je pensais que cela pourrait aider ceux qui utilisent Angular 5. Bizarrement, l'opérateur elvis ne fonctionnera pas dans la boucle * ngFor, mais fonctionne pour * ngif. Alors, voici mon code pour résoudre le problème.

<div *ngIf = "fullObject?.objProperty">
      <h1>{{fullObject.objProperty1}}</h1>
      <div *ngFor = "let o of fullObject.objPropertyArray">
          <h3>{{o._subheader}}</h3>
          <p>
              {{o._subtext}}
          </p>
        </div>
  </div>
</div>
3
sagars01

Vous pouvez également définir une nouvelle variable isFinished sur false avant de récupérer des données du serveur ou de la fonction asynchrone et après avoir reçu les données, définissez-la sur true. Puis mettez la variable isFinished dans *ngIf pour vérifier si le processus serveur/fonction est terminé? 

0
Reza Neghabi