I have this route in my routing module:
{ path: 'signup', component: SignupComponent },
But this route shouldn't be accessed without fragments (#first-step
, #second-step
), so I've added some redirect logic into my app:
this.route.fragment.subscribe((fragment: string | null) => {
if (fragment && ['first-step', 'second-step'].includes(fragment)) {
// Fragments are correct, further logic with displaying step components
} else {
this.router.navigate(['signup'], {fragment: 'first-step', replaceUrl: true});
}
})
I use navigate
because fragments are client part of the url and it can be changed only on client, but there is a problem with browser history, with this approach it pushes poth pages - signup
and signup#first-step
. skipLocationChange
will not help here as it doesn't change url. I can simply define fragment in registration button on main page but what if user will open signup page directly from the bookmarks or address bar? I would like to have nice redirect without adding signup
page to the history, how can it be done? Is there anything I don't understand correctly?
CodePudding user response:
You could move the logic to a Guard
, so it gets process before the navigation completes.
@Injectable({ providedIn: 'root' })
export class SignupGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(route: ActivatedRouteSnapshot): boolean | UrlTree {
const {fragment} = route;
// has required fragment proceed with navigation
if (fragment && ['first-step', 'second-step'].includes(fragment)){
return true;
}
//no fragment present, return UrlTree to 'signup#first-step' for redirection
return this.router.createUrlTree(['signup'], { fragment: 'first-step' });
}
}
And then use the guard in the Route:
{
path: 'signup',
component: SignupComponent,
canActivate: [SignupGuard],
runGuardsAndResolvers: 'always',
},
I added the runGuardsAndResolvers
so the guard also gets processed while trying to navigate to signup
when on signup#first-step
or signup#second-step
. You can remove it if that's not possible within your app.
Cheers