2017-12-01 1 views
0

Ich erstelle eine Web-App für ein Universitätsprojekt, das aus zwei Teilen besteht: eine Web-API und ein Frontend, das mit dieser API verbunden ist. Die Web-App, die ich mache, ist eine Rezept-Website. Nachdem ich keine neuen Technologien wie Angular angefasst habe, nahm ich das Tutorial der Tour of Heroes auf ihrer Website und bin damit recht gut zurechtgekommen.Angular2: NgFor unterstützt nur die Bindung an Iterables wie Arrays

Allerdings bin ich jetzt an dem Punkt, wo ich verlinken muss keine Scheindatenquellen verwenden und stattdessen meine API verwenden, um Daten aus zu ziehen.

Ich habe mehrere Komponenten, und so habe ich die entsprechenden Dateien für den HTTP-Abschnitt des Tutorials enthalten, recipe.service.ts und recipes.component.html, für diesen Teil der App (die nur Dateien, die im Tutorial bearbeitet werden sollten

Es scheint mir, dass Angular nicht die Antwort als Array durch den Fehlercode liest, obwohl der angenommene Returntext JSON ist konnte nicht scheinen, die Antworten zu erhalten, um mit meinem Code richtig zu arbeiten.

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

Der Fehler, den ich in der Konsole bekommen werde, wenn der Winkel App ausgeführt wird:

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) 

einen Ausschnitt von dem, was die Anwendung soll zurückziehen (als 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" 
     } 
    ] 
} 

Wenn mir jemand helfen könnte wäre es super.

EDIT :) Danke - mein 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); 
    } 

} 
+1

Nun, Sie zeigen nicht Ihre Komponente, aber entpacken Sie das Array aus Ihrer Antwort? Klingt für mich, dass Sie nicht wollen und versuchen, Ihre Antwort zu wiederholen, die ein Objekt ist. – Alex

+0

Können Sie Ihre recipes.component.ts auch hinzufügen? – chayasan

+0

Wie würde ich das Array aus meiner Antwort extrahieren? –

Antwort

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

Weil Ihre Antwort ist ein Objekt, kein Array. Sie müssen this.recipes auf recipes.Recipes setzen. Nach:

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

scheint perfekt zu funktionieren. Vielen Dank. –

0

Sie geben die gesamte JSON-Antwort vom Dienst zurück, nicht nur das Array der Rezepte. Sie können ein Objekt nicht mit * ngFor iterieren. Ändern Sie this.recipes = Rezepte wie unten.

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