[英]Firebase query function returning undefined when page is refreshed
I Got a service in Angular that gets User Data from firestore.我在 Angular 中获得了一项服务,该服务从 firestore 获取用户数据。 The relevant service code is as follows:相关服务代码如下:
userType:string = ''
async getProfileType(): Promise<string> {
const userUID = await this.getUserUID();
const getUserType = () => {
this.af
.collection('users')
.doc(userUID)
.valueChanges()
.subscribe((doc: any) => {
console.log(doc.userType);
this.userType = doc.userType;
});
return this.userType;
};
return getUserType();
}
When I try to invoke it in the component by injecting it and calling the function in the ngOnInit method I get the following error: ERROR TypeError: Cannot read properties of undefined (reading 'userType')
当我尝试通过注入它并在 ngOnInit 方法中调用 function 来在组件中调用它时,出现以下错误: ERROR TypeError: Cannot read properties of undefined (reading 'userType')
And when I invoke the function from the service manually it returns the data fine, but I'm not sure why it can't do the same thing when invoked on the ngOnInit method.当我从服务手动调用 function 时,它返回数据正常,但我不确定为什么在 ngOnInit 方法上调用时它不能做同样的事情。
I've tried making ngOnInit async and use await on the getProfileType function but that didn't seem to make a difference.我试过使 ngOnInit 异步并在 getProfileType function 上使用 await 但这似乎没有什么不同。
The Component TypeScript is as follows:组件TypeScript如下:
import { Component, OnInit } from '@angular/core';
import { AngularFirestore } from '@angular/fire/compat/firestore';
import { UserInfoService } from '../services/user-info/user-info.service';
@Component({
selector: 'app-edit-profiles',
templateUrl: './edit-profiles.component.html',
styleUrls: ['./edit-profiles.component.scss'],
})
export class EditProfilesComponent implements OnInit {
constructor(public userInfo: UserInfoService, private af: AngularFirestore) {}
async ngOnInit() {
this.userInfo.getProfileType();
}
The Component HTML is as follows:组件HTML如下:
<div *ngIf="userInfo.userType === 'user'">
You're a User
</div>
<div *ngIf="userInfo.userType === 'project'">
You're a Project
</div>
<button mat-flat-button (click)="userInfo.getProfileType()">Get Profile Type</button>
Any help or direction is appreciated, cheers!感谢任何帮助或指导,干杯!
Your getProfileType
method claims to be returning a Promise<string>
, but it's actually just returning a string
that hasn't been initialize yet as you're never awaiting the database result.您的getProfileType
方法声称要返回一个Promise<string>
,但它实际上只是返回一个尚未初始化的string
,因为您永远不会等待数据库结果。
async getProfileType(): Promise<string> {
I'd recommend returning an Observable<string>
, since the profile type may change:我建议返回一个Observable<string>
,因为配置文件类型可能会改变:
getProfileType(): Observable<string> {
const userUID = await this.getUserUID();
return this.af
.collection('users')
.doc(userUID)
.valueChanges()
.pipe(map((doc: any) => {
return doc.userType;
}));
}
Alternatively, you can stick to the Promise
approach, but then return just one document with take(1)
or first()
:或者,您可以坚持使用Promise
方法,但随后使用take(1)
或first()
仅返回一个文档:
getProfileType(): Observable<string> {
const userUID = await this.getUserUID();
return this.af
.collection('users')
.doc(userUID)
.valueChanges()
.pipe(take(1))
.pipe((doc: any) => {
return doc.userType;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.