materialize - Objectivation des notifications
L'opérateur materialize convertit les notifications (next, error, complete) d'un Observable en objets Notification. Cela permet de traiter les erreurs et les achèvements ainsi que les valeurs comme des données.
🔰 Syntaxe et comportement de base
Convertit un flux normal en un flux d'objets Notification.
import { of } from 'rxjs';
import { materialize } from 'rxjs';
of(1, 2, 3)
.pipe(materialize())
.subscribe(notification => {
console.log(notification);
});
// Sortie:
// Notification { kind: 'N', value: 1, error: undefined, hasValue: true }
// Notification { kind: 'N', value: 2, error: undefined, hasValue: true }
// Notification { kind: 'N', value: 3, error: undefined, hasValue: true }
// Notification { kind: 'C', value: undefined, error: undefined, hasValue: false }Propriété kind de l'objet Notification :.
'N': next (valeur émise).'E': erreur'C': complete
🌐 Documentation officielle RxJS - materialize
💡 Cas d'utilisation typique.
- Error datamining : traiter les erreurs comme une partie du flux.
- Débogage et journalisation : suivi détaillé des notifications.
- Enregistrement des méta-informations** : enregistrement du moment et de la nature des notifications.
- Combinaison de flux contenant des erreurs** : traiter les erreurs dans plusieurs flux de manière unifiée.
🧪 Exemple de code pratique 1 : traiter les erreurs comme des données
Cet exemple permet de traiter les erreurs qui devraient normalement interrompre un flux comme des données et de continuer.
import { of, throwError, concat } from 'rxjs';
import { materialize, map } from 'rxjs';
// UICréation
const container = document.createElement('div');
document.body.appendChild(container);
const title = document.createElement('h3');
title.textContent = 'materialize - Analyse des données d'erreurs';
container.appendChild(title);
const output = document.createElement('div');
output.style.border = '1px solid #ccc';
output.style.padding = '10px';
container.appendChild(output);
function addLog(message: string, color: string) {
const logItem = document.createElement('div');
logItem.style.padding = '5px';
logItem.style.marginBottom = '3px';
logItem.style.backgroundColor = color;
logItem.textContent = message;
output.appendChild(logItem);
}
// Traitement normal des erreurs (interruption du flux)
addLog('--- Traitement normal des erreurs ---', '#e3f2fd');
concat(
of(1, 2),
throwError(() => new Error('Survenance d'une erreur')),
of(3, 4) // Non exécuté ici
).subscribe({
next: v => addLog(`Valeur: ${v}`, '#c8e6c9'),
error: err => addLog(`❌ Erreur: ${err.message}`, '#ffcdd2'),
complete: () => addLog('Terminé', '#e3f2fd')
});
// materializeUtilisation (suite du flux)
setTimeout(() => {
addLog('--- materializeUtilisation ---', '#e3f2fd');
concat(
of(1, 2),
throwError(() => new Error('Survenance d'une erreur')),
of(3, 4)
)
.pipe(
materialize(),
map(notification => {
if (notification.kind === 'N') {
return `Valeur: ${notification.value}`;
} else if (notification.kind === 'E') {
return `Erreur (données analysées): ${notification.error?.message}`;
} else {
return 'Terminé';
}
})
)
.subscribe({
next: msg => {
const color = msg.includes('Erreur') ? '#fff9c4' : '#c8e6c9';
addLog(msg, color);
},
complete: () => addLog('Flux terminé', '#e3f2fd')
});
}, 1000);- Les erreurs normales interrompent le flux.
- Avec
materialize, les erreurs sont traitées comme des données et le flux continue
🧪 Exemple de code pratique 2 : journalisation pour le débogage
Exemple de sortie de journalisation détaillée de toutes les notifications.
import { interval, throwError } from 'rxjs';
import { materialize, take, mergeMap } from 'rxjs';
// UICréation
const container2 = document.createElement('div');
container2.style.marginTop = '20px';
document.body.appendChild(container2);
const title2 = document.createElement('h3');
title2.textContent = 'materialize - Enregistrement de débogage';
container2.appendChild(title2);
const output2 = document.createElement('div');
output2.style.border = '1px solid #ccc';
output2.style.padding = '10px';
output2.style.maxHeight = '250px';
output2.style.overflow = 'auto';
output2.style.fontFamily = 'monospace';
output2.style.fontSize = '12px';
container2.appendChild(output2);
function addLog2(message: string) {
const now = new Date();
const timestamp = now.toLocaleTimeString('ja-JP', { hour12: false }) +
'.' + now.getMilliseconds().toString().padStart(3, '0');
const logItem = document.createElement('div');
logItem.style.marginBottom = '2px';
logItem.textContent = `[${timestamp}] ${message}`;
output2.appendChild(logItem);
}
interval(500)
.pipe(
take(5),
mergeMap(value => {
// Si la valeur est3Lève une erreur lorsque l'élément
if (value === 3) {
return throwError(() => new Error('Valeur3Erreur dans'));
}
return of(value);
}),
materialize()
)
.subscribe({
next: notification => {
switch (notification.kind) {
case 'N':
addLog2(`[NEXT] value: ${notification.value}`);
break;
case 'E':
addLog2(`[ERROR] ${notification.error?.message}`);
break;
case 'C':
addLog2('[COMPLETE]');
break;
}
},
complete: () => {
addLog2('--- ObserverTerminé ---');
}
});- Journalisation uniforme de tous les types de notification (next, error, complete)
- Suivi de l'ordre dans lequel les notifications se produisent avec des horodatages
- Utile pour le débogage et la surveillance
🆚 Comparaison avec des flux normaux
import { of } from 'rxjs';
import { materialize } from 'rxjs';
// Flux normal
of(1, 2, 3).subscribe({
next: v => console.log('Valeur:', v),
complete: () => console.log('Terminé')
});
// Sortie:
// Valeur: 1
// Valeur: 2
// Valeur: 3
// Terminé
// materializeUtilisation
of(1, 2, 3)
.pipe(materialize())
.subscribe({
next: n => console.log('Notification:', n),
complete: () => console.log('Terminé')
});
// Sortie:
// Notification: Notification { kind: 'N', value: 1, ... }
// Notification: Notification { kind: 'N', value: 2, ... }
// Notification: Notification { kind: 'N', value: 3, ... }
// Notification: Notification { kind: 'C', ... }
// TerminéManipulation d'objets de notification
import { of } from 'rxjs';
import { materialize, map } from 'rxjs';
of(10, 20, 30)
.pipe(
materialize(),
map(notification => {
// NotificationPropriétés de l'objet
return {
kind: notification.kind, // 'N', 'E', 'C'
hasValue: notification.hasValue, // A une valeur ou
value: notification.value, // Valeur (sinext(si l'objet a une valeur)
error: notification.error // Erreur (error(si l'objet a une valeur)
};
})
)
.subscribe(console.log);
// Sortie:
// { kind: 'N', hasValue: true, value: 10, error: undefined }
// { kind: 'N', hasValue: true, value: 20, error: undefined }
// { kind: 'N', hasValue: true, value: 30, error: undefined }
// { kind: 'C', hasValue: false, value: undefined, error: undefined }⚠️ Notes.
1. les erreurs n'interrompent pas le flux
Lorsque l'on utilise materialize, les erreurs sont traitées comme des données et le flux n'est pas interrompu.
import { of, throwError, concat } from 'rxjs';
import { materialize } from 'rxjs';
concat(
of(1),
throwError(() => new Error('Erreur')),
of(2)
)
.pipe(materialize())
.subscribe({
next: n => console.log('Notification:', n.kind),
error: () => console.log('Gestionnaire d'erreur'), // N'est pas appelé
complete: () => console.log('Terminé')
});
// Sortie:
// Notification: N
// Notification: E ← Les erreurs sont égalementnexttraitées comme
// Terminé2. en combinaison avec dematerialize
Les flux transformés avec materialize peuvent être restaurés avec dematerialize.
import { of } from 'rxjs';
import { materialize, dematerialize } from 'rxjs';
of(1, 2, 3)
.pipe(
materialize(),
// Un peu de traitement ici
dematerialize() // Annuler
)
.subscribe(console.log);
// Sortie: 1, 2, 33. impact sur les performances
La génération d'objets de notification entraîne des frais généraux. A n'utiliser qu'en cas de nécessité dans un environnement de production.
📚 Opérateurs associés.
- dematerialize - ramène l'objet Notification à une notification normale.
- tap - Effectue un effet de bord (à des fins de débogage).
- catchError - Gestion des erreurs.
✅ Résumé
L'opérateur materialize convertit une notification en un objet Notification.
- ✅ Peut gérer les erreurs comme des données.
- ✅ Utile pour le débogage et la journalisation.
- ✅ Peut enregistrer des méta-informations sur les notifications.
- ✅ Peut être annulé avec
dematerialize. - ⚠️ Les erreurs n'interrompent plus le flux
- ⚠️ Noter la surcharge de performance