en

RxJS Anti Pattern: Observables ersetzen

Februar 2023

RxJS ist die JavaScript-Implementierung der ReactiveX API. Es macht die Verarbeitung von asynchronen Ereignissen leichter. Bei der Implementierung mit RxJS gibt es ein immer wieder vorkommendes Anti-Pattern das ich hier beschreiben will.

Folgender hypothetischer Fall aus einer Web-Applikation. Eine Komponente zeigt ein paar Datensätze die vom Server ermittelt werden an. Die Datensätze sollen erst geladen werden wenn ein Button gedrückt wird. Der pseudo Angular-Code für die Komponente könnte so aussehen:

import { of } from 'rxjs';

class MyComponent {
    data = of([]);

    onLoadButtonClick(){
      this.data = this.someService.fetchData();
    }
}

Im HTML-Template würde man sich mit der async-Pipe auf data subscriben.

Die oben gezeigte Implementierung ist zwar schlank, hat jedoch den Nachteil, dass die Information woher die Werte von data kommen an zwei Stellen im Code implementiert ist. Dies macht die Suche nach der Quelle der Daten umständlich. Man muss in MyComponent nämlich nach allen Stellen suchen an denen data zugewiesen wird.

Hier nochmal die gleiche Komponente mit einem Load-Trigger.

import { Subject } from 'rxjs';
import { switchMap } from 'rxjs/operators';

class MyComponent {
    private loadTrigger = new Subject();
    
    data = loadTrigger
        .pipe(
            switchMap(() => this.someService.fetchData()),
        );

    onLoadButtonClick(){
      this.loadTrigger.next(undefined);
    }
}

Diese Variante beschreibt bei der Zuweisung von data woher die möglichen Werte kommen. Aus meiner Sicht macht dies das Lesen des Codes deutlich einfacher.

Feedback

Falls der Artikel interessant war oder etwas unklar ist freue ich mich über Fragen per e-Mail an markus.peroebner@gmail.com.