Angular url plus sign converting to space
You can override default angular encoding with adding Interceptor which fixes this:
import { HttpInterceptor, HttpRequest, HttpEvent, HttpHandler, HttpParams, HttpParameterCodec } from "@angular/common/http";import { Injectable } from "@angular/core";import { Observable } from "rxjs";@Injectable()export class EncodeHttpParamsInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const params = new HttpParams({encoder: new CustomEncoder(), fromString: req.params.toString()}); return next.handle(req.clone({params})); }}class CustomEncoder 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); }}
and declare it in providers section of in app.module.ts
providers: [ { provide: HTTP_INTERCEPTORS, useClass: EncodeHttpParamsInterceptor, multi: true }]
This ia a common problem. The +
character is used by the URL to separate two words. In order to use the +
character in the parameter values, you need to encode your parameter values before adding them as part of the URL. Javascript / TypeScript provide a encodeURI()
function for that specific purpose.
URL encoding converts characters into a format that can be transmitted over the Internet. [w3Schools Reference]
Here is how you can fix this problem:
let encodedName = encodeURI('xyz+manwal');let encodedURI = 'http://localhost:3000/page?name='+encodedName;//.. OR using string interpolationlet encodedURI = `http://localhost:3000/page?name=${ encodedName }`;
In the same way, you can decode the parameters using decodeURI()
method.
let decodedValue = decodeURI(encodedValue);
In Angular 5.2.7+ the "+" is replaced with space " " in a query string.
Here is the corresponding commit : fix(router): fix URL serialization
If you want to change this behaviour and replace the "+" with "%2B" you can create a custom url serializer and provide it in the AppModule providers.
import { DefaultUrlSerializer, UrlSerializer, UrlTree } from '@angular/router';export default class CustomUrlSerializer implements UrlSerializer { private _defaultUrlSerializer: DefaultUrlSerializer = new DefaultUrlSerializer(); parse(url: string): UrlTree { // Encode "+" to "%2B" url = url.replace(/\+/gi, '%2B'); // Use the default serializer. return this._defaultUrlSerializer.parse(url); } serialize(tree: UrlTree): string { return this._defaultUrlSerializer.serialize(tree).replace(/\+/gi, '%2B'); }}@NgModule({ imports: [ BrowserModule, BrowserAnimationsModule, AppRoutingModule ], declarations: [ AppComponent ], providers: [ { provide: UrlSerializer, useClass: CustomUrlSerializer } ], entryComponents: [], bootstrap: [AppComponent]})export class AppModule {}
http://localhost:3000/page?name=xyz+manwal
The URL will be converted to:
http://localhost:3000/page?name=xyz%2Bmanwal
Hope this will help.