I've been finding myself writing code that looks like this:
class WidgetService {
getWidgets() {
return this.authService.user.pipe( //authService.user is an Observable, that emits the currently authenticated users.
first(user => user!=null), //Make sure a null object isn't coming through
switchMap(user => {
return this.collection.getWhere("widget.ownerId", "==", user.id); //Get all the widgets for that user
})
);
}
}
class WidgetDisplayComponent {
ngOnInit() {
this.widgetService.getWidget().subscribe(widget => this.widget = widget).unsubscribe(); //Subscribe to cause the Observable to pipe, get the widget, then unsubscribe.
}
}
Is this an anti pattern? What should I be doing instead, where the requirements are:
I would say that it is absolutely an anti-pattern, for these reasons:
next
notification.next
notifications - as the subscriber will be synchronously unsubscribed.The pattern would only work for synchronous sources that emit only a single next
notification. In which case, the unsubscribe
is redundant, as the subscriber will be automatically unsubscribed when the source completes.
IMO, if you know that the source emits only one next
notification, you should just omit the unsubscribe
. If you are unsure, you should use either first
or take(1)
at the subscription point.
There is another mechanism that can be used to unsubscribe upon receipt of the first next
notification, but it's not one that I would encourage, as it requires a non-arrow function to be used.
The subscriber is used as the context when the next
handler is invoked, so it's possible to call unsubscribe
on it, like this:
source.subscribe(function (value) {
/* do something with value */
this.unsubscribe();
});