I a*_*bot 3 firebase typescript angular google-cloud-firestore
我的服务中有方法,在其中我试图返回User对象的Observable。这是我的代码-
constructor(private firestore: AngularFirestore,
private db: AngularFireDatabase) { }
/**
* get user with given email, if not return null
*
* @param email email to fetch
*/
getUserByEmail(email: string): Observable<User> {
var user: User;
let userRef = this.firestore.collection("users").ref.where('email', '==', email);
userRef.get().then(res => res.forEach(userDoc => {
user = userDoc[0].data() as User; // since email IDs are unique, I want the 0th element.
user.id = userDoc[0].id;
console.log(user); // has the data
// return user; // doesn't work, not the right thing
}));
console.log(user); // undefined, since call is async
return of(user);
}
Run Code Online (Sandbox Code Playgroud)
在组件内部,我需要该数据用于后续步骤,所以我这样做了-
checkEmail() {
var user$: User
this.us.getUserByEmail(this.existingUserForm.value.email).subscribe(user => {
console.log(user);
if (user) {
this.msg$ = "success";
// next steps
}
else {
this.msg$ = "User with this email does not exist!";
}
});
}
Run Code Online (Sandbox Code Playgroud)
我不确定如何从服务中返回一个可观察对象,以便可以使用组件中的数据。这是做我想做的正确方法吗?
如果您希望从Firestore获得可观察的对象,则需要在AngularFirestoreCollection上返回.valueChanges()。阅读此文档以供参考:https : //github.com/angular/angularfire2/blob/master/docs/firestore/querying-collections.md。
在您的服务中执行以下操作:(为了清楚起见,我声明了collection和user $变量)。
getUserByEmail(email: string): Observable<User> {
const collection = this.firestore.collection<User>('users', ref => ref.where('email', '==', email))
const user$ = collection
.valueChanges()
.pipe(
map(users => {
const user = users[0];
console.log(user);
return user;
})
);
return user$;
}
Run Code Online (Sandbox Code Playgroud)
如果您还需要用户的ID,则需要使用snapshotChanges()。有时,保存到Firestore时更容易维护用户数据上的ID,以避免使用snapshotChanges(我认为)。
// Query the users by a specific email and return the first User with ID added
return this.firestore.collection<User>('users', ref => ref.where('email',
'==', email))
.snapshotChanges()
.pipe(map(users => {
const user = users[0];
if (user) {
const data = user.payload.doc.data() as User;
const id = user.payload.doc.id;
return { id, ...data };
}
else {
return null;
}
}));
Run Code Online (Sandbox Code Playgroud)
在您的组件代码中,您可以通过以下方式调用它
checkEmail() {
this.user$ = this.us.getUserByEmail('email@gmail.com')
.pipe(
tap(user => {
if (user) {
this.msg = 'success';
} else {
this.msg = 'User with this email does not exist!';
}
}));
}
Run Code Online (Sandbox Code Playgroud)
请注意,直到您在this.user $上调用subscribe为止,用户将为null。或者在HTML中使用异步管道处理可观察对象上的subscribe和unsubscribe。
<div *ngIf="(user$ | async) as user">{{ user.email }}</div>
Run Code Online (Sandbox Code Playgroud)
尝试避免在您的html中对同一可观察的多次使用异步管道,而应将其设置为我上面(以用户身份)执行的本地html变量,以避免不必要的数据传递到db
有关命名约定的说明。Observable的变量名通常后缀“ $”,而其他变量(字符串,数字等)则不带有“ $”。
| 归档时间: |
|
| 查看次数: |
2831 次 |
| 最近记录: |