2016-09-09 6 views
2

私はangular2にはかなり新しいですが、ログインコンポーネントを作成しようとしました。ログインが成功した後は、セッションサービス(ユーザー名とパスワードを保存して基本認証ヘッダーを作成する)にユーザー名とパスワードを設定したい場合を除いて、すべて正常に動作します。残念ながらthis._session.loggedInは決して設定されません。誰かアイデアなぜ?Angular2の変数はサブスクリプションでは動作しません

export class LoginComponent { 

    public email = ''; 
    public password = ''; 

    constructor(
     private _router: Router, 
     private _auth: AuthenticationService, 
     private _session: SessionService) { 
    } 

    login() { 
     this._auth.login(this.email, this.password) 
      .subscribe(
       data => { 
        this._session.currentProfile = data; 
        this._session.loggedIn = true; 
        this._router.navigate(['Home']); 
       }, 
       err => {} 
      ); 
    } 
} 

AuthenticationService:サーバーからの応答が到着したとき、または

login(email, password){ 
     return this._http.get('/profile') 
      .map(res => res.json()); 
} 
+0

login()メソッドとは何ですか?それはいつ呼び出されるべきですか?購読すると、イベントを動的にディスパッチしません。 –

+0

@KamilMyśliwiecログイン方法を追加しました。ちょうど簡単なhttpを取得します。それはボタンを押したときに呼び出されます。唯一の問題は、サブスクライブコールバックでは、データがセッションサービス – perotom

答えて

1

このコードは、このコードは、後にすぐに時には実行されませんsubscribe

 data => { 
      this._session.currentProfile = data; 
      this._session.loggedIn = true; 
      this._router.navigate(['Home']); 
     } 

に渡された関数であるものは何でもobservableが新しいイベントを送出するためにはイベントが必要であり、それによって上記の関数が呼び出されます。

これは、データが到着したときに実行されるコードが必要な場合は、コールバックの内側にそれを移動する必要が

login() { 
    this._auth.login(this.email, this.password) 
     .subscribe(
      data => { 
       this._session.currentProfile = data; 
       this._session.loggedIn = true; 
       this._router.navigate(['Home']); 
      }, 
      err => {} 
     ); 
    // <<== at this point above code hasn't been executed yet and no values are set 
} 

を意味します。

loginの発信者が受信したデータにアクセスする必要がある場合は、データが到着するまで待つ必要があります。あなたはそれがSubscriptionを返すため、この場合にはsubscribeを使用することはできません観測可能

login() { 
    return this._auth.login(this.email, this.password) 
     .map(
      data => { 
       this._session.currentProfile = data; 
       this._session.loggedIn = true; 
       this._router.navigate(['Home']); 
      } 
     ); 
} 

を返すことによって、これを達成することができます。あなたの代わりにmapを使用する場合は、ObservabledoSomething()が呼び出されたときに、

this.login().subscribe(data => this.doSomething()); 

のように、呼び出し側がこの方法を使用することができ_session.currentProfileは、_session.loggedInが設定されているとrouter.navigate()が呼び出された返されます。

非同期実行は常に適切に連鎖する必要があり、非同期呼び出しからの同期実行に戻る方法がありません。

+0

でクリアに設定されないことです。多分それは別の問題です。 'this._session.loggedIn'の値を設定した直後にログに記録すると、それは正しいですが、新しいコンポーネント' Home'inに移動して 'SessionService'をもう一度注入して' this 'の値を返します。 _session.loggedIn'が間違っています。私はangular2ですべてのサービスがシングルトンだと考えましたか? – perotom

+0

サービスに値を格納していないようです。 'login()'を呼び出したコンポーネント内でのみ。 Angular2のサービスはプロバイダーごとのシングルトンです。コンポーネントに提供すると、すべてのコンポーネントインスタンスのサービスインスタンスが取得されます。遅延ロードされたモジュールでプロバイダを提供すると、遅延ロードされたモジュールのプロバイダがルートプロバイダで収集されないため(ルートスコープを所有しています)、他の '@NgModules() 'に追加されたプロバイダは、スコープは1つのインスタンスしかありません –

+0

私はそれが問題だと思うので、 'app.module.ts'に' @NgModules() 'を使ってサービスを登録するだけでいいのですか? – perotom

関連する問題