我有一个API调用,该调用返回有关当前用户的数据(即用户名,全名,授权组成员身份,电子邮件地址等)。我只想在每个用户会话中调用一次此API,并在所有组件之间共享其数据。
我不想依赖localStorage,因为我不希望用户修改此数据。我正在尝试使用BehaviorSubject并尝试了以下示例,但是在尝试通过组件访问它时,我一直收到初始值(null)。
// HTTP Service:
getUserData() {
const url = `${baseUrl}/api/users/`;
return this.httpClient.get<UserData>(url).toPromise();
}
// Utils Service
export class UtilsService {
private userDataSubject: BehaviorSubject<UserData>;
constructor(
private httpService: HttpService,
) {
this.userDataSubject = new BehaviorSubject<UserData>(null);
this.setUserData();
}
async setUserData() {
let userData: UserData = await this.httpService.getUserData();
this.userDataSubject.next(userData);
console.log(this.userDataSubject.value); // Properly returns the data I want
}
public get userDataValue(): UserData {
return this.userDataSubject.value;
}
// Component
ngOnInit() {
this.userData = this.utils.userDataValue; // This is the variable I need to set in my component.
console.log(this.userData); // Returns null
console.log(this.utils.userDataValue); // Also returns null
}
我也尝试过为userDataValue()使用异步函数:
async userDataValue(): Promise<UserData> {
return this.userDataSubject.value;
}
并修改了我的组件:
async ngOnInit() {
this.userData = await this.utils.userDataValue();
console.log(this.userData); // Still returns null
console.log(await this.utils.userDataValue()); // Still returns null
}
到目前为止,只有避免使用BehaviorSubject并在每个组件中调用API的情况下,我才能使这项工作正常进行,但这似乎没有必要。非常感谢您提供有关如何进行此工作的指导。谢谢。
问题是setUserData()
是一个异步函数,this.httpService.getUserData()
需要一些时间才能从后端获取数据。因此,当您的组件调用它ngOnInit()
时,方法userDataSubject
尚未收到新值,这就是它返回null的原因。我建议使用BehaviorSubject subscribe
处理程序,以便您的代码在正确的时间执行应做的事情。就像这样:
export class UtilsService {
public userDataSubject: BehaviorSubject<UserData>;
constructor(private httpService: HttpService) {
this.userDataSubject = new BehaviorSubject<UserData>(null);
this.setUserData();
}
async setUserData() {
let userData: UserData = await this.httpService.getUserData();
this.userDataSubject.next(userData);
}
以及您的组件中
ngOnInit() {
this.utils.userDataSubject.subscribe((data) => {
console.log(data);
// component logic to use your data
// this will be called every time userDataSubject receives a new value
});
}