1
votes

I would like to create a service that subscribes to changes in Angular's paramMap. Unfortunately this doesn't seem to work.

export class LocationResourcesService {

  constructor(private activatedRoute: ActivatedRoute) {

    this.activatedRoute.paramMap.pipe(
      map((params: ParamMap) => params.get('account-id')),
    ).subscribe((newValue) => console.log(newValue))
  }
  // ----------
}

Tthe subscription above only ever emits one value - when Angular first loads into the page. And that value is null. The same subscription does when it's placed in the constructor of a component that's active in the page. presumably because the route has loaded and the ActivatedRoute has been set.

I would have assumed that ActivatedRoute was a singleton service and that I could therefore subscribe to changes on it. Obviously that's not the case though so how can this service subscribe to the value of activatedRoute.ParamMap?

1
Does your router correctly analyzes the route? try the enableTracing option and see if the account-id param appears when you navigate to the relevant route. - Shy Agam

1 Answers

0
votes

There's unfortunately no easy answer to this. I'm not going to reproduce the whole discussion but the solution can be seen here: https://github.com/angular/angular/issues/11023#issuecomment-399667101.

And I'm copying it across to make it easy to get a feel for it. As I said, it's not straightforward:

import { Injectable } from '@angular/core';
import { ActivatedRoute, Router, NavigationEnd, Params } from '@angular/router';
import { filter, switchMap } from 'rxjs/operators'
import { of, Observable } from 'rxjs'

@Injectable()
export class MiscService {

  params$: Observable<Params>

  constructor( private router: Router,
              private route: ActivatedRoute) {

    // Create an observable representing the params
    this.params$ = this.router.events.pipe(
      filter(event => event instanceof NavigationEnd),
      switchMap(() => {
        const params = this.route.firstChild?.params
        // return params or an empty observable 
        return params || of()
      })
    )
    
    // subscribe to the params$ observable - can be done for 
    // multiple observers
    this.params$.subscribe((params) => {
      console.log('params', params)
    })
  }

}