0

I need to guard the routerLinks based on some boolean configurations coming from a server. Currently i have written canActivate route guard. ActivateRoutes file

async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> {
        const visibility = route.data.name;
        return await this.service.activateRouterLinks(visibility);
}

This my app.module.ts file

{
        path: 'home',
        loadChildren: 'src/app/home/home.module#HomeModule',
        data: {
            title: 'Home', name: Names.HOME
        },
        canActivate: [ActivateRoutes]
    },

But actually what i want is i want to pass a boolean value to data like this instead of name.

 data: {
                    title: 'Home', state: homePageActive
                },

that coming from my service class (the route guard). Currently I am using a map and every time page loads it will search all the map to find the name. Therefore I want to set for a boolean value at once.

This is my service class code.

 linkNames = new Map<string, []>();
 homePageActive = false;
 getConfigurations() {
        this.getUIConfigurations().subscribe(
            configs => {
                for (const value of configs.names) {
                    this.linkNames.set(value.name, value.secondary_tabs);
                }
             mapNames();
            });
    }

mapNames() {
        if (this.linkNames.has(Names.HOME)) {
           homePageActive = true;
        }
}

asyn cactivateRouterLinks(visibility) {
        await this.waitSecond();
        if (this.linkNames.has(visibility)) {
            return true;
        } else {
            this.router.navigateByUrl('/page_not_found');
            return false;
        }
    }

waitSecond() {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('return aftersecond!');
            }, 160);
        });
    }
Yair Cohen
  • 2,032
  • 7
  • 13
Hans
  • 308
  • 7
  • 20

1 Answers1

0

You are trying to pass data from RouteGuard to a component, but RouteGuards are only used to guard whether the user has access to a component.

Instead, use a Resolver.


What's a resolver?

A resolver allows you to perform certain actions before a component loads as well as pass data to that component. It's often used to pre-fetch data so it's ready as soon as the component loads.

It also allows you to handle errors before routing to the component, there's no point rendering a component that errors, therefore it can also be used to improve performance.


Example:

Here's a simple setup of how it works:

First, create a Resolver service (very similar to a guard)

@Injectable()
export class YourResolver implements Resolve<ReturnedData> {

    constructor(private myService: MyService) {}

    resolve(route: ActivatedRouteSnapshot): Observable<ReturnedData> {
        return this.myService.getData();
    }
}

Then in your Router:

  {
            path: '', 
            component: YourComponent,
            resolve: {
                myData: YourResolver
            }, 
 },

You can then access it from your component like this:

ngOnInit() {
  this.route.data
    .subscribe((data) => {
      console.log(data.myData)
    });
}
Yair Cohen
  • 2,032
  • 7
  • 13