2017-12-21 27 views
0

私は自分のページを置くために角度ルーティングの認証書を置いた。私は、トークンが有効かどうかをチェックし、それに基づいて、さらなるナビゲーションのために真または偽を返すことを望むAPIを持っています。角度認証方式のAPI応答メッセージに基づいてtrue/falseを返すにはどうすればよいですか?

しかし、「購読」では、購読外で永続的でない「結果」フラグを割り当てているようです。ここでは「結果」の変数が間違っていますか?どうすれば修正できますか?私の間違いを以下のコードで理解するのを助けてください。

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { 
    const jwt = localStorage.getItem('jwt'); 
    let result = false; 

    this.signinService.isSignedin(jwt).subscribe((res) => { // <--- 
    console.log(res.json().message); 
    if (res.json().message === 'Token Valid') { 
     result = true; 
     console.log(result); 
     return true; 
    } else { 
     result = false; 
     return false; 
    } 
    }, (err) => { // <--- 
    console.log(err); 
    result = false; 
    return false; 
    }); 
    console.log('END' + result); 
    return result;} 

上記のコードは、以下の順序でコンソールに表示されます。これは私にとっては奇妙なものです。誰でも説明できますか?

を使用すると、定義されたコールバック関数が実行される前に、結果の値が返された

トークン有効

+1

あなたがすることはできません。そのため、このメソッドはPromiseまたはObservableを返すこともできます。これらの型では、ブール値**を非同期で返すことができます**。そうした場合、ルータは返されたobservable/promiseを購読し、ブール値が送出されたときにナビゲートします(またはしない)。 –

+0

お返事のいずれかがお手伝いしましたか? :) – Alex

+0

はい、それは私が私はAPIの呼び出しからブール値を返すことができないことを理解させた。だから私は以下のコメントで述べたように、今はjwtの存在でそれを行い、それに応じてブール値を返すことに決めました。私は、ユーザーが投稿したときだけ、サーバー側のトークンを確認します。 – notsogoodcoder

答えて

1

をENDfalse。これは、APIのラウンドトリップが終了した後にコールバックが呼び出されるため、かなり論理的です。

1

しかし、「購読」では、私の「結果」フラグが購読外で永続しないことを割り当てているようです。

私は、インタプリタがこのコードをどのように読んで評価するのか完全に理解していないと思います。 JavaScript event loopであるため、がブロックされないため、インタプリタはサブスクリプションブロックにアクセスし、要求を行い、応答が返るのを待たずにサブスクリプションブロックの外部でコードの実行を続けます。これが「ENDfalse」が最初に印刷される理由です。応答が返され、コールバック関数は、console.log(res.json().message);「トークン有効」と console.log(result);がtrueを返している行で実行されます。

これを解決できる方法は、observable全体を返し、実際にresultの値を使用したい場所にサブスクライブすることです(canActivateの関数シグネチャでは、データではなく観測可能なものを返す)。

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { 
    const jwt = localStorage.getItem('jwt'); 
    return this.signinService.isSignedin(jwt); 
} 
+0

私は正しいページにリダイレクトするものに基づいてブール値を返そうとしています。今、私はjwtの存在でそれをすることに決めました、そして、ユーザーが投稿するときだけ、サーバー側でトークンを確認します。 あなたの詳細なフィードバックは、JSの非ブロックイベントを理解するのに役立ちました。ありがとう!! – notsogoodcoder

-1

あなたはsubscribeから何かを返すことはできませんが、何を行うことができ、あなたのガードから観測を返すことです。

また、他の点で指摘されているように、これは非同期なので、コンソールログの順序です。あなたはここでそれについての詳細を読むことができます:あなたのコードをフォーマットする方法についてはHow do I return the response from an Observable/http/async call in angular2?

、聞かせてのを述べたリターンとして観察可能:

// add 'return' and use 'map' instead: 
return this.signinService.isSignedin(jwt).map((res) => { 
    if (res.json().message === 'Token Valid') { 
    return true; 
    } else { 
    return false; 
    } 
}, (err) => { 
    return false; 
}); 
関連する問題