4

Angular is converting from HttpModule to HttpClientModule and deprecating the former, as detailed at Difference between HTTP and HTTPClient in angular 4?.

However the Angular tutorial at https://angular.io/tutorial/toh-pt6 uses HttpModule, while the Fundamentals information at https://angular.io/guide/http uses HttpClientModule as detailed at https://github.com/angular/angular/issues/19280. The comparison is made more difficult by the tutorial using an in-memory server while the Fundamentals use a real web server.

I've tried to make the switch from HttpModule to HttpClientModule in the Angular tutorial code using a real web server and gotten some parts working but other parts are not working. It seems to work to change one of the getHeroes methods in hero.services.ts from

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

though there may be ways this can be improved and this version may have problems I haven't discovered yet.

But I don't see an equivalent for the search method in hero-search.service.ts

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

One should be able to dispense with map, but you can't use the same approach as above because there is an Observable instead of a Promise, and you get errors such as:

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

Has anyone converted the Heroes demo in the Angular tutorial to use HttpClientModule or knows how to convert the search code above?

2 Answers 2

4

While HttpClient parses the JSON response into an Object, it doesn't know what shape that object is. So you can specify what type the response will be:

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

Notice you can create interface for that:

interface ItemsResponse {
  data: Hero[];
}

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

If you doubt what type of response will be or don't want to create interface then just use any:

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

TOH-HttpClientModule Example

See also

Sign up to request clarification or add additional context in comments.

1 Comment

This solved the problem, as illustrated in plnkr.co/edit/uW3F0TPLqP9sSA4AdyGu?p=preview. In hero.service.ts I switched to using similar syntax in methods such as getHeroes instead of the code I gave above. But I wan't sure how to handle headers and post, and the create method is throwing the error "Cannot create property 'id' on string". Advice on those parts would be appreciated.
0

rewrite your component they removed response.json in httpClient no need to call response.json() anymore. If data is not right name for response, open console and look for the right name of return object.

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

}

3 Comments

Object of Observable<{}|Hero[]> can't be assigned to Observable<Hero[]>.
Its probably that your hero class have required field and empty object can't be hero class due to required fields.
No, it's because the the httpClient can return two kinds of object. If server returned nothing it will return {}. And in subscription we have to write a logic for handling this situation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.