web-dev-qa-db-fra.com

RxJS - abonnez-vous une seule fois mais ne complétez pas Observable

imaginez une situation où vous avez un Observable qui contient des données qui changent en temps réel, exemple ci-dessous ...

interface User {
   name: string;
   projectId: string;
   dataThatChangesALotInRealTime: Object;
}

userData: Observable<User>

Cette userData observable est utilisée dans le composant pour afficher certaines données qui changent en temps réel. par exemple.

<p>
{{ (userData | async)?.dataThatChangesALotInRealTime }}
</p>

Maintenant, je veux insérer des données dans la base de données en fonction des données actuelles dans userData observable. Voici la fonction

addToDatabase() {
  let sub = this.userData.subscribe(data => {
     this.exampleDatabase.doc(`test/${data.dataThatChangesALotInRealTime.id}`)
          .add({ test: 'hello'})
     sub.unsubscribe() // <- This
  })
}

Question

Est-ce une bonne solution pour se désinscrire à l'intérieur de l'abonnement pour éviter les insertions multiples dans la base de données? Existe-t-il une manière différente/meilleure de procéder?

Ceci est juste un exemple minimaliste, si vous avez des questions ou que mon explication est mauvaise, faites-le moi savoir dans les commentaires et je mettrai à jour ma question. Je vous remercie

10
Raold

Vous pouvez utiliser l'opérateur first:

this.userData.pipe(first()).subscribe(...);

Cela se terminera automatiquement (et donc se désinscrira) après l'émission de la première valeur.

Notez que vous devez vous assurer qu'il émet au moins une fois avant de terminer, sinon une erreur sera générée. Si vous ne pouvez pas vous en assurer, vous pouvez utiliser take(1) à la place:

this.userData.pipe(take(1)).subscribe(...);

Notez que cela ne modifie pas directement l'observable userData, donc les autres abonnements continueront à émettre malgré tout. En effet, les opérateurs dans rxjs ne modifient pas les observables mais renvoient à la place un nouvel observable.

14
Ingo Bürk