Angular HttpClient return expecting observable<HttpEvent<any> rather than observable<any>

roverred picture roverred · Jan 23, 2018 · Viewed 14.4k times · Source

I'm getting a compilation error on the return type when using HttpClient. In my function GetPortfolio, I'm expecting the GET call to return the json object of type Observable<Portfolio> but it's giving the error:

Type Observable<HttpEvent<Portfolio>> is not assignable to type Observable<Portfolio>. Type HttpEvent<Portfolio> is not assignable to type Portfolio. Type HttpProgressEvent is not assignable to type Portfolio. Property name is missing in type HttpProgressEvent.

My code:

import { Injectable } from '@angular/core';
import { environment } from './environments/environment';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';


export interface Portfolio {
  name: string;
  id: string;
}

@Injectable()
export class PortfolioService {

    private httpOptions;

    apiUrl: string;

    constructor(private http: HttpClient) {
      this.apiUrl = environment.apiUrl + "/api/portfolios";

      this.httpOptions = {
        headers: new HttpHeaders(
          {
            'Content-Type': 'application/json',
          })   
      };
    }


    GetPortfolio(portfolioId: string): Observable<Portfolio> {
      return this.http.get<Portfolio>(this.apiUrl + '/${portfolioId}', this.httpOptions);
   }

}

From the angular hero tutorial and docs HttpClient requests should expect Observable<any>: Angular HttpClient doc

So am I doing something wrong? Or should I be setting the return value to Observable<HttpEvent<Portfolio>> ?

Answer

LLai picture LLai · Jan 23, 2018

Typecast your httpOptions

private httpOptions: {
    headers: HttpHeaders
};

The typescript compiler is pulling the wrong get method type (src)

/**
* Construct a GET request which interprets the body as JSON and returns the full event stream.
*
* @return an `Observable` of all `HttpEvent`s for the request, with a body type of `T`.
*/
get<T>(url: string, options: {
    headers?: HttpHeaders | {[header: string]: string | string[]},
    observe: 'events',
    params?: HttpParams|{[param: string]: string | string[]},
    reportProgress?: boolean,
    responseType?: 'json',
    withCredentials?: boolean,
}): Observable<HttpEvent<T>>;

When you specify the type with headers, it pulls the correct type. (src)

/**
* Construct a GET request which interprets the body as JSON and returns it.
*
* @return an `Observable` of the body as type `T`.
*/
get<T>(url: string, options?: {
    headers?: HttpHeaders | {[header: string]: string | string[]},
    observe?: 'body',
    params?: HttpParams|{[param: string]: string | string[]},
    reportProgress?: boolean,
    responseType?: 'json',
    withCredentials?: boolean,
}): Observable<T>;