Как изменить данные, возвращаемые JSON? - PullRequest
0 голосов
/ 08 июля 2019

Я использую API OMDB (БД онлайн-фильма).Я создал интерфейс, который возвращает ожидаемые типы данных.При запросе данных через метод http get возвращаемые данные: {Search: Array (10), totalResults: «31», Response: «True»}.Данные, которые мне нужны, находятся в массиве поиска.При подписке я использую res.Search для доступа к этой информации: subscribe ((res) => {res = this.movieResults = res.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 ]

1 голос
/ 08 июля 2019

Здесь задействованы две структуры данных: внешняя, возвращаемая службой http, которую вы описали в своем вопросе:

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

И та, которая вас волнует, используется для каждого элементаМассив поиска: 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)
  );
}
0 голосов
/ 08 июля 2019

Я создавал стек-блиц, и вот уже 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à!

0 голосов
/ 08 июля 2019

@ Amitk88, почему вы экспортируете SearchInterface дважды export interface SearchInterface export default SearchInterface;

Также не присваивайте переменную, подобную этой res = this.movieResults = res.Search;

  getData(event) {
    const film = event.target.value;
    this.data.searchFilm(film)
    .subscribe( (res: SearchInterface ) => {
      console.log(res)
    });
  }

Проверьте ответ, который вы получите.Я не вижу Поиск в качестве ключа в вашем интерфейсе, но вы ожидаете найти Поиск в ответе.Если вы ожидаете, что Поиск будет ключевым в ответе, включите его в интерфейс

0 голосов
/ 08 июля 2019

Поскольку ваш 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;
...