Issue with RouterLink not recognizing QueryParams

I have encountered an issue where dynamically generated URLs with queryParams inside [routerLink] are breaking routes.

For example:

this.url = '/question/ask?details=1'

<a [routerLink]="url"> {{ data.name }}</a>

Upon mouseover, the URL appears as #/question/ask%3Fdetails%3D1 and breaks when clicked.

Unfortunately, passing [queryParams] separately is not possible due to the dynamic nature of the URLs. However, the following workaround works:

<a [routerLink]="/question/ask" [queryParams]={details: 1}> {{ data.name }}</a>

Is there any solution to pass a complete URL with queryParams inside [routerLink]?

Answer №1

Summary:

When you use the routerLink directive in Angular, it automatically encodes the URL by calling the encodeURI function on the value passed to it.


Detailed Explanation

The reason behind this behavior is that when a complete URL is directly passed to the routerLink, it triggers the serializeUrl method within the directive. This method internally calls the serialize function of urlSerializer. You can view the implementation of the serialize method here.

serialize(tree: UrlTree): string {
    const segment = `/${serializeSegment(tree.root, true)}`;
    const query = serializeQueryParams(tree.queryParams);
    const fragment =
        typeof tree.fragment === `string` ? `#${encodeUriFragment(tree.fragment !)}` : '';

    return `${segment}${query}${fragment}`;
}

export function encodeUriFragment(s: string): string {
    return encodeURI(s);
}

A potential solution to address this issue would be to decode the URL using the built-in parseUrl method provided by Angular's Router. This method helps extract information such as the root of the URL, along with parameters and query strings.

Component

@Component({
  ...
})
export class AppComponent {
  name = 'Angular 6';
  url: any;
  formattedUrl: any;
  params: any = {};

  constructor(private router: Router) {
  }

  ngOnInit() {
    this.urlDecoder();
  }

  urlDecoder() {
    this.url = '/a?i=1 a';
    let parsedUrl = this.router.parseUrl(this.url);
    console.log(parsedUrl)
    const g: UrlSegmentGroup = parsedUrl.root.children[PRIMARY_OUTLET];
    const s: UrlSegment[] = g.segments;
    this.formattedUrl = `${s.map(p => p.path).join('/')}`; // needed to combine all consecutive segments
    this.params = parsedUrl.queryParams;
  }
}

HTML

<a [routerLink]="formattedUrl" [queryParams]="params">
  Link Here
</a>

View Demo on StackBlitz

Answer №2

Give this a shot:

this.url = ['/page', 'create']; //Perhaps without the slash: ['page', 'create']
this.query = {info: 1};

HTML:

<a [routerLink]="url" [queryParams]="query">Go Somewhere</a>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The console is displaying an undefined error for _co.photo, but the code is functioning properly without any issues

I am facing an issue with an Angular component. When I create my component with a selector, it functions as expected: it executes the httpget and renders a photo with a title. However, I am receiving two errors in the console: ERROR TypeError: "_co.photo ...

Obtaining attributes of a class from an object passed into the constructor

