How to dynamically update Angular6 query parameters without changing routes

Lately, the project I've been focused on involves managing numerous lists with search, sort, and pagination functionalities. I have successfully implemented data fetching from an API based on these criteria.

Recently, a new requirement emerged - the ability for users to share specific lists by generating shareable links. For example, if User A customizes their list by sorting it by 'Customer' and navigating to page 5, they should be able to send that link to User B who will then open the same list on page 5 sorted by 'Customer'. Simple concept, but crucial feature.

I devised a solution where I subscribe to queryParams on ActiveRoute, parse these parameters, and reload the list accordingly. Here's a snippet of the code:

Component Template HTML:

<ngb-pagination [collectionSize]="size" [page]="page" (pageChange)="changePage" >
</ngb-pagination>
<pre>Current page: {{page}}</pre>

Component Typescript:

ngOnInit() {

    this.route
      .queryParams
      .subscribe(queryParams => {

          this.sort = queryParams['sort'];
          this.search = queryParams['search'];
          this.page= +queryParams['page'] || 1;

          this.refresh();
    });

    this.refresh();
}

refresh() : void {

    this.transactionsService.fetch({
      from: (this.page - 1) * this.size,
      take: this.size,
      search: this.search,
      sort: this.sort
    }).subscribe(data => {

      this.entities = data.entities;

      this.total_size = data.total;
    });

}

changePage(event: number) : void {

    this.router.navigate(['/transactions'], { 
      queryParams : { page: event},
      queryParamsHandling: 'merge'
    });
  }

However, I am not completely satisfied with this approach as I feel it is somewhat messy, especially since all actions are routed through the primary router. I am exploring ways to optimize this process such as avoiding subscription in ngOnInit and enhancing the changePage function logic:

 changePage(event: number) : void {

    this.page = event;

    this.refresh();

    // Need to find a way to update query params without triggering navigation
    this.route.queryParams['page'] = this.page; ??????
  }'

Seeking guidance on how to achieve this effectively.

Answer №1

Opt for the location provider instead of navigation

import { ActivatedRoute, Router } from '@angular/router';  
import { Location } from '@angular/common';

...
constructor(
    private router: Router,
    private location: Location,
    private activatedRoute: ActivatedRoute,
    ...
)

changePage(event: number) : void {
  ...       
  this.location.go(`${this.activatedRoute.url}?page=${event}` );
  ...
}

this.location.go will not trigger window refresh in this scenario.

A dynamic way to create URLs:

const urlTree = this.router.createUrlTree([], {
    queryParams: { page: event },
    queryParamsHandling: 'merge',
    preserveFragment: true 
});

this.location.go(urlTree)

However, it's acceptable to keep subscription within the ngOnInit hook. To prevent the router from updating the browser history, ensure you include the parameter replaceUrl: true

this.router.navigate([], { 
  relativeTo: this.activatedRoute, 
  queryParams: 
  {
      page: event
  },
  replaceUrl: true,
});

If you do not configure onSameUrlNavigation: 'reload', Angular router will not automatically refresh your page; therefore, it is fine to maintain your current solution

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

Angular 2: Implementing a Universal CSS Style Sheet

Is there a way to include a universal CSS file in Angular 2 applications? Currently, I have multiple components that share the same button styling, but each component has its own CSS file containing the styles. This setup makes it difficult to make changes ...

Angular Universal build stuck on rendering page while waiting for API response

I'm currently developing a compact web application using the angular universal starter in combination with pokeapi. To enhance performance and reduce API requests, I intend to implement pre-rendered pages since the data displayed remains mostly static ...

How to connect multiple HTTP requests using observables in Angular 7

Is there a more efficient way to remove an alert only if it is not assigned to any user? Currently, I am checking my users list and filtering out the users who have this alert assigned using observables. But I wonder if there is a better approach to achi ...

You cannot use 'ReactPlayer' as a JSX element

I'm currently facing an issue with my React project where I am trying to integrate react-player. In my TypeScript setup, I encountered the following error during the build process: 'ReactPlayer' cannot be used as a JSX component. Its instan ...

Troubleshooting Typescript in Intellij for Cordova Mobile Application

Considering developing a new Cordova application using Typescript and Ionic in Intellij. Currently, I use JavaScript for development and utilize the chrome remote debugging feature to step through the code on the device. Is there a way to achieve remote d ...

