3
votes

I'm trying to implement a guard that checks if the user has saved certain configuration parameters before accesing a view. Both the configuration forms and the view I want to guard are separated.

To do this, I've been trying to get the configuration parameters from a service (back end API), so I'm able to check if the required fills are not null, so I can return true or false in the canActivate method, and also navigate with Router.

I've tried getting the response from both the Constructor of the Guard Class, and from the canActivate method, only to find the service isn't even called. I've also tried implementing the class with OnInit, but no luck.

How can I make the canActivate method wait for the API response before returning values ture or false?

Thank you in advance!

Quick Edit. I've tried several things, including these:

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';

@Injectable()
export class ConfigurationGuard implements CanActivate{
  constructor(private service: Service) {}
  canActivate(){
    this.service.getConfigParameters().subscribe(parameters => {
      //if parameters are correct return true
      //else return false
    });
  }
}

Also tried:

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';

@Injectable()
export class ConfigurationGuard implements CanActivate{
  paramsCheck: boolean
  constructor(private service: Service) {
    this.service.getConfigParameters().subscribe(parameters => {
      //if parameters are correct paramsCheck=true
      //else paramsCheck=false
    });
  }
  canActivate(){
    if(paramsCheck){return true}
    return false
  }
}

and also tried using ngOnInit

import { Injectable, OnInit } from '@angular/core';
import { CanActivate } from '@angular/router';

@Injectable()
export class ConfigurationGuard implements CanActivate,OnInit {
  paramsCheck: boolean
  constructor(private service: Service) { }
  ngOnInit(){
    this.service.getConfigParameters().subscribe(parameters => {
      //if parameters are correct paramsCheck=true
      //else paramsCheck=false
    });
  }
  canActivate(){
    if(paramsCheck){return true}
    return false
  }
}

None of this options worked. I've also tried a service call method that returned a boolean that lets me know if the parameters from the configuration it gets from the service are correct, but no dice. I'm guessing verification will have to be made on server side?

2
Show us what you've been tryingYounesM

2 Answers

0
votes

If your service to get configuration parameters returns an observable do

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';

@Injectable()
export class CanActivateViaAuthGuard implements CanActivate {

  constructor(private service : Service) {}

  canActivate() {
    this.service.getConfigurationParameters().subscribe(
        parameters => {
            // if parameters are correct return true
            // else return false
        });
  }
}
0
votes

You can make use of Router resolve and then bring data from service and the routing wont happen untill all the data has been fetched from the service. Please check this link for a demo use of Router resolve.

Eg - https://github.com/rahulrsingh09/footballdetails/blob/master/src/app/team/team.resolve.ts

Please find a link to an answer i had given to a similar issue

Get the value returned by canActivate Method in Angular2 Route in a component?

This is my repo in which i make use of Router resolve