Cosa sono i BehaviorSubject (articolo)
Subject è un argomento trattato più in dettaglio in uno dei capitolo seguenti.
Tuttavia, vista l'estrema utilità e flessibilità, nei prossimi video inizieremo già ad utilizzarlo, anche se non ne sfrutteremo il vero potenziale.
Un Subject rappresenta uno speciale tipo di Observable e ne esistono 4 tipologie, descritte in seguito.
Nei prossimi esempi utilizzeremo esclusivamente il BehaviorSubject, uno speciale Observable che ci consentirà di emettere dei valori semplicemente invocando la sua funzione next()
, come mostrato di seguito:
BehaviorSubject
rappresenta, infatti, il tipo di Subject
più flessibile e semplice da utilizzare.
Infatti, anche se l'approccio non sarà idiomatico, dato che usciremo leggermente dalle best practice di RxJS e della programmazione funzionale, in cui lo stato dovrebbe essere completamente gestito da funzioni pure, questa tipologia di Subject ci offre un comodissimo metodo, getValue()
, per recuperare l'ultimo valore emesso dall'Observable, anche senza la necessità di sottoscriverlo.
In Angular, può essere banalmente creato un BehaviorSubject
all'interno di un Service per contenere e gestire uno stato.
Dato che il Subject
è un Observable
, potremo:
1) emettere valori nell'Observable tramite il metodo next()
quando necessario
2) sottoscriverlo in diversi componenti e/o servizi allo scopo di rimanere in ascolto di eventuali valori emessi, e reagire di conseguenza.
Creiamo, quindi, un semplice Servizio che contiene un BehaviorSubject
e forniamo un metodo update()
per emettere dei valori nell'Observable:
Creaiamo un componente in cui iniettiamo il servizio e tramite il quale emettiamo dei valori nel BehaviorSubject
(ad es. un count
incrementato al click di un button e che invoca il metodo update()
del servizio):
Di seguito invece due componenti che sottoscrivono il BehaviorSubject
e visualizzano il valore emesso:
1) il primo esempio utilizza il pipe async
fornito da Angular, che sottoscrive l'observable dietro le quinte e visualizza i valori emessi direttamente nel template
2) il secondo esempio invece effettua una sottoscrizione manuale tramite metodo subscribe. In questo caso è necessario annullare manualmente la sottoscrizione quando il componente viene distrutto.
Il pipe async
esegue automaticamente la cancellazione dell'Observable quando un componente viene distrutto
getValue()
Come dicevamo, il BehaviorSubject
espone un metodo chiamato getValue()
che ci permette invece di recuperare il valore attuale dell'Observable in qualunque momento, senza la necessità di sottoscriverlo.
IMPORTANTE: questa modalità di utilizzo del BehaviorSubject
rappresenta una bad practice. Tuttavia risulta molto utile soprattutto ai neofiti o a chi non ha ancora confidenza con l'approccio funzionale reattivo. Quindi, seppur sconsigliato, potrebbe risultare comodo e mi sento in dovere di segnalarlo :)
Possiamo quindi aggiornare il servizio creato in precedente per recuperare i dati dall'Observable tramite il metodo getValue
:
Ora possiamo recuperare il valore dall'Observable semplicemente iniettando il servizio e utilizzando il metodo custom getData()
del servizio:
Creiamo quindi una demo con tutti i componenti sender e receiver e verificare che i valori del sender siano trasmessi a tutti:
Di seguito il source code completo (tutto in un unico file):
SUBJECT e MULTICAST
Come anticipato, quello che ho descritto in questo articolo è un utilizzo limitato del Subject, che esprime il massimo potenziale quando sfruttato per il multicasting.
Di questo argomento parleremo nel capitolo dedicato totalmente al Subject.
Live demo su StackBlitz:
https://stackblitz.com/edit/angular-snippet-subject-to-share-data?file=src/app/app.component.ts