Les Observables occupent une place très importante dans le framework d'Angular, et nous permettent de créer des fonctionnalités très avancées et complexes beaucoup plus facilement. Il est donc essentiel de maîtriser la manipulation de ces Observables. Cette manipulation se fait avec les opérateurs.
Il existe deux types principaux d'opérateurs :
les opérateurs bas niveau – ces opérateurs touchent aux émissions directement, généralement pour transformer ou filtrer ces émissions, et sont le sujet de ce chapitre ;
les opérateurs haut niveau – ces opérateurs touchent à l'Observable lui-même, et nous en parlerons dans le prochain chapitre.
Avant de plonger dans les opérateurs eux-mêmes, regardons comment on branche des opérateurs à un Observable.
Branchez le tuyau
Pour appliquer des opérateurs à un Observable, on les passe, dans l'ordre, à une méthode qui s'appelle pipe()
:
const modifiedObservable$ = originalObservable$.pipe(
firstOperator(),
secondOperator(arguments),
thirdOperator
);
Vous créez un nouvel Observable en branchant un "tuyau" à un autre Observable et en y ajoutant les opérateurs que vous voulez y ajouter. Le concept de "tuyau", pipe, en anglais, est très utile : chaque émission de l'Observable traverse le tuyau et donc les opérateurs dans l'ordre.
Regardons un exemple concret.
Transformez les émissions
Le premier opérateur que vous allez utiliser est l'opérateur map()
qui permet de transformer les émissions d'un Observable. Utilisons notre Observable interval$
pour un premier exemple simple :
this.interval$ = interval(1000).pipe(
map(value => value * 10)
);
On passe donc une fonction à l'opérateur map()
qui définit la transformation à effectuer. Ici, on multiplie chaque émission par 10.
Essayons quelque chose d'un peu plus complexe :
this.interval$ = interval(1000).pipe(
map(value => value % 2 === 0 ?
`Je suis ${value} et je suis pair` :
`Je suis ${value} et je suis impair`
)
);
Mais ça ne compile pas ! Pourquoi ? Parce qu'on a dit que interval$
allait émettre des number
, et ici on lui demande d'émettre une string
! C'est bien l'émission finale qui définit le type de l'Observable global. Modifiez donc le type d' interval$
:
interval$!: Observable<string>;
Ainsi l'application compile et donne :
Pendant la suite du cours, vous serez amenés à utiliser l'opérateur map()
à plusieurs reprises.
Filtrez les émissions
L'opérateur filter()
permet de filtrer les émissions, laissant passer uniquement celles qui vous intéressent. Importez-le depuis rxjs/operators
et ajoutez-le à interval$
:
this.interval$ = interval(1000).pipe(
filter(value => value % 3 === 0),
map(value => value % 2 === 0 ?
`Je suis ${value} et je suis pair` :
`Je suis ${value} et je suis impair`
)
);
Ainsi, on filtre toutes les émissions de l'Observable de base qui ne sont pas divisibles par 3. Ces émissions sont ensuite transformées comme avant en chaîne de caractères.
Créez des effets secondaires
En programmation réactive, un effet secondaire est une fonction qui fait quelque chose avec les émissions d'un Observable sans les modifier. Pour ajouter un effet secondaire à un Observable, on utilise l'opérateur tap()
.
Créez d'abord la méthode qui sera appelée par votre effet secondaire :
logger(text: string): void {
console.log(`Log: ${text}`);
}
Maintenant, en important tap
depuis rxjs/operators
, ajoutez l'opérateur à interval$
:
this.interval$ = interval(1000).pipe(
filter(value => value % 3 === 0),
map(value => value % 2 === 0 ?
`Je suis ${value} et je suis pair` :
`Je suis ${value} et je suis impair`
),
tap(text => this.logger(text))
);
Avec ça, dans la console, vous avez :
En résumé
Les opérateurs sont passés à la fonction
pipe()
des Observables ;L'opérateur
map()
permet de transformer les émissions d'un Observable ;L'opérateur
filter()
permet de filtrer les émissions d'un Observable ;L'opérateur
tap()
permet d'ajouter des effets secondaires à un Observable.
Passons maintenant aux opérateurs haut niveau – rendez-vous au chapitre suivant !