usr-local-ΕΨΗΕΛΩΝ
usr-local-ΕΨΗΕΛΩΝ

Reputation: 26874

Angular 12 HttpClient POST to string does not compile

I have a POST method returning a plain string.

The following does not compile

public ping(): Observable<string> {
    return this.httpClient.post<string>(this.uri, {}, {
      observe: 'body', responseType: 'text'
    });
  }

Error is

TS2322: Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<string>'.     Type 'ArrayBuffer' is not assignable to type 'string'

It looks like Webstorm insists to compile my statement into the following public method of the HttpClient (ctrl-clicked on it)

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

How do I correctly tell Angular that the server is returning a plain string?

Upvotes: 0

Views: 2843

Answers (2)

Majid joghataey
Majid joghataey

Reputation: 1537

I've got a service which wraps the HttpClient but trying to set responseType doesn't work, the only way that I can get the error to go away is by doing responseType: 'text' as 'json'

responseType: 'text' as 'json'

Upvotes: 2

jonrsharpe
jonrsharpe

Reputation: 121966

It's the generic type that's confusing things, the following works just fine:

return this.httpClient.post(this.uri, {}, {
  observe: 'body', responseType: 'text'
});

If you look in the implementation you can see only three overloads with a generic type argument, post<T>, all of which expect responseType: 'json'. Given that the compiler can't match any of the overloads, it shows you the error from applying the first one listed for the method, which indeed returns Observable<ArrayBuffer>.

Note that, for the overload you actually want, the observe parameter is optional, so you can just do:

return this.httpClient.post(this.uri, {}, { responseType: 'text' });

Also I got a much more helpful error when I actually tried to build with the broken service than I did inline in the IDE; it actually told me none of the overloads applied:

ERROR in src/app/service.ts:11:45 - error TS2769: 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.
    Type '"text"' is not assignable to type '"json"'.
  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.
    Type '"text"' is not assignable to type '"json"'.
  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.
    Type '"text"' is not assignable to type '"json"'.

11     return this.http.post<string>("", {}, { responseType: "text" });
                                               ~~~~~~~~~~~~

  node_modules/@angular/common/http/http.d.ts:2297:9
    2297         responseType?: 'json';
                 ~~~~~~~~~~~~
    The expected type comes from property 'responseType' which is declared here on type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'
  node_modules/@angular/common/http/http.d.ts:93m2413:9
    2413         responseType?: 'json';
                 ~~~~~~~~~~~~
    The expected type comes from property 'responseType' which is declared here on type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'
  node_modules/@angular/common/http/http.d.ts:2458:9
    2458         responseType?: 'json';
                 ~~~~~~~~~~~~
    The expected type comes from property 'responseType' which is declared here on type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'

Upvotes: 2

Related Questions