bugfix> angular > 投稿

次のようなユーザーのロールを返すメソッドがあります。

 getUserRoles() : Observable<string[]> {
    return this.getToken().pipe(
      map(token => {
        let payload = decode(token);
        return payload["roles"];
      })
    )
  }

これをアンカーで使用して、次のような役割に基づいてアイテムを表示/非表示にしようとしています。

<a *ngIf="(authService.getUserRoles | async).includes('admin')" routerLink="/admin" clrDropdownItem>Admin</a>

ただし、コンパイラエラーが発生します。

ERROR in src/app/components/profile/profile.component.html:15:18 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '() => Observable<string[]>' is not assignable to parameter of type 'Promise<unknown>'.
      Type '() => Observable<string[]>' is missing the following properties from type 'Promise<unknown>': then, catch, [Symbol.toStringTag], finally
15       <a *ngIf="(authService.getUserRoles | async).includes('admin')" routerLink="/admin" clrDropdownItem>Admin</a>
                    ~~~~~~~~~~~~~~~~~~~~~~~~~
  src/app/components/profile/profile.component.ts:7:16
    7   templateUrl: './profile.component.html',
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component ProfileComponent.

私が間違っていることを完全に理解することはできません。私はAngular9を使用しています。

回答 3 件
  • ああ、わかったと思います!

    テンプレート内の関数呼び出しでも、同じような問題が発生しました。簡単に言えば、変更検出によってトリガーされた変更検出は、多かれ少なかれです while (true);

    これを変更してみてください

    <a *ngIf="(authService.getUserRoles() | async).includes('admin')" ...
    
    

    のようなものに

    <a *ngIf="userIsAdmin" ...
    
    

    およびコンポーネントのTS部分

    userIsAdmin = false;
    onDestroy = new Subject();
    ngOnInit() {
        this.authService.getUserRoles().pipe(takeUntil(this.onDestroy)).subscribe(/* assign value to this.userIsAdmin here
    }
    ngOnDestroy() {
        /* To prevent a memory leak */
        this.onDestroy.next(); 
        this.onDestroy.complete();
    }
    
    

  • あなたのアプローチはうまくいきません...

    コードを次のように変更した場合でも: authService.getUserRoles() | async この関数はビューがチェックされるたびに実行されるため、コードは機能しません。 あなたは恩恵を受けません async パイプ、反対。

    それが良いだろう

    1) Subscribe to your data in the initilazition of the component (remember to unsubscribe before you destroy the component).

    2) Create new pipe to handle that logic.

    3) Use guards.

    4) Make the function synchronous:

    .ts
        isInRole(role: string): boolean {
            const token = this.getToken();
            const payload = decode(token);
            return payload && payload["roles"] && payload["roles"].includes(role);
        }
    .html
         <a *ngIf="isInRole('admin')" routerLink="/admin" clrDropdownItem>Admin</a>
    
    

  • この概念を試してください(テストされていません)

    getUserRoles() : Observable<string[]> {
          let obs = from(this.getToken())
          obs.subscribe(pipe(
          map(token => {
            let payload = decode(token);
            return payload["roles"];
          }));
          return obs;
        )
      }
    
    

あなたの答え