Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

176
Visualizações
canActivate Dependant on Parent Route Resolve

I have routes setup like so:

export const APP_ROUTES: Routes = [
    {
        path: '',
        resolve: {
            user: CurrentUserResolver
        },
        children: [
            {
                path: ':sectionKey',
                canActivate: [SectionAccessGuard],
                children: [
                    {
                        path: 'dashboard',
                        component: DashboardComponent
                    }
                ]
            }
        ]
    }
]

Where the parent route will retrieve the user via a HTTP call, and I'd like my sub-route :sectionKey to only be activated if the current user has access to it. The issue is, it appears my canActivate SectionAccessGuard is called prior to the snapshot being fully populated:

@Injectable()
export default class SectionAccessGuard implements CanActivate {
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        console.log(route.data);
        console.log(route);
        return true;
    }
}

In the console, the first entry will have nothing; however, the 2nd entry will eventually have the user field populated.

I know the canActivate method can return an Observable<boolean> as well, but I don't see any hooks on how to wait until the resolve completes.

What am I missing here? I feel like this should be pretty straight forward. I'm currently using angular v4.0.0-rc.2

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

It's been about 8 months since I posted this so I'll give an update on where we ended up:

Storing data in the router through resolves started to become very awkward depending on where the component was (this.route.parent.parent.parent.data.user), so we're no longer using resolves, and instead using NgRx to store that kind of information.

Our guards then are in charge of triggering the fetching of the data, as well as waiting until it's complete. Something like this:

@Injectable()
export class AuthenticationGuard implements CanActivate {
    constructor(private router: Router, private store: Store<ApplicationState>) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        this.store.dispatch(new AuthenticateAction());

        return this.store
            .select('auth')
            .filter((s) => !!s && !s.authenticating)
            .map((s) => s.authenticated)
            .take(1);
    }
}

Where there are a couple flags in the state (authenticating and authenticated) that tell the guard where we're at in the process.

about 4 years ago · Santiago Trujillo Relatório

0

I'm not sure if it's possible to enforce the guard to work after the resolver completes, but I'd try to move the code from the resolver into canActivate().

When the observable that gets the current user info returns the data, apply your logic to check if the user is allowed to navigate to the route.

about 4 years ago · Santiago Trujillo Relatório

0

I'm struggling with this too and I'd like to see more documentation surrounding this from the Angular team. It seems canActivate does not wait to start running until after the parent is finished, but resolve does.

You can change your can activate code into another resolve, because a child resolve does wait for a parent resolve. If it is changed to resolve you will have access to the user through route.parent.data.user and you can then make a call to router.navigate to leave the section if the user isn't authorized.

Another approach is to set up a service that can be injected into both the resolve guard and the canActivate guard. You'd have to set up an observable from the resolve guard and subscribe to it in the canActivate guard.

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda