Angular / Typescript / Firestore - 如何 return if 语句中的可观察值
Angular / Typescript / Firestore - How to return an observable value within an if statement
我正在使用 angular 和 Firestore。我正在检查 firestore 以获取我的路由守卫中的值。
我发现在页面刷新时,return未定义。但是,如果我只是将 return 硬编码为 true 或 false,它就可以工作。
我的 if 语句中的任何日志总是 return 正确,但由于某种原因似乎没有更新我的全局变量。
如果我使用我的站点导航返回到根目录并浏览我的站点,它可以正常工作。但是,当我刷新页面时,它 return 未定义。
会不会是范围界定问题?
路由守卫
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Subscription } from 'rxjs/Subscription';
//testing
import { Observable } from 'rxjs/Observable';
import { AngularFireAuth } from 'angularfire2/auth';
@Injectable()
export class CheckBillingService implements CanActivate {
private _subscription: Subscription;
private userBillingDocRef: AngularFirestoreDocument<any>;
userBilling: Observable<any>;
public activeAccount:Observable<boolean>
constructor(private authService: AuthService,
private router: Router,
private auth: AngularFireAuth,
private readonly afs: AngularFirestore) {}
canActivate(): Observable<boolean> {
this.authService.user.subscribe((user) => {
if (user) {
var userId = user.uid;
this.userBillingDocRef = this.afs.doc('user_billing/${userId}');
this.userBilling = this.userBillingDocRef.snapshotChanges();
this.userBilling.subscribe((value) => {
const data = value.payload.data();
if (data.account_status == "Active") {
this.activeAccount = Observable.of(true);
console.log('inside if statement for active = ', this.activeAccount);
} else {
this.activeAccount = Observable.of(false);
console.log('inside if statement for not active = ', this.activeAccount);
this.router.navigate(['resubscribe']);
return Observable.of(false);
}
console.log('userBilling.subscribe = ', this.activeAccount);
});
console.log('just outside userBilling.subscribe = ', this.activeAccount);
}
});
// When refreshig my page, this returns as undefined.
// If I navigate to the correct page and work my way through the site it works fine
// However, refresh returns undefined.
console.log('out of auth = ', this.activeAccount);
return this.activeAccount;
}
}
根据您的代码,页面将 运行 在您的可观察方法 return 编辑之前 运行 异步,而不是 return 可观察的完整方法,例如所以
canActivate(): Observable<boolean> {
return Observable.create(observer=> {
this.authService.user.subscribe((user) => {
if (user) {
var userId = user.uid;
this.userBillingDocRef = this.afs.doc('user_billing/${userId}');
this.userBilling = this.userBillingDocRef.snapshotChanges();
this.userBilling.subscribe((value) => {
const data = value.payload.data();
if (data.account_status == "Active") {
this.activeAccount = Observable.of(true);
// observe here
observer.next(true)
console.log('inside if statement for active = ', this.activeAccount);
} else {
this.activeAccount = Observable.of(false);
// observe here
observer.next(false)
console.log('inside if statement for not active = ', this.activeAccount);
this.router.navigate(['resubscribe']);
}
console.log('userBilling.subscribe = ', this.activeAccount);
});
console.log('just outside userBilling.subscribe = ', this.activeAccount);
}
});
});
// When refreshig my page, this returns as undefined.
// If I navigate to the correct page and work my way through the site it works fine
// However, refresh returns undefined.
console.log('out of auth = ', this.activeAccount);
}
观察我在 Observer.create
中包装所有内容的位置,您可以在此处了解更多信息
然后 observer.next
将 return 您真正希望 canActivate
挂钩对
做出反应的内容
// observe here
observer.next(true)
observer.next(false)
Observable 可以是异步的;它们通常用于此目的。在这种情况下,订阅外部的代码在订阅内部的代码之前执行。
这就是为什么它看起来像是 "not updating" 变量的原因。是的,但您没有在正确的时间访问它们。当您对值进行硬编码时它会起作用,因为订阅是同步执行的。
我正在使用 angular 和 Firestore。我正在检查 firestore 以获取我的路由守卫中的值。
我发现在页面刷新时,return未定义。但是,如果我只是将 return 硬编码为 true 或 false,它就可以工作。
我的 if 语句中的任何日志总是 return 正确,但由于某种原因似乎没有更新我的全局变量。
如果我使用我的站点导航返回到根目录并浏览我的站点,它可以正常工作。但是,当我刷新页面时,它 return 未定义。
会不会是范围界定问题?
路由守卫
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Subscription } from 'rxjs/Subscription';
//testing
import { Observable } from 'rxjs/Observable';
import { AngularFireAuth } from 'angularfire2/auth';
@Injectable()
export class CheckBillingService implements CanActivate {
private _subscription: Subscription;
private userBillingDocRef: AngularFirestoreDocument<any>;
userBilling: Observable<any>;
public activeAccount:Observable<boolean>
constructor(private authService: AuthService,
private router: Router,
private auth: AngularFireAuth,
private readonly afs: AngularFirestore) {}
canActivate(): Observable<boolean> {
this.authService.user.subscribe((user) => {
if (user) {
var userId = user.uid;
this.userBillingDocRef = this.afs.doc('user_billing/${userId}');
this.userBilling = this.userBillingDocRef.snapshotChanges();
this.userBilling.subscribe((value) => {
const data = value.payload.data();
if (data.account_status == "Active") {
this.activeAccount = Observable.of(true);
console.log('inside if statement for active = ', this.activeAccount);
} else {
this.activeAccount = Observable.of(false);
console.log('inside if statement for not active = ', this.activeAccount);
this.router.navigate(['resubscribe']);
return Observable.of(false);
}
console.log('userBilling.subscribe = ', this.activeAccount);
});
console.log('just outside userBilling.subscribe = ', this.activeAccount);
}
});
// When refreshig my page, this returns as undefined.
// If I navigate to the correct page and work my way through the site it works fine
// However, refresh returns undefined.
console.log('out of auth = ', this.activeAccount);
return this.activeAccount;
}
}
根据您的代码,页面将 运行 在您的可观察方法 return 编辑之前 运行 异步,而不是 return 可观察的完整方法,例如所以
canActivate(): Observable<boolean> {
return Observable.create(observer=> {
this.authService.user.subscribe((user) => {
if (user) {
var userId = user.uid;
this.userBillingDocRef = this.afs.doc('user_billing/${userId}');
this.userBilling = this.userBillingDocRef.snapshotChanges();
this.userBilling.subscribe((value) => {
const data = value.payload.data();
if (data.account_status == "Active") {
this.activeAccount = Observable.of(true);
// observe here
observer.next(true)
console.log('inside if statement for active = ', this.activeAccount);
} else {
this.activeAccount = Observable.of(false);
// observe here
observer.next(false)
console.log('inside if statement for not active = ', this.activeAccount);
this.router.navigate(['resubscribe']);
}
console.log('userBilling.subscribe = ', this.activeAccount);
});
console.log('just outside userBilling.subscribe = ', this.activeAccount);
}
});
});
// When refreshig my page, this returns as undefined.
// If I navigate to the correct page and work my way through the site it works fine
// However, refresh returns undefined.
console.log('out of auth = ', this.activeAccount);
}
观察我在 Observer.create
中包装所有内容的位置,您可以在此处了解更多信息
然后 observer.next
将 return 您真正希望 canActivate
挂钩对
// observe here
observer.next(true)
observer.next(false)
Observable 可以是异步的;它们通常用于此目的。在这种情况下,订阅外部的代码在订阅内部的代码之前执行。
这就是为什么它看起来像是 "not updating" 变量的原因。是的,但您没有在正确的时间访问它们。当您对值进行硬编码时它会起作用,因为订阅是同步执行的。