Преобразование из HttpModule в HttpClientModule

Angular преобразуется из HttpModule в HttpClientModule и отказывается от первого, как подробно описано в Разница между HTTP и HTTPClient в angular 4?.

Однако в руководстве по Angular на странице https://angular.io/tutorial/toh-pt6 используется HttpModule , в то время как информация об основах на https://angular.io/guide/http использует HttpClientModule, как подробно описано на https://github.com/angular/angular/issues/19280. Сравнение усложняется тем, что в учебнике используется сервер в памяти, в то время как в Основах используется реальный веб-сервер.

Я попытался переключиться с HttpModule на HttpClientModule в учебном коде Angular, используя реальный веб-сервер, и некоторые части работают, но другие не работают. Кажется, удалось изменить один из методов getHeroes в hero.services.ts с

  getHeroes(): Promise<Hero[]> {
    return this.http.get(this.heroesUrl)
      .toPromise()
      .then(response => response.json().data as Hero[])
      .catch(this.handleError);
  }

to

  getHeroes(): Promise<Hero[]> {
    return this.httpClient.get(this.heroesUrl)
      .toPromise()
      .then(data => data['heroes'] as Hero[])
      .catch(this.handleError);
  }

хотя могут быть способы улучшить это, и в этой версии могут быть проблемы, которых я еще не обнаружил.

Но я не вижу эквивалента для метода поиска в hero-search.service.ts

  search(term: string): Observable<Hero[]> {
    return this.http
      .get(`api/heroes/?name=${term}`)
      .map(response => response.json().data as Hero[]);
  }

Можно обойтись без карты, но вы не можете использовать тот же подход, что и выше, потому что есть Observable вместо Promise, и вы получаете такие ошибки, как:

Type 'Observable<Object>' is not assignable to type 'Observable<Hero[]>'.

Кто-нибудь преобразовал демонстрацию Heroes в руководстве по Angular для использования HttpClientModule или знает, как преобразовать приведенный выше код поиска?


person Mickey Segal    schedule 20.09.2017    source источник


Ответы (2)


Хотя HttpClient анализирует ответ JSON на объект, он не знает, какой формы этот объект. Таким образом, вы можете указать, какого типа будет ответ:

return this.http
    .get<{ data: Hero[] }>(`api/heroes/?name=${term}`)
    .map(res => res.data);

Обратите внимание, что для этого можно создать интерфейс:

interface ItemsResponse {
  data: Hero[];
}

return this.http
  .get<ItemsResponse>(`api/heroes/?name=${term}`)
  .map(res => res.data);

Если вы сомневаетесь, какой будет тип ответа, или не хотите создавать интерфейс, просто используйте any:

return this.http
  .get<any>(`api/heroes/?name=${term}`)
  .map(res => res.data);

Пример TOH-HttpClientModule

Смотрите также

person yurzui    schedule 20.09.2017

перепишите свой компонент, они удалили response.json в httpClient, больше не нужно вызывать response.json (). Если данные не являются правильным именем для ответа, откройте консоль и найдите правильное имя возвращаемого объекта.

search(term: string): Observable<Hero[]> {
return this.http
  .get(`api/heroes/?name=${term}`)
  .map(response => {
         console.log(response);
         return response['data'] as Hero[]
   });

}
person alexKhymenko    schedule 20.09.2017
comment
Объект Observable ‹{} | Hero []› не может быть назначен Observable ‹Hero []›. - person Ravinder Payal; 22.11.2017
comment
Вероятно, у вашего класса героя есть обязательное поле, а пустой объект не может быть классом героя из-за обязательных полей. - person alexKhymenko; 22.11.2017
comment
Нет, это потому, что httpClient может возвращать два типа объектов. Если сервер ничего не вернул, он вернет {}. А в подписке мы должны написать логику работы с этой ситуацией. - person Ravinder Payal; 22.11.2017