Angular2:NgFor仅支持绑定到诸如Arrays之类的Iterables

时间:2017-12-01 17:52:13

标签: javascript json node.js angular angular2-routing

我正在为大学项目创建一个Web应用程序,该应用程序分为两部分:Web API和连接到所述API的前端。我正在制作的网络应用程序是一个食谱网站。没有触及像Angular这样的新技术,我在他们的网站上参加了“英雄之旅”教程,并且相当不错。

但是,我现在必须链接不使用模拟数据源,而是使用我的API从中提取数据。

我有几个组件,因此我已经包含了本教程HTTP部分的相关文件, recipe.service.ts recipes.component.html ,对于应用程序的这一部分(应该在教程中编辑的唯一文件。

在我看来,Angular并没有通过错误代码将响应作为数组读取,尽管假定的返回文本是JSON。我已经看过这个问题,但似乎没有得到正确使用我的代码的答案。

recipe.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Recipe } from './recipe';
import { RECIPES } from './mock-recipes';
import { MessageService } from './message.service';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable()
export class RecipeService {

  private recipesURL = 'http://localhost:3000/api/recipes';

  constructor(
    private http: HttpClient,
    private messageService: MessageService) {}

  getRecipes(): Observable<Recipe[]> {
    //Todo: send the message after fetching heroes
    //this.messageService.add('RecipeService: fetched recipes');
    return this.http.get<Recipe[]>(this.recipesURL);
  }

  getRecipe(id: number): Observable<Recipe> {
    this.messageService.add(`RecipeService: fetched recipe id=${id}`);
    return of(RECIPES.find(recipe => recipe.recipeID === id));
    //return of(RECIPES.find(recipe => recipe.recipeName));
  }

  private log(message: string) {
    this.messageService.add('RecipeService: ' + message);
  }
}

recipes.component.html

<h2>My Recipes</h2>
<ul class="recipes">
  <li *ngFor="let recipe of recipes">
    <a routerLink="/detail/{{recipe.recipeID}}">
      <span class = "badge">{{recipe.recipeName}}</span> {{recipe.userID}}
    </a>
  </li>
</ul>

运行Angular应用程序时我在控制台中出现的错误:

ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
    at NgForOf.ngOnChanges (common.js:2537)
    at checkAndUpdateDirectiveInline (core.js:12092)
    at checkAndUpdateNodeInline (core.js:13598)
    at checkAndUpdateNode (core.js:13541)
    at debugCheckAndUpdateNode (core.js:14413)
    at debugCheckDirectivesFn (core.js:14354)
    at Object.eval [as updateDirectives] (RecipesComponent.html:3)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:14339)
    at checkAndUpdateView (core.js:13508)
    at callViewAction (core.js:13858)

应用程序应该撤回的片段(作为JSON):

{
    "Error": false,
    "Message": "Success",
    "Recipes": [
        {
            "recipeID": 1,
            "recipeName": "orci",
            "ingredients": "Vivamus metus arcu, adipiscing molestie, hendrerit at, vulputate vitae, nisl. Aenean lectus. Pellentesque eget nunc. Donec quis orci eget orci vehicula condimentum. Curabitur in libero ut massa volutpat convallis.",
            "method": "Vivamus in felis eu sapien cursus vestibulum. Proin eu mi. Nulla ac enim. In tempor, turpis nec euismod scelerisque, quam turpis adipiscing lorem, vitae mattis nibh ligula nec sem. Duis aliquam convallis nunc. Proin at turpis a pede posuere nonummy. Integer non velit.",
            "createdBy": 150,
            "postedTime": "2017-06-01 15:11:27"
        },
        {
            "recipeID": 2,
            "recipeName": "sit",
            "ingredients": "Suspendisse potenti. In eleifend quam a odio.",
            "method": "Donec semper sapien a libero. Nam dui. Proin leo odio, porttitor id, consequat in, consequat ut, nulla. Sed accumsan felis. Ut at dolor quis odio consequat varius. Integer ac leo.",
            "createdBy": 982,
            "postedTime": "2017-02-21 08:40:58"
        }
    ]
}

如果有人能帮助我,那就太棒了。

谢谢:)

编辑 - 我的recipes.component.ts

import { Component, OnInit } from '@angular/core';
import { Recipe } from '../recipe';
import { RecipeService } from '../recipe.service'

@Component({
  selector: 'app-recipes',
  templateUrl: './recipes.component.html',
  styleUrls: ['./recipes.component.css']
})
export class RecipesComponent implements OnInit {

  recipes: Recipe[];

  constructor(private recipeService: RecipeService) { }

  ngOnInit() {
    this.getRecipes();
  }

  getRecipes(): void {
    this.recipeService.getRecipes().subscribe(recipes => this.recipes = recipes);
  }

}

2 个答案:

答案 0 :(得分:0)

  getRecipes(): void {
    this.recipeService.getRecipes().subscribe(recipes => this.recipes = recipes.Recipes);
  }

因为您的响应是对象,而不是数组。您需要将this.recipes设置为recipes.Recipes。根据:

{
    "Error": false,
    "Message": "Success",
    "Recipes": [... //here is your array

答案 1 :(得分:0)

您从服务返回整个json响应,而不仅仅是recipes数组。您无法使用* ngFor迭代对象。更改 this.recipes =食谱,如下所示。

getRecipes(): void {
        this.recipeService.getRecipes().subscribe(recipes =>
        if(recipes){
          this.recipes = recipes.Recipes;
         }
        );
      }