Angular 6:找不到类型为“object”的不同支持对象“[object Object]”。NgFor 只支持绑定到 Iterables,比如 Arrays

Jas*_*son 4 angular angular-httpclient angular6

我有一个组件从资产文件夹加载本地 json 文件(仅包含名称)。由于 HttpClient 负责将数据格式化为 json,所以这里没有使用 map。

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'

 export type cont= {name: string};

@Component({
  selector: 'my-app',
  template: `
    1st List
    <ul>
      <li *ngFor="let contact of contacts | async">{{contact.name}}</li>
    </ul>
    2st List
    <ul>
      <li *ngFor="let contact of contacts2 | async">{{contact.name}}</li>
    </ul>
    `
})
export class AppComponent {;
  contacts: Observable<cont[]>;
  contacts2: Observable<cont[]>;
  constructor (http: HttpClient) {
    this.contacts = http.get<cont[]>('http://localhost:4200/assets/contacts.json');               
    setTimeout(() => this.contacts2 = this.contacts, 500);
  }
}
Run Code Online (Sandbox Code Playgroud)

联系人.json

 {
"items": [
  { "name": "Mark Twain" },
  { "name": "Sherlock Holmes" }
]
Run Code Online (Sandbox Code Playgroud)

}

可以通过http://localhost:4200/assets/contacts.json在浏览器上获取数据,但是当我尝试通过异步管道呈现相同的数据时,我在下面收到此错误。尝试了多种方法将 observable 转换为 Observable<[]> 但是没有人通过这种情况。这里有什么问题。如何将 httpclient 上的 json 数据转换为 Array ?尝试关注类似的帖子,但没有任何帮助)?

错误

And*_*riy 6

您正在尝试迭代一个对象:

{
  "items": [
    { "name": "Mark Twain" },
    { "name": "Sherlock Holmes" }
  ]
}
Run Code Online (Sandbox Code Playgroud)

你应该迭代 contacts.items

<ul>
  <li *ngFor="let contact of (contacts | async)?.items">{{contact.name}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

或者只是使用可观察的地图:

const url = 'http://localhost:4200/assets/contacts.json';
this.contacts = http.get<cont[]>(url).pipe(map(data => data.items)); 
Run Code Online (Sandbox Code Playgroud)

另一种解决方案使用 Symbol.iterator

我添加它只是因为它是有趣的(在我看来)方法,尽管在这种情况下不实用。

我可以对异步对象进行迭代:

<ul>
  <li *ngFor="let contact of contacts | async">{{contact.name}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

但我将通过添加可迭代协议将此对象转换为可迭代

const url = 'http://localhost:4200/assets/contacts.json';
this.contacts = http.get<cont[]>(url).pipe(
  map((data: any) => {
    data[Symbol.iterator] = () => data.items[Symbol.iterator]();
    return data;
  })
);
Run Code Online (Sandbox Code Playgroud)

线

data[Symbol.iterator] = () => data.items[Symbol.iterator]()
Run Code Online (Sandbox Code Playgroud)

将对象上的迭代(默认情况下不可能)重定向到其items数组上的迭代。

我创建了一个STACKBLITZ 来证明这一点