0

I want to have multiple components associated to the root path in order to display one landing page view for anonymous users and an inbox for the authenticated users, without having to use manual navigation and path changes crutches.

I've tried to enable my scenario with a routing block like this:

{ path: '', component: LandingComponent, canActivate: [ ForbidAuthGuard ] },
{ path: '', component: LocationsComponent, canActivate: [ RequireAuthGuard ] }

Angular is indeed calling ForbidAuthGuard, which is failing on an authenticated user and therefore cancelling the navigation event altogether, ignoring the RequireAuthGuard route.

As implied by their conflicting names both guards are exclusive to each other so only one of the routes will ever be active, yet Angular seems to be ignoring the second route.

Is this mechanic viable at all? or Is there any other technique to achieve the end goal of the first paragraph?.

For completeness' sake I am using @angular/router and @angular/core with version 5.2.8.

7
  • 1
    there is a proper way to do achieve your goal, but it isn't "having multiple components associated with the root path". Commented Mar 14, 2018 at 21:53
  • @RandyCasburn I'd love to know more, can you elaborate please? Commented Mar 14, 2018 at 21:54
  • Yes, since you are open minded :-). The proper way is based upon abstracting authentication away so it just works and doesn't affect your day-to-day development. The mechanism is the HttpClient and HTTPIntercepter provided by the API. You can find the docs here: angular.io/guide/http#intercepting-requests-and-responses with many many examples found via Google. Commented Mar 14, 2018 at 22:04
  • @RandyCasburn I do have an http interceptor to globaly set the auth header and handle implicit oauth token refresh, but i fail to see how it can participate in the routing process to determine which component is shown on the screen. Sorry. Commented Mar 14, 2018 at 22:18
  • Capture the 401/403 HTTP status codes in an intercepter and redirect to, perhaps a LandingComponent if not authorized, otherwise (if state has not been set/if first visit) redirect to maybe a LocationsComponent Commented Mar 14, 2018 at 22:31

2 Answers 2

1

You can do something like this:

{ path: '', component: MyService.DoACheck() ? LandingComponent, LocationsComponent },

But that then would not use your guards.

The more common solution, I'm assuming, is the one you don't want:

Define one route with a guard.

In that route guard, determine if the user can access the route, if not, navigate to the other route.

Like this:

export  class AuthGuard implements CanActivate {

    constructor(private authService: AuthService,
                private router: Router) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return this.checkLoggedIn(state.url);
    }

    checkLoggedIn(url: string): boolean {
        if (this.authService.isLoggedIn()) {
            return true;
        }

        // Retain the attempted URL for redirection
        this.authService.redirectUrl = url;
        this.router.navigate(['/login']);
        return false;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I am using an approach similar to this while someone helps me realize the vision i truly want for my routing. Thanks :)
Have you considered posting an issue/feature request to the Angular github repo?
Pretty sure this issue I'm having is just due to my limited knowledge and not due to an issue with Angular itself.
0

Yes, you can have multiple Components associated to a single route:

app.component.html

<div class="block">
  <div class="columns">
    <div class="column is-two-thirds">
      <router-outlet></router-outlet>
    </div>

    <div class="column">
      <router-outlet name="aux"></router-outlet>
    </div>
  </div>
</div>

Routing Config

{
  path: 'my-single-url',
  children: [
    { path: '', component: ComponentOne },
    { path: '', component: ComponentTwo, outlet: 'aux' }
  ]
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.