quirky purple
quirky purple

Reputation: 2219

Angular 9 Redirect if query param not provided

I have a route that should only be accessible to a user when they click a link from an email and are redirected with a valid query parameter in the url. If the parameter is not provided, I want to redirect to a 404 page not found component, like follows.

this.route.queryParams.subscribe(params => {
      if (params.myParam) {
        //do something
      } else {
        // redirect to 404
      }
    })

The issue I have is that query params is initialized to an empty object in ngOnInit(). I have utilized rjxs to wait until the parameter is accessible like this

this.route.queryParamMap.pipe(
      filter(paramMap => paramMap.has('myParam')),
      map(paramMap => paramMap.get('myParam')),
      take(1)
    ).subscribe(myParam => doSomething(myParam));

But I'm not very well versed in rxjs operators, and now I'm stuck on how to actually redirect if paramMap has finished initializing and the parameter isn't found.

Upvotes: 1

Views: 2647

Answers (2)

bryan60
bryan60

Reputation: 29355

this is a problem in many apps, as the params and query params are implemented as behavior subjects, get around this by waiting for the NavigationEnd event, where the query params will definitely already be set...

   const navEnd$ = this.router.events.pipe(filter(e => e instanceof NavigationEnd));
   navEnd$.pipe(withLatestFrom(this.route.queryParams)).subscribe(
     ([navEnd, queryParams]) => {
       if (queryParams.myParam) {
         // do the thing
       } else {
         // navigate
       }
     }
   )

Upvotes: 3

Sreekanth Reddy Balne
Sreekanth Reddy Balne

Reputation: 3424

In order to route to a 404 if the queryParam is not set, do:

import { Router } from '@angular/router'

class ...

constructor(private router: Router, private route: ActivatedRoute){
this.route.queryParamMap.pipe(
  skip(1),
  map(paramMap => paramMap.get('myParam')),
  tap(param=>{if(param=={} || param==undefined)this.router.navigateByUrl("/404.html")})
).subscribe(myParam => doSomething(myParam));

}

You can start the subscription within the constructor, that way you will get the first value before it is modified in any other methods like ngOninit.

Upvotes: 0

Related Questions