Angular: Http ResponseType cannot be set

Created on 8 Aug 2017  ·  62Comments  ·  Source: angular/angular

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

Response type cannot be set for HttpClient methods.

        const options = {headers: headers, params: params, responseType: 'text'};

        return this.http.get(url, options).share();

Would show an error

  Types of property 'responseType' are incompatible.
    Type 'string' is not assignable to type '"json"'.

Expected behavior

It is expected that the response type should be exported like

export type ResponseType = 'arraybuffer' | 'blob' | 'json' | 'text';;

And one would be able to set it using this type. Otherwise the type cannot be changed.

Environment

Angular version: 4.1.1 and still there in 5.0.0-beta.2
as seen here: https://github.com/angular/angular/blob/master/packages/common/http/src/client.ts

http feature

Most helpful comment

@zaiddabaeen currently, this is by design. Typescript needs to be able to infer the observe and responseType values statically, in order to choose the correct return type for get(). If you pass in an improperly typed options object, it can't infer the right return type.

Another workaround is:

const options = {headers, params, responseType: 'text' as 'text'};
return this.http.get(url, options).share();

All 62 comments

A workaround:

const options: {
            headers?: HttpHeaders,
            observe?: 'body',
            params?: HttpParams,
            reportProgress?: boolean,
            responseType: 'text',
            withCredentials?: boolean
        } = {
            headers: headers,
            params: params,
            responseType: 'text'
        };

@zaiddabaeen currently, this is by design. Typescript needs to be able to infer the observe and responseType values statically, in order to choose the correct return type for get(). If you pass in an improperly typed options object, it can't infer the right return type.

Another workaround is:

const options = {headers, params, responseType: 'text' as 'text'};
return this.http.get(url, options).share();

I understand, but I believe that's unintuitive and confusing to the developers. I don't recall I ever casted a string to a 'string' before. Enumerating and using types as suggested would sound to me as a cleaner solution.

@zaiddabaeen the problem is for:

const res = this.http.get(url, options);

What is the type of res? It depends on the values in options - but Typescript has no way to know what those values are if it's not inlined.

In other words:

const res = this.http.get(url, {responseType: 'text'});

is not equivalent to

const options = {responseType: 'text'};
const res = this.http.get(url, options);

In the first one Typescript can infer that the type of res is Observable<string>, in the second one it cannot be determined via type inference. If we added this feature, we would have to return an Observable<any> which would be a poor experience.

I expect most cases where this is desired can be solved with the spread operator:

// Some options we want to control dynamically.
const options = {headers: ..., params: ...};
const res = this.http.get(url, {...options, responseType: 'text'});

This way Typescript can infer the return type based on the signature and the value of responseType, but options can also be passed in without reconstructing the whole object.

So instead we have to do workarounds to get the desired effect? That can't be the way to go about this. I've been screaming at my computer for quite a while over this now, 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'.. None of the workarounds above works.

@chrillewoodz The default is JSON however. Why are you casting it to json?
My approach works, and I can confirm that it is now run on production.

@zaiddabaeen I'm not casting anything to json (as far as I'm aware). This is what I have:

  public get<T>(url: string, params?: {[key: string]: any}, headers?: HttpHeaders): Observable<T> {
    return this.http.get<T>(this.config.host + url, this.getRequestOptions(params, headers));
  }

  private getRequestOptions(params?: any, customHeaders?: HttpHeaders) {

    let defaultHeaders: HttpHeaders = new HttpHeaders();

    defaultHeaders = defaultHeaders.set('Content-Type', 'application/json');

    return {
      headers: customHeaders || defaultHeaders,
      params: params ? this.convertJSONtoParams(params) : null
    };
  }

Attempting to add responseType: 'text' to the return of getRequestOptions is what throws the error.

Use responseType: 'text' as 'text'

None of the workarounds above works.

I have already tried all of the above :|

I also had this problem, but by removing the <T> from the get call I was able to get it to work using responseType: 'text'as 'text'.

Eg this does not work and returns the error:

const options: { responseType: 'text' as 'text', withCredentials: true };
this.httpClient.get<string>(url, options)

But this does work:

