2016-06-27 3 views
1

私はlogin()関数を持ち、テンプレートにはコンポーネントにバインドされた変数{{message}}があります。非同期操作の後に角度2の結合が削除されたようです

login() { 
    this.busy = true; 
    this.message = 'Trying to log in ...'; // correctly updates the template here 
    this.authService.login().subscribe(
     () => { 
      this.busy = false; 
      if(!this.authService.isAuthenticated()) { 
       return; 
      } 
      this.router.navigate(['/']); 
     }, 
     error => { 
      console.log(this.message); 
      console.error(error); 
      this.busy = false; 
      this.setErrorMessage(); 
      console.log(this.message); 
     } 
    ); 
} 

問題は「エラー」コールバックの内側に、私はthis.setErrorMessage()を呼び出すときに、テンプレートが更新を取得していないということです。

はここでログイン機能です。 this.setErrorMessage()の後にconsole.log(this)を実行しましたが、コンポーネント変数は正しく設定されていますが、HTMLには反映されていません。

アイデア?

更新日: error機能が更新されました。また、@GünterZöchbauerが提案したように.catch()で試してみました。いいえ、運がいいよ。

ここsetErrorMessage()機能です:

setErrorMessage() { 
    this.message = 'There was an error while trying to log you in. Please try again in a few moments!' 
} 

関連するテンプレートの一部:

login():Observable<any> { 
    return this.http.get(API_URL + "/login", {headers: this.headers()}) 
     .map(this.parseResponse) 
     .catch(this.handleError); 
} 

parseResponseと:

<p id="GB-login-frame-text"> 
    {{message}} 
</p> 

authService.login()機能がそうのようなObservableを返しますが、の機能:

private parseResponse(response:Response):any { 
    let result = response.json(); 
    return result.data || {}; 
}  

private handleError(error:any) { 
    let errMsg = (error.message) ? error.message : 
     error.status ? `${error.status} - ${error.statusText}` : 'Server error'; 
    if(error.status == 401) { 
     localStorage.removeItem('user'); 
     window.location.href = '/login'; 
     return; 
    }  
    return Observable.throw(errMsg); 
} 

そしてerror関数が呼び出されるコンソール出力:

Trying to log in ... 
login.component.ts:39 Object {error: "A generic error occurred"}(anonymous function) @ login.component.ts:39SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.error @ Subscriber.ts:204Subscriber._error @ Subscriber.ts:137Subscriber.error @ Subscriber.ts:107(anonymous function) @ auth.service.ts:50SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93onLoad @ http.umd.js:1104ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423 
login.component.ts:42 There was an error while trying to log you in. Please try again in a few moments! 

messageは、それが思わコンポーネントjs一部で正しく更新されているが、それはhtmlには反映されません。

login() { 
    this.busy = true; 
    this.message = 'Trying to log in ...'; // correctly updates the template here 
    this.authService.login() 
    .catch(// needs import 
     error => { 
      console.error(error); 
      this.busy = false; 
      this.setErrorMessage(); 
      return Observable.of([]); // needs import 
     } 
    }) 
    .subscribe(
     () => { 
      this.busy = false; 
      if(!this.authService.isAuthenticated()) { 
       return; 
      } 
      this.router.navigate(['/']); 
     } 
    ); 
} 
+2

あなたは私たちに、テンプレートと 'setErrorMessage'方法を示してもらえますか? – rinukkusu

+0

完了しましたが、そのコードは非常に些細です。 –

+0

Plunkerで再現できますか? –

答えて

2

上のコメントに基づいて:

+0

これを正解とマークしました。彼のインプットがこれを理解するのを助けて以来、+1 @ギュンターもまた。 –

2

は、私は、例外が発生したときにそれ以外の場合は、変更検出がコンポーネント上で実行されません、あなたはエラーの後に正常に実行されるコードを確認するためにcatch()を使用する必要があると思います問題と他の答えでは、エラーの変化の検出が行われないように思われます。これはAngular2のNgZoneで実行されていない場合がほとんどです。私はこれをバグと見なしますが、可能です。

その後、次のようにそれを包む使用することができます。

constructor(private zone:NgZone) { 
    // ... 
} 

login() { 
    this.busy = true; 
    this.message = 'Trying to log in ...'; // correctly updates the template here 
    this.authService.login().subscribe(
     () => { 
      this.busy = false; 
      if(!this.authService.isAuthenticated()) { 
       return; 
      } 
      this.router.navigate(['/']); 
     }, 
     error => this.zone.run(() => { 
      console.log(this.message); 
      console.error(error); 
      this.busy = false; 
      this.setErrorMessage(); 
      console.log(this.message); 
     }) 
    ); 
} 
+0

'Observable'のプロトタイプは' Rx.Observable.prototypeです。subscribe([observer] | [onNext]、[onError]、[onCompleted]) 'を実行します。だからそれはエラーをキャッチします。 –

+0

@ MartinC。私はこの動作を期待していますが、変更検出がエラーの後に失敗した場合、エラーが発生したようには見えません。この質問で述べた状況を完全には調べていませんでしたが、コンポーネントで例外がスローされた後に変更検出が実行されないことがわかりました。 –

+0

それから 'NgZone'の中で実行されていないかもしれませんし、' zone.run(()=> {...}) 'にラップする必要があります。同様の問題はhttp://stackoverflow.com/questions/37849791/angular2-meteor-bind-data-from-calling-this-call/37857413#3785741になります。 –

関連する問題