title: Angular2: Routing to the same page and changing query parameters
body: <p>I have an <code>Angular 2</code> project where I want to do the following:</p>
  
  <p>Lets say I have a <code>Component</code> which has a datatable that supports paging and sorting.
  What I want to achieve is that every time the table page/size and sorting changes, to also change the <code>URL Parameters</code>. </p>
  
  <p>However when I access the particular component from the <code>Router</code> I also want to set the default URL parameters on the <code>Address Bar</code>
  So the sequence I thought of was the following:</p>
  
  <ol>
  <li>Navigate to my component with no parameters</li>
  <li>Set up the query parameters <code>Observable</code> on <code>NgOnInit</code> and upon receiving the first parameters
  reload the url again to set the default ones</li>
  <li>Every time a parameter changes navigate to current route. This will change the params so the query parameter <code>Observable</code> will emit the event. Then a new <code>Ajax</code> call will be triggered.</li>
  </ol>
  
  <p>Now this probably isnt the best idea but the problems I have are the following:
  1. The first time two <code>Ajax</code> calls are triggered
  2. If I click on the "current route" link on the page <code>NgOnInit</code> doesn't trigger so I cannot replace in the address bar the default parameters. </p>
  
  <p>A short version of the code is the following (I have purposely omitted imports/@Component annotation etc):</p>
  
  <pre><code>export class MyComponent implements OnInit, OnDestroy {
  
    private params = {page: 0, size: 5}
    private activatedRoute: ActivatedRoute;
    private router: Router;
    private data = []
  
    private pageLoaded = false;
    private queryParamsSubscription = new Subscription();
  
    constructor(
      private router: Router, 
      private activatedRoute: ActivatedRoute
      private http: Http) {}
  
      ngOnInit(): void {
        this.queryParamsSubscription = this.activatedRoute.queryParams
          .debounceTime(100)
          .switchMap((routeParams) =&gt; {
            //assign the Url Parameters to my params object
            this.params = Object.keys(routeParams)
              .reduce((params, key) =&gt; {
                params[key] = routeParams[key];
                return params
              }, this.params);
            if(!this.pageLoaded) {
              //if the page is not leaded yet run reloadRoute and only replace 
              //the url (true flag) without adding to browser history
              //this will only run once
              this.reloadRoute(true);
              this.pageLoaded = true;
            }
            //finally perform the ajax call with the new params
            //so basically whenever the url parameters change
            //then fire an ajax call
            return this.findAll(this.params)
          })
          .subscribe((data) =&gt; {
              this.data = data;
            }
          );
    }
  
    //request data from the server
    findAll(params: any) {
      let urlParams: : URLSearchParams = //create urlParams from param
      return this.http.get(this.baseUrl, new RequestOptions({search: urlParams}))
       .map((res: Response) =&gt; res.json())
       .catch(err =&gt; {
         console.error(err);
         return Observable.from(err);
       })
    }
  
    ngOnDestroy(): void {
      this.queryParamsSubscription.unsubscribe();
    }
  
    onChangePageSize(size) {
      this.params['size'] = page.size
    }
  
    onChangePage(page) {
      this.params['page'] = page.page - 1;
      this.reloadRoute();
    }
  
    //this basically is called every time a parameter changes
    //so I navigate to the same page with the new parameters
    private reloadRoute(replaceUrl: boolean = false) {
  
      this.router.navigate(
        [this.activatedRoute.routeConfig.path], 
        {queryParams: params, replaceUrl: replaceUrl}
      );
    }
  
  }
  </code></pre>