2017-02-16 27 views
0

我正在使用omdbapi.com API为电影数据制作一个简单的搜索引擎。我已经设置了服务获取数据和组件来创建视图,但是当我尝试连接到HTML我得到一个错误:如何在从Angular2的外部源获取JSON之后显示结果

Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays. Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

电影类

export class Movie { 
    constructor(
     Title: string, 
     Year: string, 
     Rated: string, 
     Released: string, 
     Runtime: string, 
     Genre: string, 
     Director: string, 
     Writer: string, 
     Actors: string, 
     Plot: string, 
     Language: string, 
     Country: string, 
     Awards: string, 
     Poster: string, 
     Metascore: string, 
     imdbRating: string, 
     imdbVotes: string, 
     imdbID: string, 
     Type: string, 
     Response: string 
    ) {} 

} 

这里我的组件:

import { Component, OnInit } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import { Subject } from 'rxjs/Subject'; 

//observable class extensions 
import 'rxjs/add/observable/of'; 
import 'rxjs/add/operator/switchMap'; 
import 'rxjs/add/operator/map'; 
//observable operators 
import 'rxjs/add/operator/catch'; 
import 'rxjs/add/operator/debounceTime'; 
import 'rxjs/add/operator/distinctUntilChanged'; 

import { MovieSearchService } from './movie-search.service'; 
import { Movie } from './movie'; 

@Component({ 
    selector: 'movie-search', 
    templateUrl: './movie-search.component.html', 
    styleUrls: ['./movie-search.component.css'], 
    providers: [MovieSearchService] 
}) 

export class MovieSearchComponent implements OnInit { 
    movies: Observable<Movie[]>; 
    private searchTerms = new Subject<string>(); 

    constructor(
     private movieSearchService: MovieSearchService, 
     private http: Http 
    ) {} 

    search(term:string) { 
     return this.searchTerms.next(term); 
    } 

    ngOnInit(): void { 
     this.movies = this.searchTerms 
     .debounceTime(300) // wait 300ms after each keystroke before considering the term 
     .distinctUntilChanged() // ignore if next search term is same as previous 
     .switchMap(term => term // switch to new observable each time the term changes 
     // return the http search observable 
     ? this.movieSearchService.search(term) 
      // or the observable of empty heroes if there was no search term 
     : Observable.of<Movie[]>([]) 
     ) 
     .catch(error => { 
      console.log("--------- Error -------"); 
      console.log(error); 

      return Observable.of<Movie[]>([]); 
     })  
    } 
} 

这是服务

import { Injectable } from '@angular/core'; 
import { Http, Jsonp } from '@angular/http'; 

import { Observable} from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 

import { Movie } from './movie'; 

@Injectable() 
export class MovieSearchService { 
    constructor(
     private http: Http, 
     private jsonp: Jsonp 
    ) {} 

    search(term: string): Observable<Movie[]> { 
     return this.http 
      .get(`http://www.omdbapi.com/?s=${term}`) 
      .map(response => { 
       return response.json().each() as Movie[] 
      }) 
    } 
} 

和视图

<div class="col-xs-12"> 
    <input #searchBox id="search-box" /> 
    <button (click)="search(searchBox.value)">Search</button> 
</div> 

<ul *ngIf="movies"> 
    <li *ngFor="let movie of movies"> 
     {{ movie.title }} 
    </li> 
</ul> 

我如何可以使视图显示每部电影的片名? 预先感谢您的时间。

+0

可能重复[http与Observable在Angular 2不能使用数据](http://stackoverflow.com/questions/41961693/http-with-observable-in-angular-2-cant-use-data) – AngularChef

+0

请发布API返回的JSON结构示例 –

回答

1

总是检查网络选项卡,看看您是否实际接收数据以及数据的外观如何。

对此进行测试。显然,你首先需要建立自己的网址是这样的:

return this.http.get('http://www.omdbapi.com/?s='+term) 

然后作为响应,它的建成是这样的:

{"Search":[{"Title":"24","Year":"2001–2010","imdbID".... 

所以你需要解压得到一个数组的内容:

.map(response => {response.json().Search}) 

,并订阅你的组件:

this.movieSearchService.search(term) 
    .subscribe(d => this.movies = d) 

,然后当你要显示你的标题:

<ul *ngIf="movies"> 
    <li *ngFor="let movie of movies"> 
     {{ movie.Title }} 
    </li> 
</ul> 

注意在上述代码SearchTitle。这是区分大小写的,因此您需要使用{{ movie.Title }}和大写字母T来显示数据。

这应该清理一下! :)

+0

感谢您的回复@ AJT_82 –

+0

欢迎您! :)如上所述,使用您的开发人员工具,例如F12中的chrome。然后打开您的网络选项卡并检查请求并查看是否得到回应。与您的网址有空的回应,这就是为什么你不能迭代。这是一张照片。检查我标记为黄色的部分:) http://imgur.com/a/RuClo – Alex

+0

对不起,我在完成之前偶然发布了我的答案。我得到一个错误:

Argument of type '(term: string) => Subscription | Observable' is not assignable to parameter of type '(value: string, index: number) => ObservableInput'. Type 'Subscription | Observable' is not assignable to type 'ObservableInput'. 
我相信这是因为我宣布电影作为一个观察的对象,如电影:可观察 影片包含结构(名称,年份等..) 如果我没有声明它是可观察的,我应该如何声明可变电影? –

相关问题