2017-10-06 2 views
1

J'ai un service qui récupère une liste de livres que j'obtenir localement cette erreur:Conversion Observable à un tableau angulaire 4 HTTP

BooksComponent.html:2 ERROR Error: Cannot find a differ supporting object 
'[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays. 
    at NgForOf.webpackJsonp.../../../common/@angular/common.es5.js.NgForOf.ngOnChanges (common.es5.js:1681) 
    at checkAndUpdateDirectiveInline (

Voici ma classe de service:

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/Rx'; 
import { Books } from './books'; 

@Injectable() 
export class FetchbooksService { 
books:any[]; 
    constructor(private _http:Http) { } 
    fetch():Observable<Books[]>{ 
    return this._http.get('./assets/books.json').map(
     (response:Response)=> <Books[]>response.json(), 
     error => console.log(error) 
    ).do(data => console.log(data)); 
    } 
} 

et c'est le composant:

import { Component, OnInit } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { FetchbooksService } from '../fetchbooks.service'; 
import { Books } from '../books'; 
@Component({ 
    selector: 'app-books', 
    templateUrl: './books.component.html', 
    styleUrls: ['./books.component.css'] 
}) 
export class BooksComponent implements OnInit { 
bookss:Books[]; 
    constructor(private _bookservice: FetchbooksService) { 
    _bookservice.fetch().subscribe(
    (bookss)=> this.bookss = bookss, 
     error => console.log(error)= 
    ); 

    } 

    ngOnInit() { 
} 

} 

Books est une interface s'il vous plaît me dire ce que je fais mal?

c'est books.component.html:

<ul> 
    <li *ngFor = "let book of bookss "> 
    Book: {{book.title}} 
    </li> 
</ul> 

et ce sont les données renvoyées par le service:
console.log(bookss) result

+3

Cette erreur est pas dans le côté 'admissible TS, c'est une erreur d'itération HTML. Pourriez-vous poster le fichier 'BooksComponent.html' s'il vous plait. L'erreur est dans '* ngFor' de ce fichier. –

+0

Si nous pouvions également voir le fichier 'console.log' de vos données récupérées du service, ce serait génial. Y a-t-il une chance que, même si vous attendez une série de livres ('Books []'), vous receviez une autre structure de données? –

+0

merci pour la réponse, j'ai ajouté le html et console.log dans la question s'il vous plaît regardez-le et dites-moi ce qui ne va pas avec beaucoup merci – user3368703

Répondre

0

Comme mentionné précédemment, vous ne recevez pas un tableau, mais un objet objets imbriqués. Vous devez utiliser un canal personnalisé ou transformer les données dans le composant.

Si vous voulez aller avec le tuyau personnalisé ... C'est la voie à suivre, si vous avez besoin de maintenir la clé! .. dont j'ai l'image dont vous avez besoin dans ce cas.

importation choses nécessaires:

import { Pipe, PipeTransform } from '@angular/core'; 

@Pipe({ name: 'keys' }) 
export class ValuesPipe implements PipeTransform { 
    transform(value: any, args?: any[]): any[] { 
     let keyArr: any[] = Object.keys(value), 
      dataArr = []; 
     keyArr.forEach((key: any) => { 
      dataArr.push(value[key]); 
     }); 
     return dataArr; 
    } 
} 

ajouter le ValuesPipe à votre tableau declarations dans votre module, et l'utiliser comme suit dans le modèle:

<div *ngFor="let book of bookss | keys"> 
    {{book.author }} : {{ book.title }} 
</div> 

Juste pour bout avenir, souvenez-vous, Si vous allez avec le tuyau, rappelez-vous si le tuyau doit être très coûteux et souvent utilisé.


Si la génération des données n'a pas besoin de rester la même que lorsqu'elle a été reçue. Donc, après avoir reçu les données que je qualifierais une méthode qui rend vos données itératives, MAIS, là, vous perdez la clé (nécessite une modification de garder la clé)

_bookservice.fetch().subscribe(
(bookss) => { 
    this.bookss = bookss.books; 
    this.transform(); 
}, 
    error => console.log(error) 
); 

transform(books) { 
    let keyArr: any[] = Object.keys(books), 
    dataArr = []; 
    keyArr.forEach((key: any) => { 
     dataArr.push(books[key]); 
    }); 
    return dataArr; 
} 
+0

PS, ce très probablement un doublon, mais je ne pouvais pas trouver un lors de la recherche, ce qui s'appliquerait avec cet ensemble spécifique de la façon dont les données sont construites. – Alex