Can you identify the specific error type that occurs in the onError function of react-query's MutationCache when using Typescript

Can someone help me with identifying the type of error in react-query MutationCache onError function when using Typescript? I also need guidance on how to override the type so that I can access and use the fullMessage from the data. const queryClient = new ...

Numerous mistakes detected in the TypeScript code

I've implemented the following class within an ASP.NET Core React application: import * as React from 'react'; interface MyInputProps { inputType: string; id: string; className: string; parentFunctio ...

What are the steps for integrating TypeScript code into a Vue component?

https://github.com/bradmartin/nativescript-texttospeech This texttospeech package has TypeScript documentation available. Is there a way to convert this code for use in NS-Vue? import { TNSTextToSpeech, SpeakOptions } from 'nativescript-texttospeec ...

Setting up Cypress.config file for SQL database testing with Cypress

Currently, I am looking to experiment with SQL databases. I have SqlWorkbench installed and have mysql added in my package file. However, I encountered an issue while attempting to run Cypress as SyntaxError: Unexpected token 'export' The probl ...

The data structure does not match the exact object type

Why isn't this code snippet functioning as expected? It seems that 'beta' has keys of type string and their values are compatible (id is a number type, and temp is also a number type). Additionally, the Record function should make the values ...

Angular assets generated by JHipster

I am working on a sample jhipster app with angular as the front-end. The structure of my folders is as follows: src |-webapp |--app |---content |----images |-----jhipster_family_member_0.svg I am curious about how webpack recognizes the content folder as ...

Is it possible to determine the type of a variable by simply clicking on it in IntelliJ (specifically in typescript)?

Having the ability to hover over a variable and see the expected type in TypeScript would be incredibly beneficial. I'm curious if there is some sort of internal static analysis being conducted that stores this information. Is there a method for acces ...

Encountering an Error on Building Android with Ionic 2 RC0 and Angular 2: ngc error during symbol values resolution

An error occurs when trying to build the Android application using the command ionic build android. The error message reads: "ngc: Error: Error encountered resolving symbol values statically. Reference to a local (non-exported) symbol 'dictionary&apo ...

Warning from Firebase CLI deployment: The Node.js 8 runtime has been marked as deprecated and is scheduled to be phased out by 2020-12-05

Attempting to deploy TypeScript onto my FCF isn't working as expected based on the documentation and official Firecasts video. When deploying the default code (helloworld) instead of TypeScript, it deploys a node.js file which is confusing. Below are ...

Is it possible to omit the expression of <T> when it is not necessary to define?

Is there a way to write code without using the <T> notation when it's not necessary? Here is what I have in mind: interface Props<?T> { className: string data?: T } const props: Props = {className: "hello, world"} const pro ...

What could be causing the error in Angular 5 - Webpack when using postcss-merge-rules vesion?

Issue with postcss plugin Upon attempting a ng build --prod, I encountered this log error. The problem seems to be related to angular universal and specifically affects bootstrap and font-awesome. 10% completion building modules 4/6 modules 2 active ...u ...

The Angular Material date picker's keyboard input format is functional only in Chrome

I'm facing a challenge with the date picker component from Angular Material. When I try to manually type in a date like "2019.12.20" instead of selecting it, the input only works in Google Chrome. But when I tested it on Edge and Firefox, the date val ...

angular2 npm is experiencing a 404 error across all rc1 packages

Having trouble updating to Angular2 rc1, as npm seems to be unable to fetch the necessary packages: { "name": "App", "version": "1.0.0", "license": "MIT", "dependencies": { "@angular/common": "2.0.0-rc.1", "@angular/compiler": "2.0.0-rc.1" ...

How to Connect to Printer in Ionic 2

Does anyone know if there is an option to implement printing/connecting a printer from Ionic 2? Is there a Cordova plugin available for printing? I found this plugin: Cordova Print plugin Any help/information on this would be greatly appreciated. Also, i ...

Using React and TypeScript together can lead to issues when trying to use union keys as an index

I've implemented a hook using useState and the delete method to effectively manage my form values. const [values, setValues] = useState<tAllValues>({}); The values stored include: { name: 'Andrew', age: 34, avatar: [{ name: ...