Angular 8 - Как сохранить данные о поведении при перезагрузке страницы - PullRequest
0 голосов
/ 04 августа 2020

Я пытаюсь сделать текущего пользователя наблюдаемым в службе аутентификации, поэтому я хочу отображать текущего пользователя, даже если страница перезагружается

Все работает нормально, но я не могу получить текущий пользователь после перезагрузки страницы

На AuthService:

  private currentUserSubject: BehaviorSubject<any>;
  public currentUser: Observable<any>;

  constructor(private httpClient: HttpClient,public router: Router) {
    this.currentUserSubject = new BehaviorSubject(JSON.parse(localStorage.getItem('currentUser')));
    this.currentUser = this.currentUserSubject.asObservable();
   }



login(user: User) {
  return this.httpClient.post<any>(`${this.API_URL}/users/login`, user)
    .subscribe((data: any) => {
      localStorage.setItem('access_token', data.token)
      this.getUserProfile(data.user._id).subscribe((res) => {

  --->>>> this.currentUserSubject.next(res.nom);

        this.router.navigate(['/profile/' + res._id]);
      })
    })
}

На PageComponent:

 currentuser;

  ngOnInit() {
      
        this.currentuser = this.authService.getCurrentUser()
        console.log("my user s heeere " + this.currentuser)
        
  }

Результат

my user heeere JOETEST

После перезагрузки страницы

my user heeere null

Ответы [ 4 ]

1 голос
/ 04 августа 2020

Вы не можете держать данные в сервисе после refre sh. Весь жизненный цикл страницы компонентов и службы запускается заново по refre sh. Вместо этого обращайтесь к данным из localStorage / sessionStorage. Таким образом, ваш ngOnInit будет похож на

const loggedInUser= (JSON.parse(localStorage.getItem('currentUser')); if(!loggedInUser) {this.currentuser = this.authService.getCurrentUser()}

0 голосов
/ 04 августа 2020

Для обработки сеанса пользователя Создайте специальную функцию аутентификации

Он следует принципу разделения ответственности и единой ответственности и делает ваш код очень ремонтопригодный. Я публикую полное решение для дальнейшего использования.

auth.service.ts

import { Injectable, PLATFORM_ID, Inject } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { AuthApiService } from '../api/auth.api';
import { tap, take, first } from 'rxjs/operators';
import { isPlatformBrowser } from '@angular/common';

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

    private readonly CAH_TOKEN = 'CahToken';
    private readonly CAH_USERNAME = 'username';

    private logger: BehaviorSubject<boolean> = new BehaviorSubject(false);

    constructor(private api: AuthApiService, @Inject(PLATFORM_ID) private platformId) {
        this.logger.next(this.isUserLoggedIn());
    }

    /** Subscribe to know automatically whenever login status changes */
    public isLoggedIn = () => this.logger.asObservable();
    public logout = () => this.api.logout().pipe(tap(_ => this.deleteUser()));
    public login = (username, password) => this.api.login(username, password).pipe(tap(_ => { if (_.success) { this.saveUser(_); } }));

    public getToken = () => localStorage.getItem(this.CAH_TOKEN);
    public getUserName = () => localStorage.getItem(this.CAH_USERNAME);

    private saveUser(res): void {
        localStorage.setItem(this.CAH_TOKEN, res.data.token);
        localStorage.setItem(this.CAH_USERNAME, res.data.username);
        this.logger.next(true);
    }

    private deleteUser(): void {
        localStorage.removeItem(this.CAH_TOKEN);
        localStorage.removeItem(this.CAH_USERNAME);
        this.logger.next(false);
    }

    private isUserLoggedIn(): boolean {
        const user = isPlatformBrowser(this.platformId) && localStorage.getItem(this.CAH_TOKEN) ? true : false;
        return user;
    }
}

auth.api.ts

// API ДЛЯ ВХОДА / ВЫХОДА

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../../environments/environment';
import { Observable } from 'rxjs';

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

    constructor(private http: HttpClient) { }

    login(username: string, password: string): Observable<any> {

        const url: string = environment.cahServerUrl + 'api/users/auth/login';
        const body = { username, password };
        return this.http.post(url, body);
    }

    logout(): Observable<any> {

        const url: string = environment.cahServerUrl + 'api/users/auth/logout';
        const body = {};
        return this.http.post(url, body);
    }

}

export interface LoginRes {
    success: boolean;
    message: string;
    data: any;
}

В someComponent.ts

// АВТОМАТИЧЕСКИ РАССКАЗЫВАЕТСЯ ПРИ ЛОГИНЕ ИЛИ ВЫХОДЕ ПОЛЬЗОВАТЕЛЯ

 this.auth.isLoggedIn().subscribe(_ => {
      this.isLoggedIn = _;
      if (_) { this.userName = this.auth.getUser().username; }
    });

В login.component.ts

// ЧТОБЫ ВОЙТИ ПОЛЬЗОВАТЕЛЯ

this.auth.login(username, password).subscribe(this.handleLogin, this.handleLoginError, () => { this.isBtnClicked = false; });


  handleLogin = (res: LoginRes) => {
    if (res.success) {
      this.router.navigate(['/']);
    }
    else {
      this.message = res.message;
    }
  }

  handleLoginError = err => {
    console.log(err);
  }
0 голосов
/ 04 августа 2020

Для сохранения данных (в данном случае пользователя) вам необходимо сохранить данные в LocalStorage.

Во время входа в систему: -

login(user: User) {
  ...
  .subscribe((data: any) => {
      localStorage.setItem('access_token', data.token)
      localStorage.setItem('currentUser', data.user)
      
  --->>>> this.currentUserSubject.next(data.user);
...
}

В конструкторе: -

constructor(private httpClient: HttpClient,public router: Router) {
    this.currentUserSubject = new BehaviorSubject(localStorage.getItem('currentUser') || '');
    this.currentUser = this.currentUserSubject.asObservable();
   }
0 голосов
/ 04 августа 2020

Самый простой ответ - сохранить значение в localstorage. Немного сложнее, но в долгосрочной перспективе это окупается, это библиотеки управления состоянием в angular. Мне нравится использовать для этой цели Akita.

Akita имеет возможность сохранять текущее состояние в локальном хранилище без какого-либо взаимодействия, даже после перезагрузки страницы, он автоматически считывает данные оттуда.

Документы и исходный код доступен на github https://datorama.github.io/akita/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...