Angular 错误 - NgFor 仅支持绑定到 Iterables,例如 Arrays
Angular error - NgFor only supports binding to Iterables such as Arrays
我正在使用 Node 后端构建一个 Angular 应用程序。这是我的 server.js
与 REST 端点相关的部分:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cors = require('cors');
var mysql = require('mysql');
const con = mysql.createConnection({
host: 'localhost',
user: 'myusername',
password: 'mypass',
database: 'somedb'
});
con.connect((err) => {
if (err) throw err;
console.log('Connected!');
});
app.use(bodyParser.json());
app.use(cors());
app.route('/api/levels').get((req, res) => {
con.query('SELECT * FROM level', (err, rows) => {
if (err)
res.send(JSON.stringify({ "status": 500, "error": err, "response": null }));
else
res.send(JSON.stringify({ "status": 200, "error": null, "response": rows }));
});
});
...
这部分有效,我已经通过 Postman 对其进行了测试,并得到以下响应:
{
"status": 200,
"error": null,
"response": [
{
"id": 1,
"title": "A1.1"
},
{
"id": 2,
"title": "A1.2"
},
... // the rest of the rows
]
}
Angular 服务:
@Injectable()
export class LevelService {
constructor(private http: HttpClient) {}
public getAll() {
return this.http.get('http://localhost:8000/api/levels/');
}
...
}
在组件中调用服务:
@Component({
selector: 'app-level-list',
templateUrl: './level-list.component.html',
styleUrls: ['./level-list.component.css']
})
export class LevelListComponent implements OnInit {
private levels: any[];
constructor(private levelService: LevelService) { }
ngOnInit() {
this.levelService.getAll().subscribe((data: any[]) => this.levels = data);
}
}
组件模板中使用的数据:
<ul class="level-list">
<li *ngFor="let level of levels">
<app-level-list-item [level]="level">
</app-level-list-item>
</li>
</ul>
最后它应该显示在主页上:
<div style="text-align:center">
<h1>{{ title }}</h1>
</div>
<p>{{introText}}</p>
<app-level-list></app-level-list>
但是,当我打开页面时,没有任何数据可见,并且在控制台中出现错误:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'.
NgFor only supports binding to Iterables such as Arrays.
我做错了什么?
您的服务响应似乎不是数组类型,而是:
interface ServiceResponse {
status: number;
error: any; // not apparent of the type
response: Level[];
}
我认为您需要更改 getAll
方法来映射它,以便响应是您的 Level[]
而不是 ServiceResponse
:
public getAll(): Observable<Level[]> {
return this.http.get<ServiceResponse>('http://localhost:8000/api/levels/')
.map(res => res.response);
}
Http 请求 returns 你是一个 Response 类型,你发送的实际数据在它的正文中。要获得它,请使用 .json() 方法,然后您可以像 属性 一样访问您的数组,就像上面提到的那样。
this.levelService.getAll().subscribe(data => this.levels = data.json().response);
更新
结果发现 HttpClient 不需要使用 .json() (实际上,我写那个的时候考虑的是 Http)
所以你可以写
this.levelService.getAll().subscribe(data => this.levels = data['response']);
根据文档,括号符号似乎是必需的。
我最近遇到了这个异常。归结为这样一个事实,即我试图对一些我认为是对象数组但实际上不是的东西进行 ngFor。它是单个物体或原始动物。
我建议在浏览器中调试它并验证 levels
实际上是一个数组。
您需要向您的服务添加一个映射方法并将响应转换为 JSON。将您的 Angular 服务更改为以下内容:
@Injectable()
export class LevelService {
constructor(private http: HttpClient) {}
public getAll() {
return this.http.get('http://localhost:8000/api/levels/')
.map(res=>res.json());
}
...
}
我正在使用 Node 后端构建一个 Angular 应用程序。这是我的 server.js
与 REST 端点相关的部分:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cors = require('cors');
var mysql = require('mysql');
const con = mysql.createConnection({
host: 'localhost',
user: 'myusername',
password: 'mypass',
database: 'somedb'
});
con.connect((err) => {
if (err) throw err;
console.log('Connected!');
});
app.use(bodyParser.json());
app.use(cors());
app.route('/api/levels').get((req, res) => {
con.query('SELECT * FROM level', (err, rows) => {
if (err)
res.send(JSON.stringify({ "status": 500, "error": err, "response": null }));
else
res.send(JSON.stringify({ "status": 200, "error": null, "response": rows }));
});
});
...
这部分有效,我已经通过 Postman 对其进行了测试,并得到以下响应:
{
"status": 200,
"error": null,
"response": [
{
"id": 1,
"title": "A1.1"
},
{
"id": 2,
"title": "A1.2"
},
... // the rest of the rows
]
}
Angular 服务:
@Injectable()
export class LevelService {
constructor(private http: HttpClient) {}
public getAll() {
return this.http.get('http://localhost:8000/api/levels/');
}
...
}
在组件中调用服务:
@Component({
selector: 'app-level-list',
templateUrl: './level-list.component.html',
styleUrls: ['./level-list.component.css']
})
export class LevelListComponent implements OnInit {
private levels: any[];
constructor(private levelService: LevelService) { }
ngOnInit() {
this.levelService.getAll().subscribe((data: any[]) => this.levels = data);
}
}
组件模板中使用的数据:
<ul class="level-list">
<li *ngFor="let level of levels">
<app-level-list-item [level]="level">
</app-level-list-item>
</li>
</ul>
最后它应该显示在主页上:
<div style="text-align:center">
<h1>{{ title }}</h1>
</div>
<p>{{introText}}</p>
<app-level-list></app-level-list>
但是,当我打开页面时,没有任何数据可见,并且在控制台中出现错误:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'.
NgFor only supports binding to Iterables such as Arrays.
我做错了什么?
您的服务响应似乎不是数组类型,而是:
interface ServiceResponse {
status: number;
error: any; // not apparent of the type
response: Level[];
}
我认为您需要更改 getAll
方法来映射它,以便响应是您的 Level[]
而不是 ServiceResponse
:
public getAll(): Observable<Level[]> {
return this.http.get<ServiceResponse>('http://localhost:8000/api/levels/')
.map(res => res.response);
}
Http 请求 returns 你是一个 Response 类型,你发送的实际数据在它的正文中。要获得它,请使用 .json() 方法,然后您可以像 属性 一样访问您的数组,就像上面提到的那样。
this.levelService.getAll().subscribe(data => this.levels = data.json().response);
更新
结果发现 HttpClient 不需要使用 .json() (实际上,我写那个的时候考虑的是 Http) 所以你可以写
this.levelService.getAll().subscribe(data => this.levels = data['response']);
根据文档,括号符号似乎是必需的。
我最近遇到了这个异常。归结为这样一个事实,即我试图对一些我认为是对象数组但实际上不是的东西进行 ngFor。它是单个物体或原始动物。
我建议在浏览器中调试它并验证 levels
实际上是一个数组。
您需要向您的服务添加一个映射方法并将响应转换为 JSON。将您的 Angular 服务更改为以下内容:
@Injectable()
export class LevelService {
constructor(private http: HttpClient) {}
public getAll() {
return this.http.get('http://localhost:8000/api/levels/')
.map(res=>res.json());
}
...
}