Angular BehaviorSubject 没有从 http 调用中获取数据
Angular BehaviorSubject isn't getting data from http call
我正在尝试使用 behaviorSubject 通过 http 调用从 db 获取用户名。当用户登录时,进程应该被初始化。然后当用户名更改时,我想显示它而不重新加载我的页面以获取更新的值。我对 BehaviorSubject 的概念和使用不熟悉,所以这就是我到目前为止所拥有的。我创建了一个 Authservice,它从 Auth0Service 中获取 isAuthenticated$(boolean) 可观察值(我使用 auth0 进行身份验证)并检查用户是否已登录。当用户登录时,它会触发我的 getLoggedInUser 函数,该函数包含 http 调用以获取数据。但是当我想在 sidenav 中显示名称时它是 null 是 behaviorSubject 的初始值。所以我想我从来没有打电话来获取数据。
授权服务:
@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 我调用用户$:
export class SidenavComponent implements OnInit {
constructor(private authService: AuthService) {}
getUser$ : Observable<User>;
ngOnInit(): void {
this.getUser$ = this.authService.user$
}
我第一次初始化的app组件
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,现在我可以成功地将登录布尔值记录为 true在我的 getLoggedInUser() 中。我现在尝试在 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));
}
}
并且您的组件可以使用 async
和 await
关键字从上述服务获取数据。
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;
});
}
我正在尝试使用 behaviorSubject 通过 http 调用从 db 获取用户名。当用户登录时,进程应该被初始化。然后当用户名更改时,我想显示它而不重新加载我的页面以获取更新的值。我对 BehaviorSubject 的概念和使用不熟悉,所以这就是我到目前为止所拥有的。我创建了一个 Authservice,它从 Auth0Service 中获取 isAuthenticated$(boolean) 可观察值(我使用 auth0 进行身份验证)并检查用户是否已登录。当用户登录时,它会触发我的 getLoggedInUser 函数,该函数包含 http 调用以获取数据。但是当我想在 sidenav 中显示名称时它是 null 是 behaviorSubject 的初始值。所以我想我从来没有打电话来获取数据。
授权服务:
@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 我调用用户$:
export class SidenavComponent implements OnInit {
constructor(private authService: AuthService) {}
getUser$ : Observable<User>;
ngOnInit(): void {
this.getUser$ = this.authService.user$
}
我第一次初始化的app组件
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,现在我可以成功地将登录布尔值记录为 true在我的 getLoggedInUser() 中。我现在尝试在 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));
}
}
并且您的组件可以使用 async
和 await
关键字从上述服务获取数据。
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;
});
}