【问题标题】:Converting Observable to array angular 4 HTTP将 Observable 转换为数组 Angular 4 HTTP
【发布时间】:2017-10-06 21:36:36
【问题描述】:

我有一项服务正在本地获取书籍列表我收到此错误:

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 (

这是我的服务类:

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

这是组件:

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.component.html:

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

这是服务返回的数据:
console.log(bookss) result

【问题讨论】:

  • 此错误不在TS 端,它是HTML 迭代错误。请您发布BooksComponent.html 文件。错误在该文件的*ngFor 中。
  • 如果我们还可以看到从服务中检索到的您的数据的 console.log,那就太好了。有没有可能,即使您期待一系列书籍 (Books[]),您也会收到一些其他数据结构?
  • 感谢回复我在问题中添加了html和console.log,请查看并告诉我有什么问题非常感谢
  • 我认为正如您从控制台看到的那样,书籍是一个对象而不是数组,我认为它应该是一个数组,因此 ngfor 可以遍历它
  • 如何将其转换为数组??我应该在服务或组件中的哪个位置执行此操作?

标签: angular http typescript angular4-httpclient


【解决方案1】:

如前所述,您接收的不是数组,而是具有嵌套对象的对象。您需要使用自定义管道,或者然后转换组件中的数据。

如果您想使用自定义管道...这是要走的路,如果您需要维护密钥!..我认为在这种情况下您需要它。 p>

导入必要的东西:

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

ValuesPipe 添加到模块中的declarations 数组中,并在模板中按以下方式使用它:

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

为了以后的提示,请记住,如果您使用管道,请记住它是否需要 impure 管道非常昂贵并且经常被烧掉。


如果数据的构建不需要保持与接收时相同。因此,在收到数据后,我会调用一个方法,使您的数据可迭代,但是,在这里您松开了密钥(需要进行一些修改以保留密钥)

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

【讨论】:

  • PS,这很可能是重复的,但我在搜索时找不到一个,这适用于这组特定的数据构建方式。
猜你喜欢
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2020-11-30
  • 2018-07-08
  • 2016-06-02
  • 2014-10-24
  • 2020-12-01
相关资源
最近更新 更多