0

I'm trying to restrict access to my route system using CanActivateChild, however when I try to prevent user's navigation to a set of child states, the RouteGuard doesn't work, only on CanActivate. This is my routing module:

export const routes = [
    { path: "", redirectTo: "/signin", pathMatch: "full" },
    { path: "signin", component: SigninComponent },
    {
        path: "user",
        component: UserComponente,
        canActivate: [AuthGuard],
        canActivateChild: [AuthGuard],
        children: [
            { path: "profile", component: ProfileComponent, },
            { path: "address", component: AddressComponent, },
        ]
    },
    { path: "test", component: TestComponent, canActivate: [AuthGuard] },
];

In this example, if I try to access the route test, I can see the AuthGuard being executed, the function canActivate is called.

But when I try to navigate to any of the children routes (profile or address), nothing happens. Both, canActivate and canActivateChild doesn't get called on the AuthGuard.

This is my guard file:

import { Injectable } from '@angular/core';
import { CanActivate, CanActivateChild } from '@angular/router';
import { getString } from 'application-settings';
import { AppConfig } from './../config';

@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
    constructor() { }

    canActivate() {
        console.log('canActivate executing.');

        if (!getString(AppConfig.authToken)) {
            alert('You need to be logged in.');
            return false;
        }
        return true;
    }

    canActivateChild() {
        console.log('canActivateChild executing.');
        return this.canActivate();
    }
}
celsomtrindade
  • 4,501
  • 18
  • 61
  • 116
  • If you look at the console, are you seeing any errors? Where is AppConfig defined? It is imported and then used here: AppConfig.authToken But it is not declared or injected in anywhere? Same for getString. – DeborahK Jun 07 '17 at 22:24
  • @DeborahK I just didn't put it in here. But everything is being imported and used just fine. Like I said, if I try to access the test route, I can navigate there and I do see a console.log message. Also, there is no errors. Nothing happens when I try to access address or profile routes. – celsomtrindade Jun 07 '17 at 22:25
  • Does it work if you add canActivate OR canActivateChild and not both on the same path? (They *should* work together like you have ... just wondering if using each one individually works.) – DeborahK Jun 07 '17 at 22:30
  • @DeborahK No. As soon as I define it in a path with children declaration, it stops working. – celsomtrindade Jun 07 '17 at 22:33
  • Can you put together a plunker that demonstrates the problem? Then we could try out the code to help us see what is wrong. – DeborahK Jun 08 '17 at 16:42
  • Also, I have an example of canActivate with children here: https://github.com/DeborahK/Angular-Routing ... though currently it is lazy loaded. It started out without lazy loading, however, and you could download the code and change it back to standard children if you want to give it a try. – DeborahK Jun 08 '17 at 16:43
  • 1
    @DeborahK I'm still investigating this. I tried to change just the plain text on the page and it didn't updated. After I recompiled the project manually (forcing a whole update) it started working. I'm working on a NativeScript/TypeScript project. I just don't know where the issue came from. But I think it's not related to the canActivate code itself, but one of those parts not updating the code properly. – celsomtrindade Jun 08 '17 at 17:10

1 Answers1

0

you need to Inject the Router in you constructor, also you need to import it.

import { Router } from '@angular/router'

constructor(
    private router: Router
  ) {}

Because you need to let the Router know of the changes. You can return boolean, observable or UrlTree, so the router can update its state.

Nosheep
  • 493
  • 1
  • 4
  • 10