Priyal
Priyal

Reputation: 484

Setting http option as 'responseType: 'text'' causes compile failure for a http post request with angular HttpClient

Although there is an overloaded API method in angular HttpClient as bellow:

 post(url: string, body: any | null, options: {
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe?: 'body';
        params?: HttpParams | {
            [param: string]: string | string[];
        };
        reportProgress?: boolean;
        responseType: 'text';
        withCredentials?: boolean;
    }): Observable<string>;

when I try to do bellow post request with the option 'responseType: 'text'' I get a compiler error stating "No overload matches this call. ..."

const opts = {
      headers: new HttpHeaders({
        'Accept': 'text/html, application/xhtml+xml, */*',
        'Content-Type': 'text/plain; charset=utf-8'
      }),
      responseType: 'text'
    };
    return this.http.post<string>('url', null, opts);

Note : I'm passing null as response body sensibly as my API doesn't accept a body. What I'm I doing possibly wrong here?

Update Adding the full error message as per the request by Michael D

Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<string>'.
  Type 'ArrayBuffer' is not assignable to type 'string'.ts(2322)
No overload matches this call.
  Overload 1 of 15, '(url: string, body: any, options: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
    Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
      Property 'observe' is missing in type '{ headers: HttpHeaders; responseType: string; }' but required in type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
  Overload 2 of 15, '(url: string, body: any, options: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
    Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
      Property 'observe' is missing in type '{ headers: HttpHeaders; responseType: string; }' but required in type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
  Overload 3 of 15, '(url: string, body: any, options?: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
    Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
      Types of property 'responseType' are incompatible.
        Type 'string' is not assignable to type '"json"'.ts(2769)
http.d.ts(2293, 9): 'observe' is declared here.
http.d.ts(2409, 9): 'observe' is declared here.

Upvotes: 4

Views: 12907

Answers (4)

David
David

Reputation: 34435

The problem is with the responseType property. Assigning it as a string like this won't work straight away.

You can either cast it as a text type

const opts  = {
  headers: new HttpHeaders({
    'Accept': 'text/html, application/xhtml+xml, */*',
    'Content-Type': 'text/plain; charset=utf-8'
  }),
  responseType: 'text' as 'text' //<== here
};

    this.http.post(....);

Edit This will only work with using non generic version of http calls (this.http.post(...) but not generic versions this.http.post<string>)

Or, you can declare your options as any, this should stop the compiler from complaining

const opts : any = {
  headers: new HttpHeaders({
    'Accept': 'text/html, application/xhtml+xml, */*',
    'Content-Type': 'text/plain; charset=utf-8'
  }),
  responseType: 'text'
};

this.http.post<string>(....)

Upvotes: 5

Priyal
Priyal

Reputation: 484

I think I've figured out the fault in my code thanks to this comment from reppners here The problems is that I'm trying to use generics type for the post() method call which is applicable only when the responseType is equal to 'json'. Have a look at the HttpClient's post method overloaded declarations bellow

post(url: string, body: any | null, options: {
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe?: 'body';
        params?: HttpParams | {
            [param: string]: string | string[];
        };
        reportProgress?: boolean;
        responseType: 'text';
        withCredentials?: boolean;
    }): Observable<string>;

 post<T>(url: string, body: any | null, options?: {
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe?: 'body';
        params?: HttpParams | {
            [param: string]: string | string[];
        };
        reportProgress?: boolean;
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<T>;

Therefore bellow is the working code for my problem

 apiMethod(): Observable<string> {

    const options  = {
      headers: new HttpHeaders({
        'Accept': 'text/html, application/xhtml+xml, */*',
        'Content-Type': 'text/plain; charset=utf-8'
      }),
      responseType: 'text' as 'text'
  };
    return this.http.post('url', null, options);
  }

Upvotes: 4

HTN
HTN

Reputation: 3604

opts['responseType'] is inferred as string. Try responseType: 'text' as const or

const opts = {
   ...
} as const;

Upvotes: 0

Nikhil
Nikhil

Reputation: 1236

Although it is strange behavior. The options in HttpClient are not really of any type. It is customized for each overloading.

You will have to pass the options as a whole into the http call.

return this.http.post<string>('url', null, {
      headers: new HttpHeaders({
        'Accept': 'text/html, application/xhtml+xml, */*',
        'Content-Type': 'text/plain; charset=utf-8'
      }),
      responseType: 'text'
    });

Or as David suggested set the options type as any.

Upvotes: 1

Related Questions