Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular6 update query params without routing

The project, I am working on, has a lot of lists with search, sort and pagination. I am perfectly able to fetch data from API using these criteria (search, sort, pagination).

However, I was asked to make a "shareable links" so users can share their queried lists in between. If user A has his list ordered by 'Customer' and on page 5, sends link to user B, he or she will open the same list on page 5 ordered by 'Customer'. Simple.

I have a working solution. I subscribe to queryParams on ActiveRoute, parse these params and then reload list. See the code below.

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 consider this a dirty solution, particularly any action is handled through router. I would like first to avoid subscribe in ngOnInit and secondly update changePage function this way:

 changePage(event: number) : void {

    this.page = event;

    this.refresh();

    // update query params without triggering navigation
    this.route.queryParams['page'] = this.page; ??????
  }'

How is this possible?

like image 887
Luke1988 Avatar asked Sep 07 '18 15:09

Luke1988


1 Answers

Instead of navigation you can use location provider

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 refresh window in this case.

The way of dynamic creating URL:

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

this.location.go(urlTree)

But you can leave subscription inside ngOnInit hook, it's ok. To prevent router to update browser history you have to pass replaceUrl: true parameter

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

without forcing onSameUrlNavigation: 'reload' configuration angular router will not refresh your page anyway, it's ok to leave your solution as is

like image 157
Andreq Frenkel Avatar answered Nov 05 '22 17:11

Andreq Frenkel