-1

I want to get the query string parameters. I could do it in the component's constructor() or in ngOnInit(). Also, there are two ways to do that:

// option (1)
const foo = this.activatedRoute.snapshot.queryParamMap.get("foo");
//use foo...

// option (2)
const subscription = this.activatedRoute.queryParamMap.subscribe(params => {
  const foo = params["foo"];
  //use foo...
});
// ...and remember to unsubscribe in `ngOnDestroy()`

There are lots of questions from people who have trouble getting the query string, and the answer is always to use option (1) or (2), but there's never an explanation why. I've used both ways and I've never had a problem, so far.

So:

  • when should I use (1) and when should I use (2)?
  • should I do it in the constructor() or ngOnInit()?
lonix
  • 14,255
  • 23
  • 85
  • 176
  • 1
    Have you read e.g. https://link.medium.com/dZHjDJ2WGY – jonrsharpe Jul 28 '19 at 13:15
  • @jonrsharpe Never saw that, I usually read the docs and read here on SO, where peer review filters out bad advice. Thanks for the link, I'll check it out now. – lonix Jul 28 '19 at 13:17
  • There's material here, too: https://stackoverflow.com/questions/46050849/what-is-the-difference-between-activatedroute-and-activatedroutesnapshot-in-angu – jonrsharpe Jul 28 '19 at 13:18
  • Hey @jonrsharpe that blog article was great and the associated stackblitz is the best visual explanation I've seen... thanks! I linked to it below as well. – lonix Jul 28 '19 at 13:45

3 Answers3

1

Option(1) - this option is fine, it's simple and if you are not expecting that queryString will change, then I would stick to this.

Option(2) - this option is still fine but is more complicated, since you need to subscribe to it. However this option has advantage - you can react to URL changes. So if you expected that this URL will change while the component is living, then feel free to use this option.

Btw. you don't need to unsubscribe from it since the ActivatedRoute and its observables are insulated from the Router itself. The Router destroys a routed component when it is no longer needed and the injected ActivatedRoute dies with it.

When it comes to where you should init it, constructor is better place to do this, less code and your URL is ready before OnInit Hook anyway, so you can use this faster. I'm using constructor (as the name says) for construct variables.

DiPix
  • 5,755
  • 15
  • 61
  • 108
1

About where put your code, use constructor() to set up Dependency Injection and not much else. ngOnInit() is better place to "start". It's where/when the components' bindings are resolved.

About get the values once or subscribe, it depends a bit on how your application works. In case your app will change the URL with new parameters without reloading the page angular won't rerun the ngOnInit method so your component won't react appropriately to the new values. It is up to you subscribe to this change and run your logic.

Andoni
  • 171
  • 9
0

A link by @johnrsharp above, led me to this stackblitz which is a brilliant visual explanation.

Also:

  • Use route.snapshot.queryParamMap when you'll never change the route within the component. So the original snapshot is enough.
  • Use route.queryParamMap.subscribe when you'll change the route from within the component, so you'll need to react to the latest values.

I'm doing this in ngOnInit() as the UI is setup at that point, so there is no chance of anything being undefined. Basically, it avoids a race condition.

lonix
  • 14,255
  • 23
  • 85
  • 176