Consider the following code snippet: interface MyInterface { readonly valA: number; readonly valB: number; } class MyClass { readonly valA: number; readonly valB: number; constructor(props: MyInterface) { this.valA = props.val ...

Is it possible to dynamically change an ngModel value directly from the component?

I'm currently immersed in an Angular project and my initial file setup was like this: dog.ts: export interface Dog { name: string; age: number; breed: string; } dog.component.ts: import { Dog } from '../dog'; @Component({ //setup ...

most efficient method of sharing information between various angular controllers

I am looking for a way to share form data among multiple controllers before submitting it. Currently, I am using module.value() to store the data as a global variable. var serviceApp = angular.module('sampleservice', [ ]); serviceApp.valu ...

Tips on retrieving a strongly typed value from a method using Map<string, object>

Having had experience working with C# for a while, I recently ventured into a Node.js project using TypeScript V3.1.6. It was exciting to discover that TypeScript now supports generics, something I thought I would miss from my C# days. In my C# code, I ha ...

Puppeteer with Typescript: Encountering issues during the transpilation process

The issue stems from the fact that I am unable to use Javascript directly due to Firebase Functions Node.JS version lacking support for Async/Await. As a workaround, I have converted the code into Typescript and am currently attempting to transpile it to c ...

Troubleshooting Problem with Next.js 13 Integration, Supabase, and Server Actions in layout.tsx

I'm currently developing a Next.js 13 application and experimenting with managing user authentication through Supabase. I've encountered some challenges when attempting to verify if a user is logged in using an asynchronous function within my lay ...

What is the best way to ensure the secure signing of a transaction in my Solana decentralized application (

I am currently involved in an NFT project that recently experienced a security breach, and I am developing a dapp to rectify the situation. Our plan is to eliminate all NFTs from the compromised collection and issue a new set of NFTs using our updated auth ...

Challenges with incorporating asynchronously fetched data in component operations

I have encountered an issue where the data retrieved from a server in a service is available in the component's template but not in the actual code. This seems strange to me. I made the call in the ngOnInit method of my main AppComponent ngOnInit() { ...

Exploring the possibilities of updating carousel items in Angular using Bootstrap

I'm working on a project where I have 4 images and a carousel that needs to navigate to the respective index when one of the images is clicked. The challenge is that the carousel is built with Bootstrap and jQuery, but the rest of the application is A ...

Easy Steps to Simplify Your Code for Variable Management

I currently have 6 tabs, each with their own object. Data is being received from the server and filtered based on the tab name. var a = {} // First Tab Object var b = {} // Second Tab Object var c = {} // Third Tab Object var d = {}// Fou ...

I'm curious if there is an eslint rule specifically designed to identify and flag any unnecessary spaces between a block comment and the function or

Can anyone help me find a solution to prevent the following issue: /** * This is a comment */ function foo() { ... } I need it to be corrected and formatted like this: /** * This is a comment */ function foo() { ... } ...

What is the best way to disable a collapsed section in VS Code using comments?

I'm wondering how to properly comment out a "folded" section of code using VS Code. For instance, I want to comment out the collapsible region: if (a == b) { dance(); } I am familiar with the keyboard shortcut for folding regions: Ctrl + Shift + ...

Determining the absence of a value using ng-if

Within my loop through a dataset, I am working on determining the setup of folders for a href link. Currently, I have an ng-if statement for each option, but I am facing an issue with checking one of the ng-ifs. Specifically, I need to check if a value is ...

Instructions on changing row color with button click and reverting back to original color upon subsequent click

When the button is pressed, I'd like to change the color. When the same button is pressed again, I want it to revert back to its original color. Currently, when the button is clicked, all rows change color. Sample Code Snippet: <table> & ...

The concept of nested labels: defining conditions for displaying specific sections of a label

Let's say I have a label that contains the following text: <label>This is a text. This is another text.</label> Is there a way to indicate that the second sentence should only be visible when a boolean value is true? For example: <la ...

Are node.js and AngularJS connected in any way?

Node.js relies on npm for package management, while AngularJS CLI also uses npm for its modules. Is there a connection between these two? I have installed Node.js and tested it with a simple 'hello.js' file containing just one line of code: con ...

What methods can a controller use to verify the legitimacy of the scope?

I'm a bit perplexed when it comes to validation in angular. It seems like all of the validation is connected to the form. But what happens when the controller needs to ascertain if the model is valid or not? Here's an example I quickly whipped u ...

Creating objects based on user input in AngularJS is a common task for developers. This tutorial will

When populating a form with radio buttons based on a JSON object, the user can select options and upon clicking submit, all radio button data is saved into an object. <form name="regForm"> <ul> <li ng-repeat="q in ...

The rapid execution of code causing an observable race condition

When exporting a CSV file in my code, I encounter a race condition while trying to modify some data before the export. The issue is that the id gets set correctly, but the number only updates after the method is called a second time. I believe the proble ...