输入字符串 | null 不能分配给字符串类型?如何在 Angular 应用中解决这个问题?

时间:2020-12-21 14:59:45

标签: angular typescript

我正在使用具有 node express 后端的 angular 应用程序。我正在使用授权服务来保持我的逻辑。仅出于某种原因使用我在以前的应用程序中使用的相同登录名,现在我收到此字符串类型的错误 | null 不能分配给字符串类型。我需要做什么来解决这个问题。我尝试在注销方法中将字符串声明为空,并将 this.userId = authInformation.userId 中的第 106 行设置为 this.userId = authInformation.userId 作为 autoAuthUser 方法中的字符串,但是在刷新浏览器之前使用此代码它将读取本地存储并且用户将保持登录状态。现在当我执行代码时,刷新页面时它不会保持用户登录,并在我使用如下原始代码时抛出这些错误。

import { AuthData } from '../models/auth-data.model';
import { environment } from '../../../../environments/environment';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Subject } from 'rxjs';

const BACKEND = environment.authUrl;

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private token: string;
  private isAuthenticated = false;
  private tokenTimer: any;
  private userId: string;

  private authStatusListener = new Subject<boolean>();


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

  //Get the authentication token
  getToken() {
    return this.token;
  }
  //Create a method to return the authentication status of a user after logging in
  getIsAuth() {
    return this.isAuthenticated;
  }
  //return the authentication status true or false as an observable
  getAuthStatusListener() {
    return this.authStatusListener.asObservable();
  }

getUserId() {
  return this.userId;
}

registerUser(user_email: string, user_password: string) {
  const authData: AuthData = {
    user_email: user_email,
    user_password: user_password
  }
  this.http.post(BACKEND + '/signup', authData)
  .subscribe(() => {
    this.router.navigate(['/'])
  }, error => {
    this.authStatusListener.next(false);
  })
}

loginUser(user_email: string, user_password: string) {
  const authData: AuthData = {
    user_email: user_email,
    user_password: user_password
  }
  this.http.post<{ token: string, expiresIn: number, userId: string }>(
    BACKEND + '/login',
    authData
  ).subscribe(response => {
    console.log(response);
    const token = response.token;
    this.token = token;
    if(token) {
      const expiresInDuration = response.expiresIn;
      this.setAuthTimer(expiresInDuration);
      this.isAuthenticated = true;
      this.userId = response.userId;
      this.authStatusListener.next(true);
      const now = new Date();
      const expirationDate = new Date(now.getTime() + expiresInDuration * 1000);
      console.log(expirationDate);
      this.saveAuthData(token, expirationDate, this.userId);
      this.router.navigate(['/']);
    }
  }, error => {
    this.authStatusListener.next(false);
  });
}
autoAuthUser() {
  const authInformation = this.getAuthData();
  if(!authInformation) {
    return;
  }
  const now = new Date();
  const expiresIn = authInformation.expirationDate.getTime() - now.getTime();
  //console.log(authInformation, expiresIn);
  if(expiresIn > 0) {
    this.token = authInformation.token;
    this.isAuthenticated = true;
    //property has to be declared as a string with the new typescript.
    this.userId = authInformation.userId;
    this.setAuthTimer(expiresIn / 1000);
    this.authStatusListener.next(true);
  }
}

logoutUser() {
  //property can no longer be set to null with the new typescript. this.token and this.userId
  this.token = null;
  this.isAuthenticated = false;
  this.authStatusListener.next(false);
  clearTimeout(this.tokenTimer);
  this.userId = null;
  this.clearAuthData();
  this.router.navigate(['/']);
}

private setAuthTimer(duration: number) {
  console.log("Setting timer: " + duration);
  this.tokenTimer = setTimeout(() => {
            this.logoutUser();
          }, duration * 1000)
  }

  private saveAuthData(token: string, expirationDate: Date, userId: string) {
  localStorage.setItem('token', token);
  localStorage.setItem('expiration', expirationDate.toISOString());
  localStorage.setItem('userId', userId);
  }

  private clearAuthData() {
    localStorage.removeItem('token');
    localStorage.removeItem('expiration');
    localStorage.removeItem('userId');
  }

  private getAuthData() {
    const token = localStorage.getItem('token');
    const expirationDate = localStorage.getItem('expiration');
    const userId = localStorage.getItem('userId');
    if(!token || !expirationDate) {
      return;
    }
    return {
      token: token,
      expirationDate: new Date(expirationDate),
      userId: userId
    }
  }
}

以下是我在 VSC 代码窗口中收到的错误。 enter image description here

enter image description here

谁能指出我正确的方向来修复错误并使服务再次正常工作?

0 个答案:

没有答案