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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With