typescript 将OKTA Observable转换为可用的字符串变量

rekjcdws  于 2022-12-19  发布在  TypeScript
关注(0)|答案(1)|浏览(143)

我试图在Angular 12中创建一个返回“用户”的服务。我使用OKTA进行身份验证。
我只想简化一下......我可以像这样把姓氏作为一个可观测项:

let familyName = this._oktaAuthStateService.authState$.pipe(
      filter((authState: AuthState) => !!authState && !!authState),
      map((authState: AuthState) => authState.idToken?.claims.family_name ?? '')
    );

但我只想传递一个字符串--而不是整个可观察对象。
例如,我现在可以通过执行以下操作将familyName用于HTML

{{familyName | async}}

但我希望有变量但没有可观察的。
这里是我的文件供参考(是的,我知道他们是笨重的)。
user.service.ts

import {Inject, Injectable} from '@angular/core';
import {OKTA_AUTH, OktaAuthStateService} from '@okta/okta-angular';
import {filter, map, Observable, of, Subscription} from 'rxjs';
import {AccessToken, AuthState, OktaAuth} from '@okta/okta-auth-js';
import {User} from './data/user.model';

@Injectable({
  providedIn: 'root'
})

export class UserService {

  constructor(
    private _oktaAuthStateService: OktaAuthStateService,
    @Inject(OKTA_AUTH) private _oktaAuth: OktaAuth
  ) { }

  get user(): Observable<any> {

    let name = this._oktaAuthStateService.authState$.pipe(
      filter((authState: AuthState) => !!authState && !!authState),
      map((authState: AuthState) => authState.idToken?.claims.name ?? '')
    );

    let email = this._oktaAuthStateService.authState$.pipe(
      filter((authState: AuthState) => !!authState && !!authState),
      map((authState: AuthState) => authState.idToken?.claims.email ?? '')
    );

    let familyName = this._oktaAuthStateService.authState$.pipe(
      filter((authState: AuthState) => !!authState && !!authState),
      map((authState: AuthState) => authState.idToken?.claims.family_name ?? '')
    );

    let givenName = this._oktaAuthStateService.authState$.pipe(
      filter((authState: AuthState) => !!authState && !!authState),
      map((authState: AuthState) => authState.idToken?.claims.given_name ?? '')
    );

    let stringName = name.subscribe(value => {
      return value.toString();
    })

    let accessToken = this._oktaAuthStateService.authState$.pipe(
      filter((authState: AuthState) => !!authState && !!authState),
      map((authState: AuthState) => authState.accessToken?.accessToken ?? '')
    );

    let obsof5: Observable<User>;
    obsof5 = of<User>({
      'email': email,
      'name': name,
      'givenName': givenName,
      'familyName': familyName,
      'accessToken': accessToken,
      'tenancy': [],
      'tenantIds': []
    });
    return obsof5;
  }
}

app.component.ts

import { Component, Inject, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { OktaAuthStateService, OKTA_AUTH } from '@okta/okta-angular';
import {AccessToken, AuthState, OktaAuth} from '@okta/okta-auth-js';
import {filter, map, Observable, Subscription} from 'rxjs';
import { UserService } from './user.service';
import {UserTenancy} from './data/user.model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'okta-angular-quickstart';
  public isAuthenticated$!: Observable<boolean>;
  public name: Observable<string> | undefined;
  email: Observable<string> | undefined;
  givenName: Observable<string> | undefined;
  familyName: Observable<string> | undefined;
  accessToken: Observable<"" | AccessToken> | undefined;

  constructor(private _router: Router,
              private _oktaStateService: OktaAuthStateService,
              @Inject(OKTA_AUTH) private _oktaAuth: OktaAuth,
              private userService: UserService
  ) { }

  public ngOnInit(): void {
    this.isAuthenticated$ = this._oktaStateService.authState$.pipe(
      filter((s: AuthState) => !!s),
      map((s: AuthState) => s.isAuthenticated ?? false)
    );

    this.userService.user.subscribe(
        (value) => {
          console.log("value", value);
          this.name = value.name;
          this.email = value.email;
          this.givenName = value.givenName;
          this.familyName = value.familyName;
          this.accessToken = value.accessToken;
      }
    );
  }

  public async signIn() : Promise<void> {
    await this._oktaAuth.signInWithRedirect().then(
      _ => this._router.navigate(['/profile'])
    );
  }

  public async signOut(): Promise<void> {
    await this._oktaAuth.signOut();
  }
}

app.component.html

<h1>Hello world - here's where you are</h1>
  <p>Name: {{name | async}}</p>
  <p>Email: {{email | async}}</p>
  <p>FamilyName: {{familyName | async}}</p>
  <p>GivenName: {{givenName | async}}</p>
  <p>AccessToken: {{accessToken | async}}</p>
  <p>Is Authenticated: {{isAuthenticated$ | async}}</p>
ccrfmcuu

ccrfmcuu1#

1-在组件类中将familyName : string;familyName$ : Observable<string>;声明为全局变量。
2-那么你可以用和isAuthenticated$相同的方法定义familyName$

this.familyName$ = this._oktaStateService.authState$.pipe(...

3-您订阅familyName$并将传入值发送到familyName,如下所示:

this.familyName$.subscribe(
  (fName) => { this.familyName = fName}
);

现在,familyName$是一个可观察对象,familyName是一个普通字符串,因此可以根据需要使用它们。

相关问题