After searching online without success, I decided to create my own versatile class that wraps the existing Params
object and allows for case-insensitive access to query string parameters.
Here's how you can incorporate it into your component:
import { ActivatedRoute } from '@angular/router';
import { CaseInsensitiveParamMap } from '../case-insensitive-param-map';
constructor(private activatedRoute: ActivatedRoute) {}
ngOnInit(): void {
// Subscribe to changes in query params:
this.activatedRoute.queryParams.snapshot.paramMap
.subscribe((params) => this.handleQueryParamsChanged(new CaseInsensitiveParamMap(params)));
// Or directly use params from the route snapshot:
const paramMap = new CaseInsensitiveParamMap(this.activatedRoute.snapshot.queryParams);
const returnUrl = paramMap.get('returnUrl');
}
private handleQueryParamsChanged(paramMap: CaseInsensitiveParamMap): void {
const returnUrl = paramMap.get('returnUrl');
// Retrieves the value of the first query param named 'returnUrl' regardless of case sensitivity
}
Additionally, I've included a helpful getNumber
method that simplifies parsing numeric query params. It returns null
if the value is not a number or doesn't exist.
Below is the implementation of the class:
case-insensitive-param-map.ts
import { ParamMap, Params } from '@angular/router';
export class CaseInsensitiveParamMap implements ParamMap {
private params: Params;
constructor(params: Params) {
this.params = params || {};
}
has(name: string): boolean {
return Object.keys(this.params).some((key) => key.toLowerCase() === name.toLowerCase());
}
private getKeysCaseInsensitively(name: string): string[] {
return Object.keys(this.params).filter((key) => key.toLowerCase() === name.toLowerCase());
}
get(name: string): string | null {
if (this.has(name)) {
const keys = this.getKeysCaseInsensitively(name);
const value = this.params[keys[0]];
return Array.isArray(value) ? value[0] : value;
}
return null;
}
getNumber(name: string): number | null {
const value = this.get(name);
return !value || isNaN(Number(value)) ? null : Number(value);
}
getAll(name: string): string[] {
if (this.has(name)) {
const result: string[] = [];
this.getKeysCaseInsensitively(name).forEach((key) => {
const value = this.params[key];
result.push(...(Array.isArray(value) ? value : [value]));
});
return result;
}
return [];
}
get keys(): string[] {
return Object.keys(this.params);
}
}
For testing purposes and documentation, here are the accompanying tests:
case-insensitive-param-map.spec.ts
import { Params } from '@angular/router';
import { CaseInsensitiveParamMap } from './case-insensitive-param-map';
describe('CaseInsensitiveParamMap', () => {
// Test cases go here...
});