Quiero mostrar los datos de mi backend (CodeIgniter) a mi frontend (Angular 4), pero aparece este error:

ERROR Error: No se puede encontrar un objeto de apoyo diferente '[objeto Objeto]' de tipo> 'objeto'. NgFor solo admite enlaces a iterables como matrices.

Este es mi componente:

import { BookService } from './../book.service';
import { Component, OnInit } from '@angular/core';
import { Book } from "../book";


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

  constructor(public bookService: BookService ) { }

  ngOnInit() {
    this.getBooks();
 }

  books:Book;
  getBooks(){
    this.bookService.getBooks()
    .subscribe(books=>{
      this.books = books;
    })

  }
}

Este es mi servicio:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map' ;

@Injectable()
export class BookService {

  constructor(private http: Http) {

  }

    books=[];
    getBooks(){
      return this.http.get("http://localhost/restserver/book/list_book.php")
      .map(res => res.json());
    } 


}

Mi .json:

{"status":true,"data":
[{"id":"1","title":"SAINS","author":"ERLANGGA","isbn":"089928778"},
{"id":"2","title":"Geography","author":"ERLANGGA","isbn":"089182372"},
{"id":"3","title":"Math","author":"Srilangka","isbn":"091283181"},
{"id":"4","title":"test","author":"test","isbn":"1283798127"},
{"id":"5","title":"AAAA","author":"BBB","isbn":"91092301290"},
{"id":"6","title":"BBB","author":"CCC","isbn":"01920192"}]}

Y esta es mi opinión:

<div class="container-fluid">
  <div class="row">
      <div class="card col-md-7">
          <div class="card-body">
            <table class="table table-responsive table-striped">
              <caption>List of Books</caption>  
              <thead>
              <tr>
                <th scope="col">#</th>
                <th scope="col">Title</th>
                <th scope="col">Author</th>
                <th scope="col">ISBN</th>
                <th scope="col">Actions</th>
              </tr>
            </thead>
            <tbody>
              <tr *ngFor="let book of books" >
                <th></th>
                <td>{{book.title}}</td>
                <td>{{book.author}}</td>
                <td>{{book.isbn}}</td>
                <td>
                  <button class="btn btn-primary "> Detail </button>
                  <button class="btn btn-success " [routerLink]="['/book-edit']"> Edit </button>
                  <button class="btn btn-danger "> Delete </button>                
              </td>
            </tr>           
          </tbody>
        </table>       
    </div>  
  </div>  
  <app-book-add class="col-md-5"></app-book-add>    
1
Arza 26 oct. 2017 a las 13:06

2 respuestas

La mejor respuesta

Problema :

Está asignando la respuesta completa a los libros, pero todo lo que necesita son datos.


1) Primera forma de solucionarlo

Cambie esta línea en el componente:

this.books = books;

Para

this.books = books.data;

2) O también puede hacer esto en la plantilla:

Cambia esto :

<tr *ngFor="let book of books" >

Para

<tr *ngFor="let book of books?.data" >
6
Vivek Doshi 26 oct. 2017 a las 10:12

books debe ser una colección de Book y luego establecer la propiedad data de la respuesta devuelta.

books:Book[]; //this should be change inside Component.

//service method should return data prop from it.
getBooks(){
  return this.http.get("http://localhost/restserver/book/list_book.php")
  .map(res => res.json().data);
} 
3
Pankaj Parkar 26 oct. 2017 a las 10:32