Angular2 * ngFor:“无法读取未定义的属性'0'”

时间:2016-09-06 08:18:58

标签: arrays json object angular ngfor

我尝试从JSON文件中获取数据以构建表单。

以下是我的模板的一部分:

  <div class="form-group">
    <label for="power">Power</label>
    <select class="form-control" id="power" required>
      <option *ngFor="let p of heroes" [value]="p.level">{{p.level}}</option>
    </select>
  </div>

以下是远程JSON文件的一部分:

{
    "data": [
        {
            "level": "newbie",
            "places": [
                {
                    "place": "earth",
                    "categories": [
                        {
                            "category": "human",
                            "values": [
                                ...

它没有问题,我在newbie菜单中获得了select和其他选项。 但我想循环播放地点,所以我用这种方式编辑html模板:

  <div class="form-group">
    <label for="power">Power</label>
    <select class="form-control" id="power" required>
      <option *ngFor="let p of heroes[0].places" [value]="p.place">{{p.place}}</option>
    </select>
  </div>

以下是我用来从JSON文件中获取数据的服务:

@Injectable()
export class HeroService {
    private url = 'app/mockups/heroes.json';

    constructor(private http: Http) { }

    getHeroes(): Promise<Hero[]> {
        return this.http.get(this.url)
            .toPromise()
            .then(response => response.json().data as Hero[])
            .catch();
    }
}

这是hero.component

export class HeroComponent implements OnInit {
    heroes: Hero[];

    constructor(private heroService: HeroService) { }

    ngOnInit():void {
        this.getHeroes();
}

    getHeroes(): void {
        this.heroService.getHeroes().then(heroes => this.heroes = heroes);
  }

但我得到“无法读取未定义的属性'0'错误。

为什么?

3 个答案:

答案 0 :(得分:10)

我想你想要的是

*ngFor="let p of heroes?.data"

因为heroes似乎是一个对象,而ngFor只能迭代数组。 level属性也在数组项中。

答案 1 :(得分:3)

我弄明白了这个问题。我收到此错误是因为我异步获取数据,当Angular第一次尝试解析绑定时,数据仍为空,因此heroes[0]失败。

所以我解决了初始化heroes数组并使用“Elvis运算符”的问题:

heroes: Hero[];而不是组件中的heroes: Hero[] = [];

heroes[0]?.places代替html模板中的heroes[0].places

答案 2 :(得分:2)

作为@Gunter Zochbauer解决方案的替代方案,您可以将heroes声明为合适类型的Array属性。如果您有任何具有heroes所有属性的类,则将heroes属性声明为:

heroes:Array<Heroes> //Assuming class name is Heroes

并在构造函数中初始化它,如下所示:

constructor(){
...    
this.heroes=new Array<Heroes>();
}

在你的ngFor循环中,只需访问类属性,如下所示:

<option *ngFor="let p of heroes" [value]="p.place">{{p.place}}</option>

希望它有所帮助。