web-dev-qa-db-fra.com

Comment obtenir la dernière émission Observable

J'ai créé un service Angular qui définit un objet avec des informations utilisateur. Lorsque je change d'utilisateur, le service émet une observable, capturée par certains composants frères pour mettre à jour les informations. Le problème est que la première fois que je configure les données, il n'y a pas encore d'abonné, donc je reçois une valeur indéfinie. J'ai lu des articles sur la conversion de l'observable en "hot" en utilisant publish () ou share () mais je suis assez nouveau pour RxJS et je n'ai toujours pas compris comment cela fonctionne à 100%, alors je suis un peu perdu.

Le code de service (la partie pertinente):

getFwcUser() : Observable<FwcUser> {
  return this.subjectFwcUser.asObservable();
}

setFwcUser(user : FwcUser) {
  this.fwcUser = user;

  this.subjectFwcUser.next(this.fwcUser);
}

REMARQUE: FwcUser est une interface avec certains champs utilisateur. Je lance setFwcUser dans un gestionnaire de boutons pour choisir l'utilisateur.

Le dernier abonné (code composant):

ngOnInit() {
  this.fwcUserService.getFwcUser()
    .subscribe(
      (user : FwcUser) => { console.log('Received: ', user); this.fwcUser = user; }
  );
  [......]
}

Imprime toujours: 'Reçu: non défini'. REMARQUE: le composant est dans un '* ngIf = "fwcUser"', il est donc chargé lorsque j'appelle 'setFwcUser' à partir d'un composant frère.

Comment pourrais-je obtenir ce composant pour lire la valeur perdue?

Aussi, quelqu'un pourrait-il recommander une bonne ressource pour se renseigner sur RxJS pour les débutants? Je lis quelques livres sur Angular4 mais aucun ne l'explique clairement ...

Merci!

4
Fel

BehaviorSubject est la réponse ici. Plutôt qu'un sujet standard (Observable) qui n'émet que des valeurs au fur et à mesure de son entrée, un BehaviorSubject émet la dernière valeur sur subscribe(). Vous pouvez également obtenir la dernière valeur manuellement à l'aide de la méthode BehaviorSubjects getValue().

Une remarque à faire sur le code ci-dessous est que le bloc null dans la déclaration BehaviorSubject représente la valeur initiale de BehaviorSubject lors de l'initialisation. Vous pouvez soit le laisser, soit le pré-renseigner avec une valeur.

Service

EDITED: Corrigé quelques erreurs de frappe.

fwcUser: BehaviorSubject<FwcUser> = new BehaviorSubject<FwcUser>(null);
fwcUser$ = this.fwcUser.asObservable();

// Set the value of the fwcUser
updateFwcUser(user) {
    this.fwcUser.next(user);
}

Composant

// Subscribe to the BehaviorSubject
ngOnInit() {
    this.fwcUserService.fwcUser$.subscribe(_fwcUser => {
        this.fwcUser = _fwcUser
    }
}

// Get the current (previously emitted) value manually
getFwcUser() {
    this.fwcUser = this.fwcUserService.fwcUser.getValue();
}
3
joshrathke

Question? Comment dans le monde gérez-vous la première valeur nulle émise? J'ai un behaviorSubject et quand je m'y abonne, je reçois un null, puis la valeur après. 

Comment puis-je obtenir juste la deuxième valeur.

Mon service

user: BehaviorSubject<User> = new BehaviorSubject(null); // The behavior-roles of the user.

authState: any = null; // The object of the user observed.
loginForm: any = false; // Login Popup
signupForm: any = false; // Signup Popup
customToken: any; // Custom Token Variable
provider: any; // Social Provider Type
loginButton: boolean; // Login Button Hidden Y/N
logoutButton: boolean; // Logout Button Y/N

    constructor(private afAuth: AngularFireAuth,
                private db: AngularFireDatabase,
                private router: Router) {
                // this.afAuth.authState.subscribe((auth) => {
                // this.authState = auth;
                // }); // Old Method

                this.afAuth.authState
                .switchMap(auth => {
                if (auth) {
                    /// signed in
                    const authData = this.db.list<User>('users/' + auth.uid).valueChanges();
                    console.log(authData);
                    return this.db.list<User>('users/' + auth.uid).valueChanges();
                } else {
                    /// not signed in
                    return Observable.of(null);
                }
                })
                // .subscribe(console.log); // check the subscription
                .subscribe((userData) => {
                console.log(userData);
                this.user.next(userData);
                // this.user.next(user);
                // console.log(this.user.next(userData));
                });
            }

My GuardService

return this.auth.user.map(value => {
       const checkValue = _.has(_.get(value, '2'), 'basicUser', true);
       if (checkValue === true) {
         console.log('Route was true');
         return true;
       } else if (checkValue === false) {
        console.log('Route was False');
       }});
1
Kevin Summersill