首页 > 解决方案 > 角度变量保持未定义

问题描述

我写了以下代码:

身份验证.service.ts

export class AuthenticationService {
  private readonly ACCESS_TOKEN = 'ACCESS_TOKEN';
  private readonly REFRESH_TOKEN = 'REFRESH_TOKEN';
  private loggedUser: string;
  public userId : number; 
  public user : User; 
  private API_URL= environment.API_URL;


  constructor(private http: HttpClient, private router:Router, private userService : UserService) {}

  login(username: string, password:string): Observable<boolean> {
    return this.http.post<any>(this.API_URL + 'token/', { username: username, password: password })
      .pipe(
        tap(tokens => this.doLoginUser(username, tokens)),
        mapTo(true),
        catchError(error => {
          return of(false);
        }));
  }

  logout() {
    this.doLogoutUser();
  }

  decodeJwt(token){
    let decoded = jwt_decode(token);
    this.userId = decoded.user_id; 
  }

  isLoggedIn() {
    return !!this.getAccessToken();
  }

  isStaff() {
    return this.user.is_staff; 
  }

  refreshToken() {
    return this.http.post<any>(this.API_URL + "token/refresh/", {
      'refresh': this.getRefreshToken()
    }).pipe(
      tap((tokens: Tokens) => {
      this.storeJwtToken(tokens.access);
      }),
      mapTo(true), 
      catchError(error => {
        this.doLogoutUser(); 
        this.router.navigate(["/login"])
        return of(false); 
      }
      )
      );
  }

  getAccessToken() {
    return localStorage.getItem(this.ACCESS_TOKEN);
  }

  getUserData(){
    this.userService.getUser(this.userId).subscribe(data => {
      this.user = data.results[0]
      console.log(this.user)
    })
  }

  private doLoginUser(username: string, tokens: Tokens) {
    this.loggedUser = username;
    this.storeTokens(tokens);
    this.decodeJwt(tokens.access); 
    this.getUserData(); 
  }

  private doLogoutUser() {
    this.loggedUser = null;
    this.removeTokens();
  }

  private getRefreshToken() {
    return localStorage.getItem(this.REFRESH_TOKEN);
  }

  private storeJwtToken(accessToken: string) {
    localStorage.setItem(this.ACCESS_TOKEN, accessToken);
  }

  private storeTokens(tokens: Tokens) {
    localStorage.setItem(this.ACCESS_TOKEN, tokens.access);
    localStorage.setItem(this.REFRESH_TOKEN, tokens.refresh);
  }

  private removeTokens() {
    localStorage.removeItem(this.ACCESS_TOKEN);
    localStorage.removeItem(this.REFRESH_TOKEN);
  }
} 

navbar.component.ts

export class NavbarComponent implements OnInit {
  constructor(public authService : AuthenticationService, private router : Router) { 
  }

  ngOnInit(): void {
    console.log(this.authService.isStaff())
  }

  logOut(){
    this.authService.logout() 
    this.router.navigate(['/login']);
  }
}

用户服务.ts

export class UserService {
  private API_URL= environment.API_URL;

  constructor(private http : HttpClient) { }

  getUsers(page:number=1){
    return this.http.get<any>(this.API_URL + 'users/', {
      params: new HttpParams().set("page", page.toString())
    });
  }

  register(data:User) {
    return this.http.post<any>(this.API_URL + 'users/', data)
  }

  getUser(id : number){
    return this.http.get<any>(this.API_URL + 'users/' + id.toString())
  }
}

登录时getUser调用 -function ,但是当我检查控制台时,导航栏构造函数给出了this.user来自isStaff-function的错误authentication.service.ts未定义。用户端点正常工作,因为当我控制台记录data.results[0]订阅函数中的值时,它会显示用户的数据。

我该如何解决这个问题?

标签: angulartypescript

解决方案


那是因为变量是undefined

export class AuthenticationService {
  private readonly ACCESS_TOKEN = 'ACCESS_TOKEN';
  private readonly REFRESH_TOKEN = 'REFRESH_TOKEN';
  private loggedUser: string;
  public userId : number;
  public user : User;   =======> UNDEFINED
  private API_URL= environment.API_URL;

this.user 将仅在login服务getUserData完成后定义。不是在那之前。但我认为该Navbar组件甚至在服务调用完成之前就已初始化。

在上面的代码中,我没有看到对该AuthenticationService.login函数的任何调用。所以我看到了2个选项,

选项 1 -> 在用户登录之前不显示navbar组件。

选项 2 -> 从用户登录后引发事件。在访问 this.user 之前AuthenticationService在组件中订阅该事件。navbar


推荐阅读