簡體   English   中英

如何在 Angular 服務中直接使用 .subscribe ?

[英]How to use .subscribe directly in Angular service?

解決了

我正在 Angular 中實現用戶的狀態:isLogged true/false。

因此,無論我在哪個組件,我都會驗證用戶是否已登錄以顯示或隱藏內容。 為此,我不想只控制 accessToken 是否在 localstorage 中,但我會檢查它是否使用 authService 向服務器(使用 Http 請求)詢問。 因此,我希望 authService 中的 isLogged() 僅返回 true/false 或設置布爾值 true/false。 通常我會在組件的 .subscribe 中處理 'res' 和 'err',但我不會在每個組件中重復它。 問題是我不知道如何直接在服務中使用 .subscribe 。

在我使用這個解決方案的那一刻。 它有效,但我根本不喜歡它!!

isLogged() {
  return this.http
    .get<any>(this.isLoggedUrl)
    .pipe(catchError(this.errorHandler));
}

// I call this method in each component that needs to know if user is logged
isLoggedResHandle() {
  this.isLogged().subscribe(
    (res) => {
      if (res.status == 200) {
        this.loggedIn = true;
      }
    },
    (err) => {
      if (err.error.message == 'TokenExpiredError') {
        this.loggedIn = false;
        //DO.. try refresh token. if refreshed: this.loggedIn = true
      } else {
        // for any other errors:
        this.loggedIn = false;
      }
    }
  );
}

解決方案

auth.service.ts

isLogged() {
    const accessToken = this.getAccessToken;
    if (typeof accessToken === 'undefined' || accessToken === null) {
      console.log('pieroooooooooo');
      this.loggedIn = false;
      return;
    }

    return this.http
      .get<any>(this.isLoggedUrl)
      .pipe(catchError(this.errorHandler))
      .subscribe(
        (res) => {
          if (res.status == 200) {
            this.loggedIn = true;
          }
        },
        (err) => {
          if (err.error.message == 'TokenExpiredError') {
            const refreshToken = this.getRefreshToken;
            if (typeof refreshToken !== 'undefined' || refreshToken !== null) {
              this.loggedIn = false;
            }

            this.loggedIn = false;
            // TODO: try to refresh it
          } else {
            this.loggedIn = false;
          }
        }
      );
  }

  getIsLogged() {
    return this.loggedIn;
  }

header.component.ts 或我想要的任何組件,例如:

<button class="btn btn-light my-2 my-sm-0" id="cartBtn" *ngIf="authService.getIsLogged()" [routerLink]="'/profile'"
      type="submit">
      <i class="fas fa-shopping-cart"></i>
      Mio Profilo
</button>

app.component.ts // 在刷新后也保持“用戶狀態”更新:

export class AppComponent implements OnInit {
  constructor(private authService: AuthService) {}

  ngOnInit(): void {
    this.authService.isLogged();
  }
}

解決方案可以是一個實現isLoggedResHandle邏輯的ParentComponentClass ,並且每個需要它的組件都可以擴展該類。

class ParentWithIsLoggedLogicCompoent {
  loggedIn = false
  
  constructor(private isLogged: IsLoggedService) {}

  isLoggedResHandle() {
    this.isLogged().subscribe(
      isLogged => this.loggedIn = isLogged,
      error => this.loggedIn = false
    )
  }
}

class YourOtherComponent extends ParentWithIsLoggedLogicCompoent implements OnInit {
  ngOnInit() {
    this.isLoggedResHandle();
  }
}

您可以使用retryWhen運算符將重試邏輯提取到服務中。 我不確定語法是否好,但它會是這樣的:

isLogged() {
  return this.http
    .get<any>(this.isLoggedUrl)
    .pipe(
      retryWhen(errors => {
        errors.switchMap(error => {
          if(errors.error.message != 'TokenExpiredError') {
            throw errors
          }

          //DO.. try refresh token. if refreshed: this.loggedIn = true
        })
      }),    
      catchError(this.errorHandler)
    );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM