如何更改JSON返回的数据?

时间:2019-07-08 17:47:19

标签: angular rxjs angular2-observables

我正在使用OMDB API(在线电影DB)。我创建了一个返回期望的数据类型的接口。通过http get方法请求数据时,返回的数据为:{搜索:Array(10),totalResults:“ 31”,响应:“ True”}。我需要的数据在搜索数组中。订阅时,我使用res.Search来访问此信息:subscribe((res)=> {res = this.movi​​eResults = res.Search;但是错误提示我的界面上不存在Search。如何解决此问题?

/ *我的界面* /

export interface SearchInterface {
    Poster: string;
    Title: string;
    Type: string;
    Year: string;
    imdbID: string;
}

导出默认SearchInterface;

/ *服务中的get方法* /

searchFilm(name: string): Observable<SearchInterface> {
    return this.http.get<SearchInterface>(this.searchUrl + this.apiKey + '&s=' + name);
  }

/ *订阅组件中的可观察对象* /

/* GET request*/
  getData(event) {
    const film = event.target.value;
    this.data.searchFilm(film)
    .subscribe( (res) => {
      /** Sort out res.Search issue */
      res = this.movieResults = res.Search;
      console.log(res);
    });
  }

4 个答案:

答案 0 :(得分:1)

这里涉及两个数据结构:您在问题中描述的由http服务返回的外部结构:

interface ActualResponse {
  Search: Array<SearchInterface>;
  totalResults: string;
  Response: string;
}

您唯一关心的对象用于Search数组的每个元素:SearchInterface。

您的服务不会改变您从服务器获得的响应。因此它的返回类型不可能是Observable<SearchInterface>:服务器返回的是ActualResponse,所以它应该是Observable<ActualResponse>

但是,由于您不在乎实际响应的其他部分,因此更好的设计是将实际响应转换为您实际关心的内容:Array<SearchInterface>。您可以使用map运算符来做到这一点:

searchFilm(name: string): Observable<Array<SearchInterface>> {
  return this.http.get<ActualResponse>(this.searchUrl + this.apiKey + '&s=' + name).pipe(
    map(response => response.Search)
  );
}

答案 1 :(得分:0)

因为您的SearchInterface包含密钥

Poster: string;
Title: string;
Type: string;
Year: string;
imdbID: string;

但是您的数据包含密钥

Search: Array(10), 
totalResults: "31", 
Response: "True"

您可以做一件事情-

searchFilm(name: string): Observable<any> {
    return this.http.get<any>(this.searchUrl + this.apiKey + '&s=' + name);
  }

movieResults: SearchInterface;

答案 2 :(得分:0)

@ Amitk88为什么要两次导出SearchInterface mock.As<IQueryable<TEntity>>().Setup(m => m.Provider).Returns(queryProviderMock.Object); export interface SearchInterface

也不要这样分配变量 export default SearchInterface;

res = this.movieResults = res.Search;

检查您收到的回复。我没有将“搜索”视为您界面中的关键,但是您希望在响应中找到“搜索”。 如果您希望“搜索”成为响应中的关键,请将其包含在界面中

答案 3 :(得分:0)

我正在创建一个堆栈炸弹,这里已经有3个答案了:)

@JB Nizet的回答非常优雅,这也是我建议的。无论如何,这是我的贡献:

// random.service.ts

searchFilm(name: string): Observable<SearchInterface[]> {
    return this.http.get<ServerResponse>(this.searchUrl + this.apiKey + '&s=' + name).pipe(
      map(res => res.Search)
    );
  }

// random.component.ts

getData(event) {
    const film = event.target.value;
    this.searchFilm(film)

    .subscribe( (res) => {
      /** Sort out res.Search issue */
      // res = this.movieResults = res.Search;
      this.movieResults = res;
      console.log(res);
    });
  }

// ramdom.model.ts

export interface SearchInterface {
    Poster: string;
    Title: string;
    Type: string;
    Year: string;
    imdbID: string;
}

export interface ServerResponse 
   {Search: SearchInterface[], totalResults: number, Response: boolean}

et voilà !