1

I have a quite simple request: I would like to investigate the activateRoute observables (both paramMap and queryParamMap) - I would like set component variables according to the results of them. Tried doing that using rxjs operators pipe and flatMap, but couldn't result it successfully. See my code:

param1: number;
param2: string;


ngOnInit() {
  this.activatedRoute.paramMap.pipe(
    flatMap(params => {
      this.param1 = +params.get(<name Of Param>);
      return this.activatedRoute.queryParamMap;
    }),
    flatMap(queryParams => {
      this.param2= queryParams.get(<name of query param>);
    })
  ).subscribe(result => /*no need to do anything*/);
Guy E
  • 1,775
  • 2
  • 27
  • 55
  • This is needlessly convoluted. It's also incorrect, since you will only get new queryParams if the params change, and you create a new subscription to queryParamMap every time a param changes. Just subscribe to paramMap, and also subscribe to queryParamMap. – JB Nizet Nov 11 '18 at 11:54
  • @JBNizet - this was my quesion - How do I subscribe to both paramMap and queryParamMap - making it sync. – Guy E Nov 11 '18 at 12:34
  • What do you mean by "making it sync"? The first one emits when the parameters change. The second one happens when the queryParams change. That doesn't necessarily happen at the same time. Can't you just use `this.activatedRoute.paramMap.subscribe(...); this.activatedRoute.queryParamMap.subscribe(...);`? If not, why? What are you trying to achieve? – JB Nizet Nov 11 '18 at 12:37
  • @JB Nizet - I need them both in the same scope - I need to make an "If then" flow depending on them both. I intend to execute a function after checking them both - 2 different independent subscriptions won't work for me – Guy E Nov 11 '18 at 13:08
  • 1
    Then just use something like `merge(route.paramMap, route.queryParamMap).subscribe(() => doSomething(route.snapshtot))`. The paramMap and the queryParamMap of the snapshot contain the current values of everything. – JB Nizet Nov 11 '18 at 13:14

2 Answers2

2

If you always want the latest value of both, use combineLatest.

combineLatest(
    this.activatedRoute.paramMap,
    this.activatedRoute.queryParamMap
).subscribe( ([paramMap, queryParamMap]) =>
    // do stuff here
);
pascalpuetz
  • 5,238
  • 1
  • 13
  • 26
1

Actually you should use the switchMap instead of mergeMap since you don't need the result of all the Observable at the end.

param1: number;
param2: string;

ngOnInit() {
  this.activatedRoute.paramMap.pipe(
    switchMap(params => {
      this.param1 = +params.get(<name Of Param>);
      return this.activatedRoute.queryParamMap;
    }),
    map(queryParams => {
      this.param2= queryParams.get(<name of query param>);
    })
  ).subscribe(result => /*no need to do anything*/);
Sunil Singh
  • 11,001
  • 2
  • 27
  • 48
  • It is actually bad practice to induce side effects in a map. I'd move the code inside your map function to the subscribe function. The same applies to switchmap, though you cannot move that to subscribe. This solution seems like a bad practice to me. – pascalpuetz Nov 11 '18 at 17:59
  • Is there a way to use the tap operator on queryParamMap to achieve a side effect (such as assigning value from queryParamMap to another variable), without having to subscribe to queryParamMap? I'm trying to write code by relying more on rxjs operators as opposed to subscribing and unsubscribing all the time to avoid unanticipated memory leaks. I tried something like "this.activatedRoute.queryParamMap.pipe(tap(val => console.log(val)))" but got nothing on the console even though queryParamMap has a value. – coder101 Sep 01 '20 at 09:57