Je crée une application angulaire avec RxJS. Dans mon StoreService, je veux avoir un Observable, auquel mes composants peuvent s'abonner. L'Observable
public unreadMessagesCount: Observable
contient la valeur des messages non lus provenant de l'API.
Toutes les 10 secondes, l'appel de l'API doit être effectué et l'observable doit se mettre à jour avec la nouvelle valeur. MAIS si aucun composant n'a d'abonnement sur cette observable, l'interrogation ne doit pas être effectuée. Et lorsque quelqu'un s'abonne, cela doit être fait immédiatement. Pour que les données soient à jour depuis le début.
Existe-t-il une manière élégante de construire cela avec RxJS? Merci d'avance!
4 Réponses :
Vous pouvez travailler avec Subject
ou BehaviorSubject
et timer
:
import { BehaviorSubject, Observable, timer } from 'rxjs'; import { tap } from 'rxjs/operators'; ... export class YourService { value$ = new BehaviorSubject('your initial value'); constructor() { timer(10000).pipe( tap(() => this.loadValue()) ).subscribe(); } loadValue() { callYourAPI().subscribe( value => this.value$.next(value); ); } }
Pas besoin d'un sujet de comportement et de faire un abonnement initial, il suffit d'avoir une observable publique dans le service dont la valeur est le timer ()
observable, chaque fois que les composants ont besoin d'un abonnement, ils s'y abonneront
Ouais tu as raison, ma faute. Réflexion sur un moyen de déclencher également une mannualy de rechargement
Utilisez timer
pour créer une émission observable toutes les N secondes, à partir de M secondes:
pulledData$ = this.interval$.pipe( switchMap(() => this.APICall$) );
Vous pouvez alors déclarer votre appel API:
XXX
Et enfin, créez une observable à partir de ces deux:
APICall$ = this.http.get('...')
Maintenant, à moins que vous ne vous y abonniez, vous n'aurez aucune valeur . Mais une fois que vous y êtes abonné, vous passez un appel API (après 1 ms cependant), et toutes les dix secondes, vous mettez à jour votre appel. N'oubliez pas de vous désinscrire lorsque vous détruisez votre composant!
Vous pouvez utiliser timer
et simplement effectuer périodiquement l'appel asynchrone avec concatMap
. Si vous voulez qu'il émette sans le délai initial, vous pouvez utiliser la syntaxe timer (0, 10000)
:
import { timer } from 'rxjs'; import { concatMap } from 'rxjs/operators'; timer(0, 10000).pipe( concatMap(i => makeHTTPCall(i)), );
Simplement simple, merci! Que doit retourner makeHTTPCall ()?
makeHTTPCall
doit renvoyer un Observable ou Promise.
Vous pouvez utiliser intervalle et switchMap pour créer un observable qui commencera à interroger votre API lorsque vous vous y abonnerez:
unreadMessagesCount$.subscribe(value => ...); unreadMessagesCount$.subscribe(value => ...); unreadMessagesCount$.connect();