web-dev-qa-db-ja.com

Angular BehaviorSubjectを使用したリロード時のデータ損失

データサービスを使用してユーザーデータをアプリに送信し、ヘッダーコンポーネントにユーザー名を表示しています。ログインコンポーネントを使用してアプリにサインインすると、ユーザー名は正しく表示されますが、ページをリロードすると、ユーザーデータが表示されなくなります。

ログイン時リロード前

enter image description hereenter image description here

リロード後

enter image description hereenter image description here

ユーザーデータは、BehaviorSubjectを使用するデータサービスから取得されます。

data.service.ts

export class DataService {

  private userSource = new BehaviorSubject({});
  currentUser = this.userSource.asObservable().pipe(distinctUntilChanged());

  constructor(private injector: Injector, private api: UtentiApiService) { }

  getUser() {
    return this.currentUser;
  }

  getUserFromToken() {
    const authService = this.injector.get(AuthService);
    const token = authService.getToken();
    const userIdToken = jwt_decode(token);
    // console.log(userIdToken);
    return this.api.getUtente(userIdToken.userId);
  }

  getPermissionsFromToken(): Observable<any> {
    const authService = this.injector.get(AuthService);
    const token = authService.getToken();
    const userIdToken = jwt_decode(token);

    return of(userIdToken.permArr);
  }
  changeUser(user: object) {
    this.userSource.next(user);
  }

}

ヘッダーコンポーネントで私はサービスを消費します:

header.component.ts

export class HeaderComponent implements OnInit {
  user: object;

  constructor(private router: Router, private authService: AuthService, private data: DataService) { }


  ngOnInit() {
    this.getUser();
  }

  getUser() {
    this.data.getUser().subscribe(utente => {
      this.user = utente;
      console.log(this.user);
    });
  }

  onLogout() {
    this.authService.logoutUser();
  }

  sendUser(user) {
    this.data.changeUser(user);
  }
}

ログインコンポーネントでユーザーデータをデータサービスに送信しますが、リロード時にログインコンポーネントが起動されないため、サービスにもヘッダーにもユーザーデータがありません。このバグを修正するにはどうすればよいですか?

ここに完全なコードを含むstackblitzがあります: https://stackblitz.com/github/ufollettu/SEANSA

ご協力ありがとう御座います

5
ufollettu

SessionStorage、localStorage、またはCookieを使用してデータを保存します。

更新を押したら、上記のストレージのいずれかにデータをコピーし、初期化時に変数にコピーして戻します。以下の例を確認してください。 sessionStorageをlocalStorageに置き換えて、localStorageにデータを保存します。

AppComponent内

    ngOnInit() {
    if (sessionStorage.getItem("user")) {
      this.data.changeUser(sessionStorage.getItem("user"));
    }
      }
@HostListener('window:beforeunload', ['$event'])
      unloadNotification($event: any) {
        sessionStorage.setItem("user", this.getUser());
      }
4
Krishna

あなたのコードから:

private userSource = new BehaviorSubject({});
  currentUser = this.userSource.asObservable().pipe(distinctUntilChanged());

  constructor(private injector: Injector, private api: UtentiApiService) { }

  getUser() {
    return this.currentUser;
  }

UserSourceはBehaviorSubjectであり、アプリケーションの起動時(リロード時も)には何も含まれていません。

あなたが呼び出すユーザーにログインするとき:

changeUser(user: object) {
    this.userSource.next(user);
  }

この呼び出しの後、BehavoirSubjectにはユーザーが含まれます。ただし、これはログインプロセス中にのみ行います。

ページをリロードするときは、localstorageからアクセストークンをフェッチし、現在のユーザーでBehavoirSubjectを次に呼び出す必要があります。

たとえば、dataServiceのコンストラクターでこれを行うことができます。

4
J. S.