Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to read querystring parameters from App.Component

I would like to centralize where/how I read a specific querystring parameter throughout my application, so I figured the best place to do this was in the app.component.ts

export class AppComponent implements OnInit, OnDestroy {
  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute) {
  }

Then, on ngOnInit(), I am looking in the snapshot as well as different subscriptions:

  ngOnInit(): void {
    console.log('AppComponent - ngOnInit() -- Snapshot Params: ' + this.activatedRoute.snapshot.params['code']);
    console.log('AppComponent - ngOnInit() -- Snapshot Query Params: ' + this.activatedRoute.snapshot.queryParams['code']);
    console.log('AppComponent - ngOnInit() -- Snapshot Query ParamMap: ' + this.activatedRoute.snapshot.queryParamMap.get('code'));

    this.activatedRouteParamsSubscription = this.activatedRoute.params.subscribe(params => {
      console.log('AppComponent - ngOnInit() -- Subscription Params: ' + params['code']);
    });

    this.activatedRouteQueryParamsSubscription = this.activatedRoute.queryParams.subscribe(params => {
      console.log('AppComponent - ngOnInit() -- Subscription Query Params: ' + params['code']);
    });

    this.activatedRoute.queryParamMap.subscribe(queryParams  => {
      console.log('AppComponent - ngOnInit() -- Subscription Query ParamMap: ' + queryParams.get('code'));
    });

    this.routerEventsSubscription = this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        console.log('AppComponent - ngOnInit() -- Subscription NavigationEnd: URL=', event.url);
      }
    });
  }

As you can see, I've set up a subscription for params, queryParams, queryParamMap and router.events.

The only one that fires between page navigations is the router.events, but there, I would have to manually parse the URL to get the query string.

Not sure if this has any effect on it, but I'm overriding the route reuse strategy so the page is reloaded even if it is on the same route:

export class AppRoutingModule {
  constructor(private router: Router) {
    this.router.routeReuseStrategy.shouldReuseRoute = function() {
        return false;
    };
  }
}

Output of root page on first visit:

AppComponent - constructor() -- Snapshot Params: undefined
AppComponent - constructor() -- Snapshot Query Params: undefined
AppComponent - ngOnInit() -- Snapshot Params: undefined
AppComponent - ngOnInit() -- Snapshot Query Params: undefined
AppComponent - ngOnInit() -- Snapshot Query ParamMap: null
AppComponent - ngOnInit() -- Subscription Params: undefined
AppComponent - ngOnInit() -- Subscription Query Params: undefined
AppComponent - ngOnInit() -- Subscription Query ParamMap: null
AppComponent - ngOnInit() -- Subscription NavigationEnd: URL= /?code=logged-out

SOLUTION

As both @Thomaz and @Nathan pointed out, my issue was that the App.Component was not inside the router-outlet.

Moreover, @Nathan also pointed out that:

You can access Router events and iterate over them wherever you want in the app though, which is why your router.events.subscribe(...) triggers.

I then enabled tracing on my routes:

RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload', enableTracing: true })

And saw that the ActivationEnd event included a snapshot which had the queryParams. In the end, I'm subscribing to router event and processing my querystring value if the event is ActivationEnd.

this.router.events.subscribe(event => {
      if(event instanceof ActivationEnd) {
        const code = event.snapshot.queryParams['code'];
        if (code) {
          // handle it...
        }
      }
}
like image 957
Cloud SME Avatar asked Jan 22 '19 20:01

Cloud SME


People also ask

How do I pass queryString?

To pass in parameter values, simply append them to the query string at the end of the base URL. In the above example, the view parameter script name is viewParameter1.

How do I get data from query params in Angular 6?

import ActivatedRoute from '@angular/router'. Inject ActivatedRoute class in constructor. Access queryParams property of ActivatedRoute class which returns an observable of the query parameters that are available in the current URL route.

What is queryString parameter?

What are query string parameters? Query string parameters are extensions of a website's base Uniform Resource Locator (URL) loaded by a web browser or client application. Originally query strings were used to record the content of an HTML form or web form on a given page.


1 Answers

ActivatedRoute can be subscribed to from components that are loaded via router-outlet. Since AppComponent is not loaded via any outlet, you cannot subscribe to ActivatedRoute params within it. The re-use strategy is not impacting this.

From the docs https://angular.io/api/router/ActivatedRoute we know the following:

[ActivatedRoute] Contains the information about a route associated with a component loaded in an outlet.

There is no outlet loading AppComponent, so your subscribes won't fire. You can access Router events and iterate over them wherever you want in the app though, which is why your router.events.subscribe(...) triggers.

like image 152
Nathan Beck Avatar answered Sep 28 '22 10:09

Nathan Beck