Получение неопределенного объекта в angular в authGaurd - PullRequest
0 голосов
/ 19 декабря 2018

Когда я пишу 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 голосов
/ 19 декабря 2018

Я бы сделал это так, используя 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);
  }


}
0 голосов
/ 19 декабря 2018

Вы знаете, что Javascript асинхронный.Это означает, что он не будет ждать ни одного запроса ввода-вывода и продолжит выполнение следующей строки кодов.Фрагмент кода, которым вы поделились, getUsername() является асинхронным, поэтому JS не будет ждать его завершения и выполнит следующую строку.В то время username равно undefined.

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;
     }
 }
}
   
   
...