const options: { responseType: 'text' as 'text', withCredentials: true };
this.httpClient.get(url, options)

The only way I got it to work without error was using @roddy's example, and that's with inlined options...

This does not work:
image

and neither will:
image

Angular v4.4.3

The generic MUST not be used when responseType is specified to something other than json because typeof T will then be inferred automatically.

Take a look at how it is defined for the get() method

    /**
     * Construct a GET request which interprets the body as an `ArrayBuffer` and returns it.
     *
     * @return an `Observable` of the body as an `ArrayBuffer`.
     */
    get(url: string, options: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType: 'arraybuffer';
        withCredentials?: boolean;
    }): Observable<ArrayBuffer>;
    /**
     * Construct a GET request which interprets the body as a `Blob` and returns it.
     *
     * @return an `Observable` of the body as a `Blob`.
     */
    get(url: string, options: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType: 'blob';
        withCredentials?: boolean;
    }): Observable<Blob>;
    /**
     * Construct a GET request which interprets the body as text and returns it.
     *
     * @return an `Observable` of the body as a `string`.
     */
    get(url: string, options: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType: 'text';
        withCredentials?: boolean;
    }): Observable<string>;
    /**
     * Construct a GET request which interprets the body as JSON and returns it.
     *
     * @return an `Observable` of the body as an `Object`.
     */
    get(url: string, options?: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<Object>;
    /**
     * 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;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<T>;

This makes perfect sense since the type can only be something angular does not know statically when the responseType is json - all other cases there is no need for a generic.

@reppners Hi Stefan, thank you for the explanation above. However, no matter how I try I cannot make the new HttpClient to work in a service that I am using to intercept image urls in my app:

get(url: string): Observable<any> {
    return new Observable((observer: Subscriber<any>) => {
        let objectUrl: string = null;
          this.http
            .get(url, {headers: this.getHeaders(), responseType: ResponseContentType.Blob} )
            .subscribe(m => {
              objectUrl = URL.createObjectURL(m.blob());
              observer.next(objectUrl);
            });

        return () => {
          if (objectUrl) {
            URL.revokeObjectURL(objectUrl);
            objectUrl = null;
          }
        }
    });
  }
  getHeaders(): Headers {
    let headers = new Headers();

    let token = this.authService.getToken();
    if (token) {
      headers.set('Authorization', 'Bearer ' + token);
    }

    return headers;
  }

Neither responseType: 'blob' set directly in the GET request, nor setting it in the options: { } as mentioned above works.

@a-kolybelnikov You can use something like this in your case:

.get(url, { headers: this.getHeaders(), responseType: ResponseContentType.Blob as 'blob' })

@btory thank you. I have tried and it won’t work.

try this: .. , responseType: 'text' as 'json'

thanks @rds-rafael , this.http.get<ArrayBuffer>(this.pdfLink, {responseType: 'arraybuffer' as 'json'}) worked for me, a bit strange.

Closing, the solution is to pass a correctly typed argument.

For blobs:
.get(url, { 'responseType: 'blob' as 'json' })

So whoever won the argument to re-factor Http to HttpClient this way is just wrong.

@chrillewoodz's solution worked for me
I had something like
this.httpClient.post<string>(url, data, {responseType: 'text' as 'json'});
and this worked as the api I was called was simply returning a string. Of course, removing the generic means that the whole thing needed to be changed to:
this.httpClient.post(url, data, {responseType: 'text' as 'text'});

While I find the workaround to this to only be a minor annoyance it was really furustring that it was so difficult to actually find this answer. It'd be nice if this was better documented or I suppose a more intuitive solution be reached.

@nortain you definitely don't need either.

this.httpClient.post(url, data, {responsesType: 'text'})

will give you an Observable<string> without you having to specify <string>. You don't need to say 'text' as 'text', Typescript knows that.

The _only_ time you should be passing a type parameter to an HttpClient method is with responseType: 'json'. All of the others are implicit.

@alxhub Ah thank you, that makes more sense and I realize i hadn't tried dropping the as 'text' when removing the generic. Also knowing that the generic is intended for json responses only helps. I appreciate the follow up.

@alxhub
Facing the same issue with observe property

this.http.get(endpoint, {
      observe: 'response'
    })
[ts]
Argument of type '{ headers: HttpHeaders; observe: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'observe' are incompatible.
    Type 'string' is not assignable to type '"body"'.

only observe: 'body' works. 'response' and 'events' does not.

All feels very convoluted to me. I'd rather have different methods to call for different results rather than the inference which is currently being used.

@Pastafarian I agree, in one case I see (with the same responseType option) that:

return this.httpClient.request('post', '/login', options)

Does work, this on the other hand does not:

return this.httpClient.post('/login', options)

Not sure I agree this httpclient is any easier or more intuitive than the previous incarnation. On the contrary it's clunky and relies on a lot of under the covers inference.

I can't really follow. Just stumbled upon this in my code:

login(username: string, password: string): Observable<string> {
  const body = `username=${username}&password=${password}`;
  const options = {
    headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
    responseType: 'text'
  };
  return this.http.post(this.loginUrl, body, options);
}

Using the latest version of VS Code, it tells me in the last line that options is wrong:

Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'responseType' are incompatible.
    Type 'string' is not assignable to type '"json"'.

Reading the comments, I have the feeling that I have to write responseType: 'text' as 'text' or responseType: 'text' as 'json' as a workaround. I don't get it, what does that even mean?

@tobihagemann responseType: 'text' as 'text' is what you want. 'text' is not 'json'.

Thanks, @alxhub. I re-read your comment and I begin to understand what's happening (should've read that more carefully).

I guess it's my choice to choose between inline, not inline but casting, or not inline but using spread operator for the things that are type-dependent, is it? Basically, these three options:

login(username: string, password: string): Observable<string> {
  const body = `username=${username}&password=${password}`;
  return this.http.post(this.loginUrl, body, {
    headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
    responseType: 'text'
  });
}
login(username: string, password: string): Observable<string> {
  const body = `username=${username}&password=${password}`;
  const options = {
    headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
    responseType: 'text' as 'text'
  };
  return this.http.post(this.loginUrl, body, options);
}
login(username: string, password: string): Observable<string> {
  const body = `username=${username}&password=${password}`;
  const options = {
    headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
  };
  return this.http.post(this.loginUrl, body, { ...options, responseType: 'text' });
}

Is the as 'text' variant (second option) really a "workaround" as stated in this issue? Or is it just the way to do things? Is there a preferred option?

This was the key answer for me: https://github.com/angular/angular/issues/18586#issuecomment-323216764

You have to inline your options object in the call to get (or post), for the Typescript compiler not to complain about your return type.

The only way this compiles without complaining that res is not an ArrayBuffer is to inline the options like this:

this.http.post<AuthResult>(this.AuthenticationEndpoint, 
    body, { withCredentials: false }).subscribe(res => {

This whole approach is counter-intuitive incarnate. I've been at this for days and I still can't manage to console log the response of a post request with parameters and a file as response.

I'm pulling my hair out.

ok so here's what worked for me :

actions.ts :

generatePOR(){
  this._api.generatePOR(this.selection).subscribe(res => {
    if(res !== null && res !== undefined){
      console.log(res.body);
    }
  }, (error) => console.log(error), () => {});
}

api.ts :

generatePOR(idList): any {
  const apiURL = `${this.API_URL}/purchaseorders/generatePOR`;
  this.PORresult = this._http.post(apiURL, idList, {
    observe: 'response',
    headers: new HttpHeaders({'Content-Type': 'application/json'}),
    responseType: 'text' as 'text'
  }).catch(this.handleError);
  return this.PORresult;
}

Here is my workaround for this breaking change.

const options: {
      headers?: HttpHeaders;
      observe: "response";
      params?: HttpParams;
      reportProgress?: boolean;
      responseType: "arraybuffer";
      withCredentials?: boolean;
    } = {
      observe: "response",
      responseType: "arraybuffer"
    };

this.http
    .get(blobRequest.url, options)
    .map(response => <ArrayBuffer>response.body)

it also appears that an ArrayBuffer is not even returned by the get, a Response object is.

I simply added below and worked well in angular 5.
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'Application/json; charset=UTF-8'
}),
responseType: 'text' as 'text'
};
const body = JSON.stringify(params);
return this._http.post(url, body, httpOptions);

Same problem occurred over here... Adding 'text' as 'text solved it...

const httpOptions = {
            headers: new HttpHeaders({
              'Content-Type':  'application/json',
              'Accept': 'text/html'
            })
        };
return this.http.post<any>(url, { 'new': new_elements, 'old': old_elements }, {...httpOptions, responseType: 'text' as 'json' });

Similar to @jmoeyersons here... Angular 5.2.10

return this.http.post(
      url,
      data,
      { headers: headers, responseType: 'text' as 'text', withCredentials: false }).map(res => {
        console.log(res);
      });

or

return this.http.post<any>(
      url,
      data,
      { headers: headers, responseType: 'text' as 'json', withCredentials: false }).map(res => {
        console.log(res);
      });

This is not well documented at all ( https://angular.io/api/common/http/HttpClient#post )

TS is easy))

    const headers = new HttpHeaders({
        'Authorization': 'Bearer ' + token
    });
    const params = new HttpParams[]
    const observe = 'response';
    const reportProgress = false;
    const responseType = 'text';
    const withCredentials = false;

    const options = {
        headers: headers,
        observe: <any>observe,
        params: params,
        reportProgress: reportProgress,
        responseType: <any>responseType,
        withCredentials: withCredentials
    };

    return this.http.get<HttpResponse>(href, options);

Seeing stuff like responseType: 'text' as 'text' feels broken to me. Maybe the whole Http options object should have been a well-defined interface with explicit enum types.

@ghillert unfortunately that would suffer from the same problem. The type of the field in the interface would be the enum type, not the particular value. HttpClient's type inference depends on the type of the object being passed to get() being narrowed to a specific _value_ type.

There's an easy solution to all this, though:

const options = {
  headers: ...,
  params: ...,
  reportProgress: false,
  withCredentials: true,
};

return this.http.get(url, {...options, responseType: 'text'});

Basically, you just have to specify the responseType and observe values directly in the call to get(). Everything else can go in the options object.

Please mention this in:

https://angular.io/guide/http#requesting-non-json-data

My code:

return this.http.get<string>(this.apiURLDisplays+'/'+name, { responseType: 'text' })
            .pipe(
                catchError(this.handleError)
            );

I don't get it though - ng serve blows up with:

ERROR in src/app/shared/api.service.ts(937,68): error TS2345: Argument of type '{ responseType: "text"; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'responseType' are incompatible.
    Type '"text"' is not assignable to type '"json"'.

But it then serves a page and it works fine in the browser... so is this just a typescript issue and it somehow still does get transpiled into javascript & works?

Enum would've been nicer though...

Also, I think the reason people are saying 'text' as 'json' works is in VSCode if you have get<string>() like mine above, it draws a red line under it if you have 'text' as 'text' but accepts 'text' as 'json'

I just read @alxhub 's comment about <string> being implicit in this case, took out <string> and VSCode accepted return this.http.get(this.apiURLDisplays+'/'+name, { responseType: 'text' as 'text' })

With using both responseType and authentication service I was able to make it work with this:

let headers2: HttpHeaders = new HttpHeaders({
      'Authorization' : 'my-auth-token'
});

this.httpClient.get(this.url, { headers : headers2, responseType : 'blob' }).subscribe(
  data => console.log(data),
  err => console.log(err)
)

Before that, I tried this:

const httpOptions2 = {
  headers: new HttpHeaders({
    'Authorization' : 'my-auth-token'
  }),
  responseType : 'blob'
};

this.httpClient.get(this.url, httpOptions2).subscribe(
  data => console.log(data),
  err => console.log(err)
)

...on httpOptions2 as a parameter it will give me

Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.

What's the reason I can't use the latter?

*'my-auth-token' was changed

@H36615

const httpOptions2 = {
  headers: new HttpHeaders({
    'Authorization' : 'my-auth-token'
  }),
  responseType : 'blob'
};

In this snippet, TypeScript will infer the type of httpOptions2 to be

{
  headers: HttpHeaders;
  responseType: string;
}

But HttpClient requires that if the options object you pass has responseType and/or observe values, they have specific types and are not just strings.

Am I missing something here? I just encountered this error myself I expect responseType blob.

const httpOptions = {
      ...
      responseType:'blob'
    };

I receive type error but if I do

const httpOptions = {
      ...
      responseType:'blob' as 'blob'
    };

It works just fine. Am I wrong thinking this is ridiculous?

Answer that this is by design is not really a good answer it looks like a poor design to me if I can create HttpRequest where that param works as expected I'd expect it to work the same everywhere. Taking that docs don't mention this hacky approach anywhere.

Granted I am new to TypeScript but it just doesn't seem right I have to resolve to workarounds like this is this a TypeScript issue or Angular?

I've spent the better part of a day on trying to figure out why postman gave the correct response and http.get didn't. I thought using http:get might work, but it didn't. Eventually I found this thread, saw that I had to take the out and use responseType: 'text' as 'text' as roddy suggested back last September. Then I read to the end of the post and found that it is still a problem. I think this should be fixed, or at the very least documented because it's far from intuitive!

Actually on a second thought after initial bafflement it does makes sense to me now as in
const httpOptions = { ... responseType:'blob' as 'blob' };
is not the same as inserting literal notation in the httpClient as @alxhub mentioned above somewhere.

What I did in case of blob type it works fine with no error in Angular 6.
I tried with both responseType: 'blob' as 'blob' but getting the syntax error and unable to build it.

const options = {headers: this.httpHeaders, responseType: 'blob' as 'json'};
return this.http.get<Blob>(Constants.BASE_URL + Constants.DOWNLOAD_FILE + path, options
)

Working for me

_downloadWeb(url, api, mimeType) { var token = getTokenWeb(); let data = { "siteId": this.state.idSite } Axios.defaults.headers.common['Authorization'] =${token} Axios.defaults.headers.common['Accept'] =${mimeType} Axios.defaults.headers.common['Content-Type'] =application/json Axios.post(url + api, data, { responseType: 'blob', }) .then((response) => { let blob = new Blob([response.data], { type: mimeType }); saveAs(blob, guid() + ".xlsx") }) .catch(function (error) { console.log("_downloadWeb", error); });; }

adding the responseType: 'blob' implicitly changes the result to Observable / Obserrvable>

Not typing the httpClient.post or httpClient.get solves it for me

return this.httpClient.post<any>(
      `${environment.apiEndpoint}/${environment.apiVersion}/template-version/${templateId}/${version}/test`,
      { answers },
      { headers: this.blobHeaders, responseType: 'blob' })
      .pipe(
        tap(
          // Log the result or error
          data => console.log('You received data'),
          error => console.log(error)
        )
      );

gives the error, but

return this.httpClient.post(
      `${environment.apiEndpoint}/${environment.apiVersion}/template-version/${templateId}/${version}/test`,
      { answers },
      { headers: this.blobHeaders, responseType: 'blob' })
      .pipe(
        tap(
          // Log the result or error
          data => console.log('You received data'),
          error => console.log(error)
        )
      );

works

this issue is still happening in Angular 7.1

I eventually came up with this and though I could share it:

// define this namespace somewhere
namespace ResponseType {
    export const JSON = 'json' as 'json';
    export const ArrayBuffer = 'arraybuffer' as 'arraybuffer';
    export const Blob = 'blob' as 'blob';
    export const Text = 'text' as 'text';
}

```typescript
// import the namespace above and use it like this
const reqOpts = {
params: params,
headers: headers,
responseType: ResponseType.JSON,
};

// no type error, the right signature is selected
const a = await this.http.get(url, reqOpts);
const b = await this.http.get(url, reqOpts);

https://github.com/angular/angular/issues/18586#issuecomment-327440092 gave a good hint at how to implement this.

This solution also work for the `observe` parameter.

____

Unless I missed something, this could be implemented in Angular directly, isn't ?

You would need to first put the following in the declaration `@angular/common/http/src/client.d.ts`:
```typescript
declare module '@angular/common/http' {
    export namespace HttpResponseType {
        export const JSON: 'json';
        export const ArrayBuffer: 'arraybuffer';
        export const Blob: 'blob';
        export const Text: 'text';
    }

    export declare type HttpObserve = 'body' | 'events' | 'response';
    export namespace HttpObserve {
        export const Body: 'body';
        export const Events: 'events';
        export const Response: 'response';
    }
}

Then implement it in angular/packages/common/http/src/client.ts:

export namespace HttpResponseType {
    export const JSON: 'json' = 'json';
    export const ArrayBuffer: 'arraybuffer' = 'arraybuffer';
    export const Blob: 'blob' = 'blob';
    export const Text: 'text' = 'text';
}

export type HttpObserve = 'body' | 'events' | 'response';
export namespace HttpObserve {
    export const Body: 'body' = 'body';
    export const Events: 'events' = 'events';
    export const Response: 'response' = 'response';
}

Finally the two namespaces should be properly exported all the way back to @angular/common/http.

@rgoupil this is a cool idea!

I had the same problem. After a half an hour of trying to implement some of the suggestions above I wen't ahead with the following (dirty but...):

// I actually get the response type as a parameter to my function
const responseType = 'text';

const options = {
    headers: new HttpHeaders()
};

// @ts-ignore
options['responseType'] = responseType;

this.http.get(url, options);

I have to hack it with
const options = {responseType: 'text' as 'json'};
this.httpClient.get<string>(url, options).subscribe()

Cast the httpOptions variable to type Object:

const httpOptions: Object = {
  responseType: 'blob'
};

as specified in the docs:https://angular.io/api/common/http/HttpClient#get

Any news on this? I've been struggling with the same issue on HttpClient.post's options...

Working with Angular 7 (8 not tested yet)

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

@Injectable()
export class RequestService {
  httpOptions = {
    headers: new HttpHeaders({
      Accept: 'application/json;charset=utf-8',
      Authorization: `Basic ${btoa('user:password')}`,
      'Content-Type': 'application/json;charset=utf-8'
    }),
    observe: 'response' as 'body'
  };

  constructor(private readonly httpClient: HttpClient) {
  }

  get<T>(uri: string): Observable<HttpResponse<T>> {
    return this.httpClient.get<HttpResponse<T>>(uri, this.httpOptions);
  }

  post<T>(uri: string, value: T): Observable<HttpResponse<T>> {
    return this.httpClient.post<HttpResponse<T>>(uri, value, this.httpOptions);
  }

  put<T>(uri: string, value: T): Observable<HttpResponse<T>> {
    return this.httpClient.put<HttpResponse<T>>(uri, value, this.httpOptions);
  }
}

I also had this problem, but by removing the <T> from the get call I was able to get it to work using responseType: 'text'as 'text'.

Eg this does not work and returns the error:

const options: { responseType: 'text' as 'text', withCredentials: true };
this.httpClient.get<string>(url, options)

But this does work:

const options: { responseType: 'text' as 'text', withCredentials: true };
this.httpClient.get(url, options)

this solution works for me

it doesn't work

const options= { 
        responseType:'arraybuffer'
      };
this.httpClient.get(url, options);

it does work

const options: any = {  //  The options with data type any does work well.
        responseType:'arraybuffer'
      };
this.httpClient.get(url, options);
const httpOptions: Object = {
  responseType: 'blob'
};

it doesn't work

const options= { 
        responseType:'arraybuffer'
      };
this.httpClient.get(url, options);

it does work

const options: any = {  //  The options with data type any does work well.
        responseType:'arraybuffer'
      };
this.httpClient.get(url, options);

Declaring the options as any or Object is fine if you are only interested in setting the responseType and probably cover most of the cases for people who encounter this issue. However if you want to set something else (like headers) then typescript will no longer be able to help you with type checking. This is the reason why I was suggesting and I preferred using _bracket notation_ to set the value for the _responseType_ and only _ts-ignore_ that line.

One of the solutions that helped me get rid of the compiler error(Type '"text"' is not assignable to type '"json"'.) was creating an HttpRequest using the constructor. And using http.request. I hope someone will help

Was this page helpful?
0 / 5 - 0 ratings