Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change of queryparam not detected

I'm having a problem to sync my filter properly. I subscribe to the queryParams of ActivatedRoute. There I get the query and my three filter criteria.

 ngOnInit() {
    this.route
      .queryParams
      .subscribe(queryParams => {
        this._query = queryParams['query'];
        this._heightFilter = queryParams['height'];
        this._colourFilter = queryParams['colour'];
        this._weightFilter = queryParams['weight'];
        // Do some request to WS to get the new data
      });
  }

When ever I click on a filter, lets say colour:blue, I call my reloadPage() and give the new queryparams and navigate to the same page just with the new queryparams.

  private reloadPage(): void {
    const queryParams: NavigationExtras = {};
    queryParams['query'] = this._query;
    //Bring filter arrays into shape for queryParams
    this.prepareFiltersForParams(queryParams);
    this.router.navigate([], {
      queryParams,
    });

This works all fine. Now we have selected colour:blue, but I also want colour:orange. I will be added to the queryParams['colour'], which then contains blue and orange. But for some reason orange is nether added to the url, even it exits in queryParams['colour']. If I add now a filter of another criteria, lets say height, everything works nice and smooth and the height filter will be added and also the colour:orange.

It seems to me that the change detection of the this.route.queryParams.subscribe is just not picking up the change of the queryParams['colour'] and therefore just not updates.

I also opened a GH issue angular#17609.

like image 425
tschaka1904 Avatar asked Jun 19 '17 11:06

tschaka1904


1 Answers

See the angular documentation https://angular.io/guide/router#activatedroute-the-one-stop-shop-for-route-information.

You probably need to use the switchmap operator:

Since the parameters are provided as an Observable, you use the switchMap operator to provide them for the id parameter by name and tell the HeroService to fetch the hero with that id.

The switchMap operator allows you to perform an action with the current value of the Observable, and map it to a new Observable. As with many rxjs operators, switchMap handles an Observable as well as a Promise to retrieve the value they emit.

The switchMap operator will also cancel any in-flight requests if the user re-navigates to the route while still retrieving a hero.

From the tour of heroes (https://angular.io/tutorial/toh-pt5#revise-the-herodetailcomponent):

The switchMap operator maps the id in the Observable route parameters to a new Observable, the result of the HeroService.getHero() method.

If a user re-navigates to this component while a getHero request is still processing, switchMap cancels the old request and then calls HeroService.getHero() again.

like image 124
Kylos Avatar answered Sep 19 '22 22:09

Kylos