最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular 2: {{object}} works, {{object.child}} throws error - Stack Overflow

programmeradmin1浏览0评论

Been working with Angular v1 for some time now and since Angular v2 came in Beta, been playing around with that.

Now I've got this piece of code, but can't get it to work, really don't know why. Somehow, when I print {{profileUser | json}} everything works fine (profileUser is an object).

But when I want to print a child of that object (for example {{profileUser.name}} or {{profileUser.name.firstName}}), Angular throws the following error:

EXEPTION: TypeError: undefined is not an object (evaluating 'l_profileUser0.name') in [ {{profileUser.name}} in ProfileComponent@4:11.

It's really confusing to me, should be just one of the simplest things around.. Just started with TypeScript btw..

Here is some 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);
          }
        )
      ;
    });
  }
}

And here is my 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);
      })
    ;
  }
}

Finally, the profile.html template:

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

or..

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

or..

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

FYI, the profileUser looks like this:

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

Would be great if somebody could help me out, this is really holding me back to get familiar with Angular v2. Thanks!

Been working with Angular v1 for some time now and since Angular v2 came in Beta, been playing around with that.

Now I've got this piece of code, but can't get it to work, really don't know why. Somehow, when I print {{profileUser | json}} everything works fine (profileUser is an object).

But when I want to print a child of that object (for example {{profileUser.name}} or {{profileUser.name.firstName}}), Angular throws the following error:

EXEPTION: TypeError: undefined is not an object (evaluating 'l_profileUser0.name') in [ {{profileUser.name}} in ProfileComponent@4:11.

It's really confusing to me, should be just one of the simplest things around.. Just started with TypeScript btw..

Here is some 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);
          }
        )
      ;
    });
  }
}

And here is my 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);
      })
    ;
  }
}

Finally, the profile.html template:

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

or..

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

or..

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

FYI, the profileUser looks like this:

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

Would be great if somebody could help me out, this is really holding me back to get familiar with Angular v2. Thanks!

Share Improve this question asked Dec 24, 2015 at 16:30 Aico Klein OvinkAico Klein Ovink 1,6472 gold badges14 silver badges21 bronze badges 6
  • 2 Elvis operator – Eric Martinez Commented Dec 24, 2015 at 16:38
  • why are you wrapping it in a promise btw? – fxck Commented Dec 24, 2015 at 16:51
  • I didn't at at first, guess you try just anything ;-) – Aico Klein Ovink Commented Dec 24, 2015 at 16:54
  • @foxx at the angular.io docs, they are using promises: angular.io/docs/ts/latest/tutorial/toh-pt4.html – Aico Klein Ovink Commented Dec 24, 2015 at 17:00
  • 1 Agreed with @foox, promises aren't necessary here since http.get returns an observable object (something similar to promises but more powerful). This answer could help you. – Thierry Templier Commented Dec 24, 2015 at 17:04
 |  Show 1 more comment

2 Answers 2

Reset to default 21

In fact your profileUser object is loaded from an HTTP request and it can be null at the beginning. The json pipe simply does a JSON.stringify.

It's what your error message said: undefined is not an object (evaluating 'l_profileUser0.name').

You need to be sure that your profileUser object isn't null to be able to get its name attribute and so on. This can be done using an *ngIf directive:

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

When the data will be there, the HTML block will be displayed.

As Eric stated the Elvis operator could also help you. Instead of having {{profileUser.name | json}}, you could use {{profileUser?.name | json}}.

Hope it helps you, Thierry

It happens because when your controller is created, the profileUser is undefined. And, when you use {{profileUser | json}} the filter json knows that you data is undefined and do nothing. When the profileUser is finally defined, the angular updates thw whole thing and then profileUser | json works. But, when you use {{ profileUser.anything | json}} you will get an error because profileUser starts undefined.

You can solve it, setting a empty profile to your variable at beginning of your controller, just like that:

profileUser = { name: {}};

This way, profileUser never will be undefined

发布评论

评论列表(0)

  1. 暂无评论