角度错误 - NgFor仅支持绑定到Iterables,例如Arrays

时间:2018-04-04 16:19:22

标签: angular ngfor

我正在构建一个带有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
    ]
}

角度服务:

@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.

我做错了什么?

4 个答案:

答案 0 :(得分:3)

看起来您的服务响应不是数组类型,而是:

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);
}

答案 1 :(得分:2)

Http请求返回一个响应类型,您发送的实际数据在其正文中。要获得它,请使用.json()方法,之后您可以像上面提到的那样访问属性,就像属性一样。

&#13;
&#13;
this.levelService.getAll().subscribe(data => this.levels = data.json().response);
&#13;
&#13;
&#13;

更新

有人说没有必要为HttpClient使用.json()(实际上,当我写这篇文章的时候我正在考虑Http) 所以你可以写

&#13;
&#13;
this.levelService.getAll().subscribe(data => this.levels = data['response']);
&#13;
&#13;
&#13;

根据文档,似乎需要括号表示法。

答案 2 :(得分:0)

我最近遇到了这个例外。它归结为这样一个事实,即我试图用一些我认为是一系列物体的东西,但实际上并非如此。这是一个单一的对象或一个主要的对象。

我建议在浏览器中调试它并验证levels实际上是一个数组。

答案 3 :(得分:0)

您需要向服务添加map方法并将响应转换为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());
  }
  ...
}