Ich versuche, einen Benutzerprofil-Service für ein Angular 4-Projekt zu erstellen, und kämpfe ein wenig damit, wie man das beobachtbare Profile-Objekt richtig initialisiert und aktualisiert. Wenn sich der Benutzer derzeit (über Firebase) authentifiziert, übergibt AuthService die Authentifizierungsinformationen des Benutzers an UserProfileService über dessen Funktion initialize(). UserProfileService sucht dann das Benutzerprofil (oder erstellt ein Profil, wenn noch keines vorhanden ist) und füllt eine öffentliche Observable mit dem Profil auf.Eine Observable abonnieren, bevor sie ausgefüllt wurde
Das Problem, das ich renne, ist mit anderen Teilen der Anwendung, die versucht, das beobachtbare Profil zu abonnieren, bevor all das passiert ist. Ich hatte ursprünglich die Initialisierung der beobachtbare über ...
public profileObservable: UserProfile = null;
... was natürlich in einer Folge „subscribe() existiert nicht auf null“ Fehler, also habe ich es zu ...
Dies zumindest wirft keine Fehler, aber alles, das profileObservable abonniert, bevor ich das Firebase-Objekt zugeordnet habe, wird nie aktualisiert.
Kompletter Code für user-profile.service.ts unten. Ich ringe immer noch darum herumzukommen, wie das funktionieren soll, hoffentlich kann jemand etwas Licht geben. Vielen Dank!
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { FirebaseListObservable, FirebaseObjectObservable, AngularFireDatabase } from 'angularfire2/database';
import * as firebase from 'firebase/app';
export class UserProfile {
$exists: Function;
display_name: string;
created_at: Date;
}
@Injectable()
export class UserProfileService {
private basePath: string = '/user-profiles';
private profileRef: FirebaseObjectObservable<UserProfile>;
public profileObservable: Observable<UserProfile> = Observable.of();
constructor(private db: AngularFireDatabase) {
// This subscription will never return anything
this.profileObservable.subscribe(x => console.log(x));
}
initialize(auth) {
this.profileRef = this.db.object(`${this.basePath}/${auth.uid}`);
const subscription = this.profileRef.subscribe(profile => {
if (!profile.$exists()) {
this.profileRef.update({
display_name: auth.displayName || auth.email,
created_at: new Date().toString(),
});
} else subscription.unsubscribe();
});
this.profileObservable = this.profileRef.map(profile => profile);
// This subscription will return the profile once it's retrieved (and any updates)
this.profileObservable.subscribe(profile => console.log(profile));
}
};
Sie werden wahrscheinlich mehr Glück mit 'neuer ReplaySubject (1)' so dass spät Abonnent noch das letzte Benutzerprofil zur Verfügung gestellt erhalten können. –
Brandon