2017-03-06 16 views
3

私は個人的な角型プロジェクトに取り組んでいます。それでも学び、角度にAngularJSから移動しよう:)角度2の方法は定義されていないか、呼び出し不可能です

これは私のコードです:

import { Injectable } from '@angular/core'; 
import { CanActivate, Router } from '@angular/router'; 

import { LoginService } from './login.service'; 

@Injectable() 
export class LoggedInGuard implements CanActivate { 

    constructor(
     private _router: Router, 
     private _loginService: LoginService 
    ) { 
    } 

    isLoggedIn() { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         return v.status == 'ok'; 
        }); 
      } else { 
       return false; 
      } 
     }; 

    canActivate() { 
     console.log(this.isLoggedIn()); 

     if (this.isLoggedIn()) { 
      return true; 
     } else { 
      this._router.navigate(['/login']); 
      return false; 
     }; 
    } 

} 

私の問題があるしかし:

  1. 私はその後、「未定義」console.log(this.isLoggedIn());this.を続ける場合印刷されます。私はそれを削除した場合
  2. 、その後、私はそれを呼び出す他のファイルから問題なく使用されているVSコード[ts] Cannot find name 'isLoggedIn'. Did you mean the instance member 'this.isLoggedIn'?に次のメッセージとコンソールUncaught (in promise): ReferenceError: isLoggedIn is not defined
  3. 方法isLoggedIn()で同じを持っています。
+0

未定義が印刷されるとログインしていますか?ログアウトしたときにコードを実行してみることはできますか?私はすべてを正しく呼び出すと思いますが、 'isLoggedIn'メソッドはすべての場合に値を返しません。 –

答えて

2

あなたはメソッドに未定義になっている理由:サブスクリthis._loginService.isLoggedIn(token)は非同期であり、すぐに返さないため

isLoggedIn() { 
    let token = localStorage.getItem('token'); 
    if (token) { 
     this._loginService.isLoggedIn(token) 
       .subscribe(v => { 
        return v.status == 'ok'; 
     }); 
    } else { 
      return false; 
     } 
}; 

です。したがって、メソッドisLoggedIn()は実行を終了し、応答がある前に戻ります。

あなたが代わりに行うことができることは、あなたの_loginServiceが他のコンポーネントが読み書きできるローカル変数、またはトークンを同期的にチェックして有効かどうかを確認する機能です。トークンが存在する場合は、ユーザーがログインしており、そこから実行できることは、トークンが期限切れでないことを確認することです。それはいくつかの異なる方法で行うことができます。あなたは、JWTのトークンの管理を支援するためにangular-jwtライブラリを使用していない場合

authenticated() { 
    // Check if there's an unexpired JWT 
    return tokenNotExpired(); 
} 

:あなたは、あなたのJWTトークンを扱う助けるためにangular2-jwtライブラリを使用している場合、あなたは次のようになりますあなたの_loginServiceのメソッドを持つことができます

isTokenValid(){ 
    let token = localStorage.getItem('token'); 
    let decodedToken = window.atob(token.split('.')[1]); 

    if((decodedToken.exp * 1000) < Date.now()){ 
     return false; 
    } 
    return true; 
} 

希望することができます。

+0

答えをありがとう。私は 'angular2-jwt'を使っていないので、' isTokenValid() 'メソッドをテストしたいと思います。しかし、 'decoded'と' decodedToken'の間に何があるのか​​よくわかりません。それらは同じで、ちょうどタイプミスか何とかあなたは最初のものからdecodedTokenを手に入れますか? – Tasos

+0

申し訳ありませんが、それはタイプミスでした。 –

+0

私はトークンを "。"で分割する必要があることを知りました。 2番目のインスタンスを取得します。しかしその後、すべてが大丈夫だった。あなたの答えは一番良いと思いますが、最後の更新でそれを編集してください。大いに感謝する – Tasos

1

これが答えとしての資格はないかもしれないが、私はコメントを投稿するには十分な評判ポイントを持っていない - 誰も、私を許し:)

私はそれがあるとして、あなたがそのようにサブスクライブから値を返すことができないと思います以下に示すように非同期呼び出し..

は代わりに、あなたのisLoggedIn()メソッドが返す必要がある:変更はここにある

isLoggedIn() { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       return this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         return v.status == 'ok'; 
        }); 
      } else { 
       return false; 
      } 
     }; 

注:return this._loginService.isLoggedIn(token)...希望、このことができます。

EDIT: 申し訳ありません... はどうしたんですが、あるあなたが実行を継続する非同期呼び出し(つまり、呼び出しを実行isLoggedIn()を呼び出している:(まだ動作しないだろうと...上記の私の答えを無視バックグラウンドと後で戻ってくる)。なぜなら、私は、上記のTylerのアドバイスに従って、返された値を格納し、後で利用するローカル変数を持っているか、コールバックを渡すことができるisLoggedIn()メソッドに - このコールバックは、非同期呼び出しが完了した後に呼び出されます。下記を参照してください:

import { Injectable } from '@angular/core'; 
import { CanActivate, Router } from '@angular/router'; 

import { LoginService } from './login.service'; 

@Injectable() 
export class LoggedInGuard implements CanActivate { 

    constructor(
     private _router: Router, 
     private _loginService: LoginService 
    ) { 
    } 

    isLoggedIn(callback: (v) => void) { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         callback(v) 
        }); 
      } 
     }; 

    canActivate() { 
     this.isLoggedIn((v) => { // this here is your callback function which will get invoked once async call is done 
      if(v.status == 'ok' { 
       // do something... 
       return true; 
      } else { 
       // do something 
       this._router.navigate(['/login']); 
      } 
     }); 
    } 

} 
関連する問題