-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Http ResponseType cannot be set #18586
Comments
A workaround:
|
@zaiddabaeen currently, this is by design. Typescript needs to be able to infer the 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 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 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 |
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 |
@chrillewoodz The default is JSON however. Why are you casting it to |
@zaiddabaeen I'm not casting anything to json (as far as I'm aware). This is what I have:
Attempting to add |
Use |
I have already tried all of the above :| |
I also had this problem, but by removing the Eg this does not work and returns the error:
But this does work:
|
The only way I got it to work without error was using @roddy's example, and that's with inlined options... Angular v4.4.3 |
The generic MUST not be used when responseType is specified to something other than Take a look at how it is defined for the /**
* 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 |
@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:
Neither |
@a-kolybelnikov You can use something like this in your case:
|
@btory thank you. I have tried and it won’t work. |
try this: .. , responseType: 'text' as 'json' |
thanks @rds-rafael , |
Closing, the solution is to pass a correctly typed argument. |
For blobs: |
So whoever won the argument to re-factor Http to HttpClient this way is just wrong. |
@chrillewoodz's solution worked for me 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 The only time you should be passing a type parameter to an |
@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
only |
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
Reading the comments, I have the feeling that I have to write |
@tobihagemann |
I have to hack it with |
Cast the httpOptions variable to type Object:
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)
|
this solution works for me |
it doesn't work
it does work
|
Declaring the options as |
One of the solutions that helped me get rid of the compiler error( |
@alxhub does it make sense to reiterate this issue with Typescript 4.1? |
In 2021 the API is still very weird: Works:
Does not work (no matches):
have to use responseType: 'blob' as 'json', |
This actually helped me. |
Worked for me as suggested by @sk4xd . |
Just my 2 cents: Please make this a documentation ticket. Everybody is already confused. I just discussed this issue with colleagues. get() has 15 overloads, 3 of which are generic. I am yet to see a compiler that generates useful error messages in face of so many overloads. The issue is that both Maybe I'm misreading this, but in here the observe is optional. But in many cases typescript needs the information for overload resolution. I think the design intends to keep people on the success path in terms of useful types. I wouldn't "fix" that. Just make it abundantly clear that the caller has to select the right overload, how to do so, and what to avoid. |
I tried the workaround mentioned almost at the top (from @alxhub ) but didn't work. This is a very simple example. EDIT: We're talking about this headers, right? If so, maybe my params object is not the right type. EDIT 2: This is what the editor tells me about those 2: EDIT 3: SO never mind, I think I was confused about usage. This worked: return this.http.get(url, {
withCredentials: false,
responseType: 'text'
}); |
@alxhub I think that with Typescript 5.0 this issue can be finally resolved |
I was getting the same issue using a body and only this method and @rds-rafael one was working for me Mine is: |
@l-Legacy-l For everyone - You should just carefully select the proper overload for your needs. |
Since TS 3.4 it is possible to use a const assertion.
|
I'm submitting a...
Current behavior
Response type cannot be set for HttpClient methods.
Would show an error
Expected behavior
It is expected that the response type should be exported like
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
The text was updated successfully, but these errors were encountered: