Skip to content

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.

ts
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.

ts
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.

ts
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

ts
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

ts
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.

ts
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.

ts
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, 3

3. 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

Publié sous licence CC-BY-4.0.