2015-12-24 1 views
7

Travailler avec Angular v1 depuis quelque temps maintenant et depuis qu'Angular v2 est arrivé en bêta, a joué avec ça.Angular 2: {{object}} fonctionne, {{object.child}} renvoie l'erreur

Maintenant, j'ai ce morceau de code, mais je n'arrive pas à le faire fonctionner, je ne sais vraiment pas pourquoi. D'une certaine manière, quand j'imprime {{profileUser | json}} tout fonctionne bien (profileUser est un objet).

Mais quand je veux imprimer un enfant de cet objet (par exemple {{profileUser.name}} ou {{profileUser.name.firstName}}), angulaire lancers francs l'erreur suivante:

EXEPTION: TypeError: undefined is not an object (evaluating 'l_profileUser0.name') in [ {{profileUser.name}} in [email protected]:11.

Il est vraiment déroutant pour moi, devrait être que l'une des choses les plus simples autour .. Tout a commencé avec tapuscrit btw ..

Voici un code - ProfileService.ts:

import { Injectable } from 'angular2/core'; 
import { Headers } from 'angular2/http'; 
import { API_PREFIX } from '../constants/constants'; 
import { AuthHttp } from 'angular2-jwt/angular2-jwt'; 
import 'rxjs/add/operator/map'; 

@Injectable() 
export class ProfileService { 

    API_PREFIX = API_PREFIX; 

    constructor(private _authHttp:AuthHttp) { 
    } 

    getProfileData(username:string):any { 
    return new Promise((resolve, reject) => { 
     this._authHttp.get(API_PREFIX + '/users/username/' + username) 
     .map(res => res.json()) 
     .subscribe(
      data => { 
      resolve(data.data); 
      }, 
      err => { 
      reject(err); 
      } 
     ) 
     ; 
    }); 
    } 
} 

Et voici ma ProfileComponent:

import {Component, OnInit} from 'angular2/core'; 
import {RouteParams} from 'angular2/router'; 
import {ProfileService} from '../../services/profile.service'; 

@Component({ 
    selector: 'profile', 
    templateUrl: './components/profile/profile.html', 
    directives: [], 
    providers: [ProfileService] 
}) 

export class ProfileComponent implements OnInit { 

    public username:string; 
    public profileUser:any; 

    constructor(private _profileService: ProfileService, 
       private _params: RouteParams) { 
    this.username = this._params.get('username'); 
    } 

    ngOnInit() { 
    this.getProfileData(this.username); 
    } 

    getProfileData(username:string):void { 
    this._profileService.getProfileData(username) 
     .then(data => { 
     this.profileUser = data; 
     console.log(data); 
     }) 
    ; 
    } 
} 

Enfin, le modèle profile.html:

<pre> <!-- works! --> 
{{profileUser | json}} 
</pre> 

ou ..

<pre> <!-- throws the error --> 
{{profileUser.name | json}} 
</pre> 

ou ..

<pre> <!-- throws the error --> 
{{profileUser.name.firstName}} 
</pre> 

Pour votre information, le ProfilForumsVidéosInterviewsPodcastNewsletterAnciens ressemble à ceci:

{ 
    "id": "9830ecfa-34ef-4aa4-86d5-cabbb7f007b3", 
    "name": { 
    "firstName": "John", 
    "lastName": "Doe", 
    "fullName": "John Doe" 
    } 
} 

Si quelqu'un pouvait me aider, Cela me retient vraiment pour me familiariser avec Angular v2. Merci!

+2

[opérateur Elvis] (https : //angular.io/docs/ts/latest/guide/template-syntax.html) –

+0

pourquoi l'enveloppes-tu dans une promesse btw? – foxx

+0

Je n'ai pas au début, devinez que vous essayez n'importe quoi ;-) –

Répondre

21

En fait, votre objet profileUser est chargé à partir d'une requête HTTP et il peut être null au début. Le tube json fait simplement JSON.stringify.

C'est ce que votre message d'erreur a dit: undefined is not an object (evaluating 'l_profileUser0.name').

Vous devez être sûr que votre objet profileUser n'est pas nul pour pouvoir obtenir son attribut name et ainsi de suite. Cela peut être fait en utilisant une directive *ngIf:

<div *ngIf="profileUser"> 
    {{profileUser.name | json}} 
</div> 

Lorsque les données seront là, le bloc HTML sera affiché.

Comme Eric déclaré l'opérateur Elvis pourrait également vous aider. Au lieu d'avoir {{profileUser.name | json}}, vous pouvez utiliser {{profileUser?.name | json}}.

espérons qu'il vous aidera, Thierry

+0

Merci beaucoup! Cela vient de le faire. Mais est-ce nouveau en v2? Devrions-nous faire cela tout le temps? –

+1

En fait, Angular1, cela se fait implicitement. Vous n'avez pas d'erreur et rien n'est affiché. La discussion de ce [problème] (https://github.com/angular/angular/issues/791) pourrait vous intéresser ;-) –

3

Cela arrive parce que lorsque votre commande est créé, le profileUser est défini. Et, lorsque vous utilisez {{profileUser | json}} le filtre json sait que vos données sont indéfinies et ne font rien.Lorsque le profileUser est finalement défini, les mises à jour angulaires de tout cela et ensuite profileUser | json fonctionne. Mais, lorsque vous utilisez {{ profileUser.anything | json}}, vous obtiendrez une erreur car profileUser démarre undefined.

Vous pouvez résoudre, définir un profil vide à votre variable au début de votre contrôleur, comme ça:

profileUser = { name: {}}; 

De cette façon, profileUser ne sera undefined