angular: by default not send undefined params in url
I’m submitting a…
- Feature request
CURRENT
To be simple, I will take example for GET request. Here you have a simple method making http call with an optional parameter:
public getCity(cityId?: number){
this.get('city', { params: {city: cityId}})
}
cityId?
is optional, so you can call method like this.getCity()
, if you do so angular will make request to this url : http://localhost/city?city=undefined
EXPECTED
I think avoid sending undefined params (not including them in HttpParams if they are undefined) should be most common use case because we can check this on backend. If params aren’t present == undefined.
MOTIVATION
Advantages of this is : maybe URL have limits and sending essential/useful data we really need is important. I don’t understand why send them by default if they are undefined. Something like Include.NON_NULL in jackson. What you think about not send them by default ? or add option in options{} object just to avoid this big codes:
let cleanedParams = new HttpParams();
req.params.keys().forEach(x => {
if(req.params.get(x) != undefined)
cleanedParams = cleanedParams.append(x, req.params.get(x));
})
const clonedRequest = req.clone({
params:cleanedParams
});
return next.handle(clonedRequest)
Otherwise yes actually we can fortunately workaround by interceptor or with :
public getCity(cityId?: number){
let params = {};
if(cityId)
params.city=cityId;
this.get('city', params)
}
But when you have 10/20 params or 500/1k http request you are happy if you avoid this condition 😄
I didn’t think about others backend endpoint so will think within my use case. Idea should only react with undefined params not with null params. For instance my endpoint in java if I expect to receive @PathVariable Long cityId
I can receive null but not undefined.
Environment
Angular 5.0.2
Browser tested:
- Chrome console (version 21.11.2017)
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 57
- Comments: 22 (3 by maintainers)
Since I use optional parameters quite a bit, I decided to write my own helper function which I have listed below in case it proves useful to others.
In a file named http-params.ts:
Then, when I need to create some HTTP parameters, I use it as follows:
For future readers, this can also be handled generically as an HTTP Interceptor:
Duplicate of #18567
This definitely should be the default behavior.
I would at least expect a property inside HttpParamsOptions.
For example:
new HttpParams({ fromObject: { a, b }, stripUndefined: true }) }
Default behaviour might be that it does not strip undefined.
An interceptor works, but shouldn’t be needed for something this simple 😃
We too seek that functionality (and believe it should come out of the box)
My solution is to add a new util method to remove “empty” object properties. And it can be used not only for http params.
We use the
lodash
library in our project. Here I used the_.pick()
method to make it more clear.That’s how I can use it:
The interceptor workaround appears to no longer work, since any
undefined
value is now stored as an actual string value"undefined"
making the comparison fail.That is, the value has been already changed to a string before the
HttpInterceptor
has a chance to see the actual initial value to remove anyundefined
ornull
values.The change was possibly introduced with this commit https://github.com/angular/angular/blame/ec8b52af69a2e04a7b077eb4d4309870ba40e273/packages/common/http/src/params.ts#L168 , which will ensure all values stored with
HttpParams
are strings.