Ich möchte euch heute etwas Bad Practice vorstellen, welche ich schon des öfteren in diversen Projekten angetroffen und auch leider schon selbst implementiert habe.
In einem konkreten Beispiel geht es darum zwei voneinander abhängige HTTP-Requests zu senden und verarbeiten. Es wird das aktuelle Objekt des Benutzers abgefragt und das des Teams.
Die Bad Practice sieht wie folgt aus:
// BAD :(
this.http
.get('https://any-api.url/me')
.subscribe((user: UserModel) => {
this.http
.get('https://any-api.url/team/' + user.teamId)
.subscribe((team: TeamModel) => {
this.userService.setUser(user);
this.teamService.setTeam(team);
// Success
console.log('USER', user);
console.log('TEAM', team);
}, () => {
// Error
});
}, () => {
// Error
});
Es sollte vermieden werden, subscribe
verschachtelt zu verwenden. Dies lässt sich am Besten mit switchMap
lösen.
// GOOD :)
this.http
.get('https://any-api.url/me')
.pipe(
switchMap((user: UserModel) => {
return this.httpClient
.get('https://any-api.url/team/' + user.teamId)
.pipe(
map((team: TeamModel) => {
return {user, team};
}),
);
}),
)
.subscribe(({user, team}: {user: UserModel, team: TeamModel}) => {
this.userService.setUser(user);
this.teamService.setTeam(team);
// Success
console.log('USER', user);
console.log('TEAM', team);
}, () => {
// Error
});
Keine Produkte gefunden.
Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Du unterstützt dadurch meine Arbeit und es entstehen keine Mehrkosten für dich.
Wir haben nun den Vorteil, dass subscribe
nur noch einmal ausgeführt wird und die Daten der Reihe nach, innerhalb der Pipeline, geladen werden. Am Ende erhalten wir den User und das zugehörige Team zurück.
Außerdem besteht nun die Möglichkeit im Falle eines Fehlers, diesen an nur einer, anstatt zwei Stellen zu bearbeiten. Sollte ein Fehler von einem der beiden Requests anders behandelt werden, kann dafür der catchError
Operator verwendet werden.
Es gibt höchstwahrscheinlich noch unzählige andere Möglichkeiten, diesen Anwendungsfall mit RxJS zu lösen. Falls ihr einen Besseren Vorschlag habt, dann schreibt diesen bitte gerne in die Kommentare. Vielen Dank!