Reputation: 2344
How can I make sure the tap operator is called even if a subscription is unsubscribed? Imagine the following:
function doUpdate() {
return this.http.post('somewhere', {})
.pipe(
tap(res => console.log(res))
)
}
const sub = doUpdate().subscribe(res => /* do something with res */);
setTimeout(() => sub.unsubscribe(), 1000)
In this case, I just want to prevent the subscribe action from being executed, yet I want to make sure the console log is fired, even if the request took longer than 1000 milliseconds to execute (and in this particular case, I don't even want the POST to be cancelled either).
Upvotes: 2
Views: 1326
Reputation: 3495
In Rxjs 7.4 tap now has three more subscribe handlers, so you can use it to get notified on subscribe, unsubscribe and finalize:
So you can do:
const subscription = subject
.pipe(
tap({
subscribe: () => results.push('subscribe'),
next: (value) => results.push(`next ${value}`),
error: (err) => results.push(`error: ${err.message}`),
complete: () => results.push('complete'),
unsubscribe: () => results.push('unsubscribe'),
finalize: () => results.push('finalize'),
})
)
.subscribe();
Upvotes: 1
Reputation: 11345
use finalize() operator, although that will also get called when observable is completed
function doUpdate() {
return this.http.post('somewhere', {})
.pipe(
finalize(() => console.log(res))
)
}
some code to demonstrate the idea: https://stackblitz.com/edit/rxjs-playground-test-m9ujv9
Upvotes: 2
Reputation: 21638
Unsubscribing from a http request will definitely cancel the request, you could try shareReplay
function doUpdate() {
return this.http.post('somewhere', {})
.pipe(
tap(res => console.log(res)),
shareReplay()
)
}
and if that doesn't work the passing the result into a subject
function doUpdate() {
const subject = new Subject();
this.http.post('somewhere', {})
.pipe(
tap(res => console.log(res))
).subscribe(subject);
return subject;
}
Upvotes: 0