this 、 this 、および this を含む多くのリソースを見てきましたが、望ましい結果を達成することができませんでした。
私がやろうとしているのは、(firebaseを使用して)ユーザーを認証し、認証されたら、次のページのダッシュボードをロードする前に、プロファイルをロードして変数userProfile
に保存することです。
マイサインインサービス:
_public signinUser(user: User) {
this.af.auth.login({
email: user.email,
password: user.password
},
{
provider: AuthProviders.Password,
method: AuthMethods.Password
}
)
.then(
success => {
console.log('Authenticated');
this.getProfile().subscribe( // PROBLEM is here
profile => {
console.log(profile);
console.log('Profile Loaded');
this.router.navigate(['/dashboard']);
}
)
}
)
.catch(function (error) {
...
console.log('ERROR SIGNING USER IN');
}
_
私のgetProfile()
メソッド:
_public getProfile(): Observable<any> {
return this.af.database.object('/profiles/' + this.user.uid)
.flatMap(
profile => {
console.log('inside success');
console.log(profile);
this.userProfile = <User>profile;
console.log('getProfile has completed');
return profile;
},
error => {
console.log(error)
});
_
これはログの一部がどのように見えるかです:
_Authenticated
auth.service.ts:104 ERROR SIGNING USER IN
auth.service.ts:105 TypeError: Cannot read property 'subscribe' of undefined
at auth.service.ts:91
at ZoneDelegate.invoke (zone.js:232)
at Object.onInvoke (ng_zone.js:238)
at ZoneDelegate.invoke (zone.js:231)
at Zone.run (zone.js:114)
at zone.js:502
at ZoneDelegate.invokeTask (zone.js:265)
at Object.onInvokeTask (ng_zone.js:229)
at ZoneDelegate.invokeTask (zone.js:264)
at Zone.runTask (zone.js:154)
auth.service.ts:106 Cannot read property 'subscribe' of undefined
auth.service.ts:184 inside success
auth.service.ts:185 Object {confirmPassword: "123123", email: "[email protected]", github: "aaa" name: "a", password: "123123"…}
auth.service.ts:188
getProfile has completed()
auth.service.ts:185
_
メソッドが個別に意図したとおりに機能していることがわかります。ユーザーが認証され、プロファイルがロードされます(ログに表示されます)。問題は、私が知らない理由でサブスクライブイベントにあります。
これは奇妙ですが、webpackを再起動すると問題は解決したようです。
これは、コードがどのように見え、promiseを介して正しく認証され、成功するとプロファイルをロードし、次に次のページをロードする方法です。
私のsigninUser
メソッド:
public signinUser(user: User) {
this.af.auth.login({
email: user.email,
password: user.password
},
{
provider: AuthProviders.Password,
method: AuthMethods.Password
}
)
.then(
success => {
console.log('Authenticated');
this.getProfile().subscribe(
profile => {
this.router.navigate(['/dashboard']);
},
error => console.log(error)
)
そして、私のgetProfile
メソッド:
public getProfile(): Observable<User> {
return this.af.database.object('/profiles/' + this.user.uid)
.map(
profile => {
console.log('inside success');
console.log(profile);
this.userProfile = <User>profile;
console.log(this.userProfile);
return profile;
},
error => {
console.log(error)
});
}
コールスタック:
- ユーザーは認証されています
- GetProfileをサブスクライブし、メソッドが完了するのを待ちます...
- GetProfile()メソッドが実行されます
- プロファイルが設定されています
- ページがリダイレクトされます
問題は、getProfile
が実際にObservable
を返さないことだと思います。
flatMap
を使用して、監視可能シーケンスをチェーン化し、プロファイルを監視可能として返すことができます。ただし、これが機能するためには、flatMap
内のコールバックがpromiseまたはobservableを返す必要があります( this answer から学んだように)。そうしないと、オブザーバブルのチェーンが壊れます。
したがって、おそらくあなたがする必要があるのは次のようなものです:
public getProfile(): Observable<any> {
return this.af.database.object('/profiles/' + this.user.uid)
.flatMap(
profile => {
console.log('inside success');
console.log(profile);
this.userProfile = <User>profile;
console.log('getProfile has completed');
return Promise.resolve(profile);//<-- this is what needs to be changed
},
error => {
console.log(error)
});