Angular BehaviorSubject没有从http调用中获取数据。

我试图用behaviorSubject通过http调用从db获取用户名。当用户登录时,这个过程应该被初始化。然后当用户名发生变化时,我想在不重载页面的情况下显示更新后的值。我对BehaviorSubject的概念和使用很陌生,所以这是我目前所做的。我创建了一个Authservice,它从Auth0Service中获取isAuthenticated$(boolean)observable(我使用auth0来进行认证),并检查用户是否登录。但是当我想在sidenav中显示名字时,它是空的,这是behaviorSubject的初始值。所以我想我从来没有调用过数据。

AuthService:

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  constructor(private api: ApiService, private auth0Service: Auth0Service ) { 
    this.auth0Service.isAuthenticated$.pipe(tap(isAuth => {
      if (isAuth) {
       this.getLoggedInUser()
        console.log(isAuth)
      }
    }));


   }

  private userSubject$ = new BehaviorSubject<any>(null);
  user$ = this.userSubject$.asObservable();

  getLoggedInUser(): Observable<any> {
    return this.api.getCurrentLoggedInUser().pipe(tap(user=> this.userSubject$.next(user)));

  }


}

sidenav,我在这里调用user$:

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

 getUser$ : Observable<User>;
 ngOnInit(): void {

    this.getUser$ =  this.authService.user$

 }

应用组件,我首先在那里初始化

export class AppComponent implements OnInit {
 constructor(public auth0Service: Auth0Service, private authService: AuthService) {}
 ngOnInit(): void {
    this.authService.user$;
 }
}

sidenav html。

   <div *ngIf="getUser$  | async as profile">
          <h3>{{profile.name}}</h3>
   </div>

谁能帮我理解为什么我得不到任何数据?

更新。

我已经成功地验证了我最初甚至没有进入getLoggedInUSer函数,但现在我把this.getLoggedInUser()调用移到了我的authguard中,现在我可以在getLoggedInUser()中成功地将loggin boolean记录为true。现在我尝试在api调用后在getLoggedInUser()中记录userSubject$,并且在调用前删除了return。我在控制台得到这个。

BehaviorSubject {_isScalar: false, observers: Array(0), closed: false, isStopped: false, hasError: false, …}
value: (...)
_isScalar: false
observers: [Subscriber]
closed: false
isStopped: false
hasError: false
thrownError: null
_value: null
__proto__: Subject

它看起来是空的,这很奇怪,因为我在调用api之后记录了这个。

解决方案:

你的服务不应该在构造函数中调用方法 this.auth0Service.isAuthenticated$.. 这些方法应该是分开的。

import { HttpClient } from '@angular/common/http';
import {Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';


@Injectable({
  providedIn: 'root'
})
export class AuthService {
    constructor(private api: ApiService, 
        private auth0Service: Auth0Service ) {}


    this.auth0Service.isAuthenticated$
        .pipe(map(v => v));


    getLoggedInUser(): Observable<any> {
        return this.api.getCurrentLoggedInUser()
            .pipe(map(v => v));
    }
}

而你的组件可以通过使用 asyncawait 关键字。

your.component.ts:

user: any;
async ngOnInit() {
    let isAuthenticated = this.authService.isAuthenticated.toPromise();
    if (isAuthenticated) {
        this.user = this.authService.getLoggedInUser().toPromise();          
        console.log(this.user);
    }
}

HTML。

<div *ngIf="user">
     <h3>{{user | json}}</h3>
</div>

更新。

你可以使用 Observable 用于获取最近更新的用户。

user: any;  

ngOnInit() {
    this.authService.isAuthenticated.pipe(
        tap(val => console.log(val)),
        switchMap(val => this.authService.getLoggedInUser())
        ).subscribe(user => {
            this.user = user;
        });
}

给TA打赏
共{{data.count}}人
人已打赏
未分类

gganimate::transition_time的结果是飞行的多边形。

2022-9-8 21:05:22

未分类

未使用Invoke-Expression参数

2022-9-8 21:16:36

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索