In an Angular Service I'm using HttpParams to send a string to the service:
get(phone: string): Observable<PhoneSearchResponse> {
let params = new HttpParams();
params = params.append("phone", phone); // sending "+123456"
return this._http.get<PhoneSearchResponse>(`${this._apiurl}/Get`, { params: params });
}
When calling get() with +123456
as parameter I'll get 123456
in the receiving service. So somewhere on the way the +
gets converted to a space.
Do I need to escape HttpParams to get them unchanged to the service?
If it matters, the backend is an asp.net core project. The called code in the controller:
[HttpGet("[action]")]
public async Task<JsonResult> Get(string phone) // receiving " 123456"
{
return Json(await PhoneSearchLogic.GetAsync(phone));
}
[Update] Very good explanation by Noémi Salaün - but I wonder if changing the parameters is expecteded behaviour "by design"? Or is the problem the ASP.NET Core controller, which should not unescape the + sign (and others)?
This post is a guide on how to Pass the URL Parameters or Query Parameters along with the HTTP Request using the HttpClient in Angular. We will be using HttpParams to add the URL Parameter, which is then used by the GET , POST , PUT & PATCH etc methods to send an HTTP request to the back end API.
Passing multiple parameters to Http get requestBy using HttpParams. append() we can pass multiple parameters to HttpClient. get() method. We have to pass page & per_page parameters to the list of users API.
As you can see in the source code common/http/src/params.ts, HttpParams
uses a default encoder HttpUrlEncodingCodec
.
HttpUrlEncodingCodec
uses the native encodeURIComponent
function but then un-encodes some symbole to meet the RFC specification (not followed by the native JS implementation).
So if you want to keep your +
symbol encoded you can encode it manually before using HttpParams
, or you can override the HttpParameterCodec
with your own implementation and pass it through the HttpParamOptions.encoder
attribute.
All this was better explained in the now deprecated Http
service. With its UrlSearchParams
and the QueryEncoder
.
As you can see in the source code http/src/url_search_params.ts
By default,
QueryEncoder
encodes keys and values of parameters usingencodeURIComponent
, and then un-encodes certain characters that are allowed to be part of the query according to IETF RFC 3986: https://www.rfc-editor.org/rfc/rfc3986.These are the characters that are not encoded:
! $ \' ( ) * + , ; A 9 - . _ ~ ? /
If the set of allowed query characters is not acceptable for a particular backend,
QueryEncoder
can be subclassed and provided as the 2nd argument to URLSearchParams.
Angular 13 still has this problem. Look at
https://github.com/angular/angular/issues/11058 and
https://github.com/angular/angular/pull/45111
The solution that worked for me was written by Ali Kamalizade at
https://betterprogramming.pub/how-to-fix-angular-httpclient-not-escaping-url-parameters-ddce3f9b8746
The following is his solution. The same solution was suggested by Noémi Salaün in the accepted answer of this question.
import { HttpParameterCodec } from '@angular/common/http';
export class CustomHttpParamEncoder implements HttpParameterCodec {
encodeKey(key: string): string {
return encodeURIComponent(key);
}
encodeValue(value: string): string {
return encodeURIComponent(value);
}
decodeKey(key: string): string {
return decodeURIComponent(key);
}
decodeValue(value: string): string {
return decodeURIComponent(value);
}
}
You can use it when you create a HttpParams.
HttpParams({ encoder: new CustomHttpParamEncoder() })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With