2015-12-24 32 views
7

Da tempo collabora con Angular v1 e da quando Angular v2 è entrato in Beta, ha giocato con questo.Angular 2: {{object}} funziona, {{object.child}} genera l'errore

Ora ho questo pezzo di codice, ma non riesco a farlo funzionare, davvero non so perché. In qualche modo, quando stampo {{profileUser | json}}, tutto funziona correttamente (profileUser è un oggetto).

Ma quando voglio stampare un bambino di quell'oggetto (ad esempio {{profileUser.name}} o {{profileUser.name.firstName}}), angolare lancia il seguente errore:

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

E 'davvero confuso per me, dovrebbe essere solo una delle cose più semplici intorno .. Appena iniziato con dattiloscritto btw ..

Ecco il codice - 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); 
      } 
     ) 
     ; 
    }); 
    } 
} 

E qui è il mio 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); 
     }) 
    ; 
    } 
} 

Infine, il modello profile.html:

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

o ..

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

o ..

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

Cordiali saluti, il profileUser assomiglia a questo:

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

sarebbe bello se qualcuno mi potrebbe aiutare, questo mi sta trattenendo per familiarizzare con Angular v2. Grazie!

+2

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

+0

perché lo stai avvolgendo in una promessa tra due? – foxx

+0

All'inizio non sapevo, provate solo qualche cosa ;-) –

risposta

21

In effetti l'oggetto profileUser viene caricato da una richiesta HTTP e può essere null all'inizio. Il tubo fa semplicemente un JSON.stringify.

È il messaggio di errore che diceva: undefined is not an object (evaluating 'l_profileUser0.name').

È necessario assicurarsi che l'oggetto profileUser non sia nullo per poter ottenere l'attributo name e così via. Questo può essere fatto utilizzando una direttiva *ngIf:

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

Quando i dati saranno lì, verrà visualizzato il blocco HTML.

As Eric ha dichiarato che l'operatore Elvis potrebbe anche aiutarti. Invece di avere {{profileUser.name | json}}, è possibile utilizzare {{profileUser?.name | json}}.

Spero che ti aiuta, Thierry

+0

Grazie mille! E 'appena fatto. Ma questo è nuovo in v2? Dovremmo farlo tutto il tempo? –

+1

Infatti, Angular1, questo viene fatto implicitamente. Non hai un errore e non viene visualizzato nulla. La discussione di questo [numero] (https://github.com/angular/angular/issues/791) potrebbe interessarti ;-) –

3

Succede perché quando viene creato il controller, il profileUser è indefinito. Inoltre, quando si utilizza {{profileUser | json}} il filtro json sa che i dati non sono definiti e non fanno nulla.Quando lo profileUser viene definitivamente definito, l'angolare aggiorna l'intera cosa e quindi profileUser | json funziona. Tuttavia, quando si utilizza {{ profileUser.anything | json}}, si verificherà un errore perché profileUser viene avviato undefined.

È possibile risolverlo, l'impostazione di un profilo vuoto per la variabile all'inizio del tuo controller, proprio così:

profileUser = { name: {}}; 

In questo modo, profileUser non sarà undefined