简体   繁体   中英

Angular 2 - CanActivate undefined value

I have a problem with the function CanActivate() which is the variable token does not receive the response of the function verifytoken always returns undefined, how can I solve this problem?

Code

private verifytoken()
  {
        if(this._functionservice.getCookie("Cookie") != '' && this._functionservice.getCookie("Cookie") != "undefined")
    {
        this._symfonyservice.validtoken().subscribe(
            data => {this.resut = data;
                      if(this.resut['is_valid']==true)
                      {
                      console.log('true');

                        return true;
                     }
                    else
                    {
                        this._functionservice.deleteCookie("Cookie");
                        console.log('false');
                        this.router.navigate(['login']);
                        return false;
                    }
            },
            error =>{
                        alert("Sessão Expirada");
                        this._functionservice.deleteCookie("Cookie");
                        console.log('false');
                        this.router.navigate(['login']);
                        return false;
                    }
            );

    }
    else{
        this.router.navigate(['login']);
        return false;
    }

  }
  canActivate() {
    let token = this.verifytoken();
    console.log(token);
    return token;
  }

I found 2 problems here:

private verifytoken()
  {
        if(this._functionservice.getCookie("Cookie") != '' && this._functionservice.getCookie("Cookie") != "undefined")
    {

     // 1 - You are returning nothing here, only inside the subscriptions. So,  you wont be able to get any data if you get inside this if statement
        this._symfonyservice.validtoken().subscribe(
            data => {this.resut = data;
                      if(this.resut['is_valid']==true)
                      {
                      console.log('true');

                        return true;
                     }
                    else
                    {
                        this._functionservice.deleteCookie("Cookie");
                        console.log('false');
                        this.router.navigate(['login']);
                        return false;
                    }
            },
            error =>{
                        alert("Sessão Expirada");
                        this._functionservice.deleteCookie("Cookie");
                        console.log('false');
                        this.router.navigate(['login']);
                        return false;
                    }
            );

    }
    else{
        // 2 - you are navigating to another place, so you wont be able to get any data from here
        this.router.navigate(['login']);
        return false;
    }

  }
  canActivate() {
    let token = this.verifytoken();
    console.log(token);
    return token;
  }

So, you have to return the subscriptions inside the if statement or you wont be able to get any data.

--- EDIT --- Answering the question:

Promisses return promisses, so, you can call subscribe after call the method.

In verifytoken() you have to return the promisse and then, in canActivate() you have to subscribe to this promisse like I did bellow or wait for the value synchronously:

private verifytoken(){
  if(this._functionservice.getCookie("Cookie") != '' && this._functionservice.getCookie("Cookie") != "undefined")
  {
    // here I returned the promisse
    return this._symfonyservice.validtoken().subscribe(
      data => {
        this.resut = data;

        if(this.resut['is_valid']==true){
            console.log('true');
            return true;
        }
        else
        {
            this._functionservice.deleteCookie("Cookie");
            console.log('false');
            this.router.navigate(['login']);
            return false;
        }
      },
      error =>{
          alert("Sessão Expirada");
          this._functionservice.deleteCookie("Cookie");
          console.log('false');
          this.router.navigate(['login']);
          return false;
      }
    );

  }
  else{
      this.router.navigate(['login']);
      return false;
  }

}

There is a trick here. You cant return the function canActivate() from inside the promisse function because it scope. So, you have 2 options:

1 - (async) is to call the promisse where you are calling canActivate and then whatch for changes from within there.

canActivate() {
  return this.verifytoken();
}

2 - (sync) is to put a while to detect when the promisse are triggered and the response is assigned to the token variable, so you can return it

canActivate() {
  var token = this.verifytoken();


  while(token == undefined){
    // wait until token has been set
  }

  return token;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM