angularangular-routerquery-stringangular-activatedrouteangular-router-params

Route query parameters is empty on first render in Angular


I have a scenario in which I decide the actions based on the query parameters of the angular url.

For example, if the url is localhost:4200/token=abc I need to do some tasks and if the url is localhost:4200 then I need to do something else. I have added this logic in the ngOnInit() of app component. The problem is, the query parameters are empty while rendering the component for the first time, and it takes a while before the params value is fed.

Code:

    constructor(private route: ActivatedRoute,private router:Router){}
    ngOnInit(): void {

    this.route.queryParams.subscribe((params: any)=>{
    console.log("params 1:",params);
    if(Object.keys(params).length){ //If there are query parameters 
          console.log("If exectued",params);
         //do Something 
    }
    else{
        console.log("Else exectued",params);
        //do Something else
     }
    })
  }

The problem is params are empty initially and it goes to else condition. It again goes to if afterwards. The output is something like

params 1: {}
Else executed > {} 
If executed > {token:abc}

How to check if the route has been initialized properly with parameters and then proceed?

PS: I found a similar thing in Next.js but how to do this in Angular?


Solution

  • I resolved this issue and was able to have two different solutions for it. Posting the solution for people looking for it.

    The query parameters are initially empty or does not load the values first because the components loads before the actual routings are applied.

    Solution 1

    Wait for the navigation to end using event property NavigationEnd

    constructor(private activatedRoute: ActivatedRoute, private router:Router) { }
    ngOnInit(): void {  
        this.router.events.subscribe(
          (event: RouterEvent) => {
            if (event instanceof NavigationEnd) {
            this.activatedRoute.params.subscribe((params: any)=>{
            if (Object.keys(params).length) { //Query params 
              doSomething();
            }
            else
              doSomethingElse();
           })
          }
          })
    }
    

    Solution 2

    Adding a delay, say .10s to ActivatedRoute to capture the route query parameters. Although adding delays is not considered good as per coding norms, but this can be beneficial in some scenarios where a certain delay is already required to trigger a popup or some logic on page load.

     ngOnInit(): void {
        setTimeout(() => {
          this.activatedRoute.params.subscribe((params: any)=>{
            if (Object.keys(params).length) { //Query params 
              doSomething();
            }
            else
              doSomethingElse();
          })
        }, 10);//A dealy of 10ms is provided here
    }
    

    In both of the solutions, if block or doSomething() function is triggered first.

    PS: Refer to David Rosey's question and the blog by Ben Nadel to get into more details.

    Thanks.