在authGaurd中以角度获取未定义的对象

时间:2018-12-19 10:36:51

标签: angular angular-ui-router mean-stack

当我写console.log(data)时我得到username,但是当我尝试写console.log(username)时却给了我undefined并且每次都返回false。我不知道为什么。

import { Injectable } from '@angular/core';
import { CompaniesService } from '../companyService/companies.service';
import {  CanActivate , Router} from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthGaurdService implements CanActivate {
  datas:boolean= false;
  username;

 constructor(private companyService: CompaniesService,
    public router: Router) {
       this.companyService.getUsername().subscribe(
       data => this.username= data.toString(),
       error => console.log(error)
      );
    console.log(this.username);
   }

 canActivate() {
  if(this.username!=null){
    return true;
  }
  else {
    return false;
  }
 }
}

2 个答案:

答案 0 :(得分:2)

您知道Javascript是异步的。这意味着它将不等待任何IO请求并继续执行下一行代码。 您共享的代码段getUsername()是异步的,因此JS不会等待它完成而将执行下一行。当时usernameundefined

constructor(private companyService: CompaniesService,
    public router: Router) {
       this.companyService.getUsername().subscribe( // <- Asynchrounous call 
       data => this.username= data.toString(),
       error => console.log(error)
      );
    console.log(this.username); // -> executed before service gets the data from server
   }
   
   // modify your code as below  :
   
    constructor(private companyService: CompaniesService,
    public router: Router) {
       this.companyService.getUsername().subscribe( // <- Asynchrounous call 
       data =>{
          this.username= data.toString();
          console.log(this.username); // will print when service gets the data from server
       }, 
       error => console.log(error)
      );
   
   }
   
   // complete work around :
  // you  file  : 
  
  import { Injectable } from '@angular/core';
import { CompaniesService } from '../companyService/companies.service';
import {  CanActivate , Router} from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthGaurdService implements CanActivate {
  datas:boolean= false;
  username;

    constructor(private companyService: CompaniesService,
    public router: Router) {
       this.companyService.getUsername().subscribe( // <- Asynchrounous call 
       data =>{
          this.username= data.toString();
          window.localStorage.setItem('username',this.username);
          console.log(this.username); // will print when service gets the data from server
       }, 
       error => console.log(error)
      );
   
   }
 
 
 canActivate() {
    let username = window.localStorage.getItem('username');
   if(username)
     {
       return true;
     } 
     else {
        return false;
     }
 }
}
   
   

答案 1 :(得分:0)

我会使用 BehaviorSubject 这样:

export class AuthGuardService implements CanActivate {

  constructor(
    private auth: AuthenticationService,
  ) { }

  canActivate(): boolean {
    return this.auth.isAuthenticated();
  }
}
export class AuthenticationService {

  userName = '';

  authenticationState = new BehaviorSubject(false);

  isAuthenticated() {
      return this.authenticationState.value;
  }

  async checkUserName() { // use this in your app constructor or ngOnInit
      this.username = await this.companyService.getUsername();
      this.authenticationState.next(this.userName !== null);
  }


}