J'ai examiné un certain nombre de ressources, y compris this , this et this , mais je n'ai pas été en mesure d'atteindre le résultat souhaité.
Tout ce que j'essaie de faire est d'authentifier un utilisateur (en utilisant Firebase) puis une fois authentifié, chargez son profil et stockez-le dans une variable userProfile
avant de charger la page suivante Tableau de bord:
Mon service de connexion:
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');
}
Ma méthode 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)
});
Voici à quoi ressemble une partie du journal:
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
Je peux voir que les méthodes, individuellement, fonctionnent comme prévu. L'utilisateur s'authentifie et le profil est chargé (affiché dans le journal). Le problème réside dans l'événement subscribe pour des raisons que je ne connais pas.
Ok c'est étrange mais j'ai redémarré webpack et il semble avoir résolu le problème.
Voici à quoi ressemble le code et il s'authentifie correctement via la promesse, puis en cas de succès, il charge le profil qui charge ensuite la page suivante:
Ma méthode 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)
)
Et ma méthode 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)
});
}
La pile d'appels:
- L'utilisateur est authentifié
- Abonnez-vous à getProfile et attendez la fin de la méthode ...
- La méthode GetProfile () s'exécute
- Le profil est défini
- La page est redirigée
Je pense que le problème est que getProfile
ne retourne pas vraiment un Observable
.
Vous utilisez flatMap
pour pouvoir enchaîner la séquence observable et renvoyer le profil en tant qu'observable. Mais pour que cela fonctionne, votre rappel à l'intérieur du flatMap
devrait retourner une promesse ou un observable (comme j'ai appris de cette réponse ). Sinon, la chaîne des observables est rompue.
Donc, ce que vous devez probablement faire est quelque chose comme:
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)
});