私はAngular 4 Webアプリケーションを作成しています。私はAuthGuard
とCanActivate
を使ってルートを保護する必要があるので、ユーザーが特定のルートにアクセスできるかどうかを確認します。AuthGuardは、関数の終了まで有効化し、サブスクリプションがtrueを返すのを待つ代わりにfalseを返します。
CanActivate
は、id
がsessionStorage
にあるかどうか最初にチェックします。それ以外の場合は、ユーザーが承認されている場合にバックエンドを確認します。 id
が既にsessionStorage
にあるプロジェクトをクリックしてcheckIfIDInStorage
に入りますが、それがelseに入り、自分のAPIを呼び出すと、関数の最後に移動して呼び出し前にfalseを返しますtrueを返しますcanActivate
のreturn false
を削除すると、それでも機能しません。私がそれが本当に戻ってきたことを確認した後、私は再びプロジェクトをクリックするとうまくいきます。
コンソール出力
can activate else
before return false
in subscribe if
true
in store
Guard.ts
canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
{
const id = route.params.id;
if (this.checkIfIDInStorage(id)) {
console.log("checking id");
return true;
}
else {
console.log("in can activate else");
this.API.checkProjectOwnership(id).subscribe((data) =>
{
console.log("in subscribe if");
if (data.type === 'AL') {
console.log("true");
this.storeProjectID(id);
return true;
}
else {
console.log("in subscribe else ");
this.router.navigate(['/dashboard']);
}
});
}
console.log("before return false");
return false;
}
storeProjectID(id: string) {
console.log("in store");
this.session.store('id', id);
return true;
}
getProjectID() {
return this.session.retrieve('id');
}
checkIfIDInStorage(id: string) {
const storedID = this.getProjectID();
return (id === storedID);
}
API.service.ts
checkProjectOwnership(params: URLSearchParams): Observable<any> {
const URL = `${this.API}/projects/ownership?id=${params}`;
return this.auth.refreshToken()
.flatMap(() => this.authHttp.get(URL, this.headers))
.map((response: Response) => response.json())
.share()
.catch(this.handleError);
}
これは、API呼び出しが非同期であるためです。この関数は、非同期呼び出しが終了するのを待機しません。代わりにルートリゾルバを使用してみることもできます。 *あなたの非同期API呼び出しを待ちます。または、あなたのガードをここに示すようにBooleanの代わりにObservableを返すようにすることができます:https://stackoverflow.com/questions/38425461/angular2-canactivate-calling-asyncfunction – DeborahK