'Angular 13 router: Combining path parameters, query parameters and fragment into a single observable that updates only once per navigation event

In Angular 13 I have a route that evaluates query parameters, path parameters and the fragment. Whenever a navigation to the route happens during which any number of the parameters changes, I want to handle all changes in one singe event.

Currently the component registered for the route combines the parameters into a single observable using combineLatest:

ngOnInit(): void {
    combineLatest([
      this.route.params, 
      this.route.queryParams, 
      this.route.fragment
    ])
    .pipe(map(p => {
      return { 
        id:         p[0]['id'],       // path parameter 'id'
        filter:     p[1]['filter'],   // query parameter 'filter'
        section:    p[2]              // fragment
      };
    }))
    .subscribe(p => {
      // handle parameter update
      // fetch data from backend
    });
  }

When navigating from route (id = 1, section = undefined) to route (id = 2, section = 1) using the routerLink directive, the code in the subscription is executed twice - first time for the change in the fragment (id = 1, section = undefined) --> (id = 1, section = 1) and a second time for the change of the id (id = 1, section = 1) --> (id = 2, section = 1).



Solution 1:[1]

The solution suggested by Barney in the comments works: Including debounceTime(0) to the map solves the problem.

ngOnInit(): void {
    combineLatest([
      this.route.params, 
      this.route.queryParams, 
      this.route.fragment
    ])
    .pipe(
      map(p => {
        return { 
          id:         p[0]['id'],       // path parameter 'id'
          filter:     p[1]['filter'],   // query parameter 'filter'
          section:    p[2]              // fragment
        };
      }), 
      debounceTime(0)                   // <--- SOLUTION !!!
    )
    .subscribe(p => {
      // handle parameter update
      // fetch data from backend
    });
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JCvanDamme