Observable Finally on Subscribe
JavascriptRxjsRxjs5Javascript Problem Overview
According to this artcle, onComplete
and onError
function of the subscribe
are mutually exclusive.
Meaning either onError
or onComplete
events will fire up in my subscribe
.
I have a logic block which needs to be executed whether I receive an error, or I finish my steam of information successfully.
I looked up for something like finally
in python, but all I found is finally
which needs to be attached to the observable I create.
But I want to to do that logic only when I subscribe, and after the stream has ended, whether successfully or with an error.
Any ideas?
Javascript Solutions
Solution 1 - Javascript
The current "pipable" variant of this operator is called finalize()
(since RxJS 6). The older and now deprecated "patch" operator was called finally()
(until RxJS 5.5).
I think finalize()
operator is actually correct. You say:
> do that logic only when I subscribe, and after the stream has ended
which is not a problem I think. You can have a single source
and use finalize()
before subscribing to it if you want. This way you're not required to always use finalize()
:
let source = new Observable(observer => {
observer.next(1);
observer.error('error message');
observer.next(3);
observer.complete();
}).pipe(
publish(),
);
source.pipe(
finalize(() => console.log('Finally callback')),
).subscribe(
value => console.log('#1 Next:', value),
error => console.log('#1 Error:', error),
() => console.log('#1 Complete')
);
source.subscribe(
value => console.log('#2 Next:', value),
error => console.log('#2 Error:', error),
() => console.log('#2 Complete')
);
source.connect();
This prints to console:
#1 Next: 1
#2 Next: 1
#1 Error: error message
Finally callback
#2 Error: error message
Jan 2019: Updated for RxJS 6
Solution 2 - Javascript
The only thing which worked for me is this
fetchData()
.subscribe(
(data) => {
//Called when success
},
(error) => {
//Called when error
}
).add(() => {
//Called when operation is complete (both success and error)
});
Solution 3 - Javascript
I'm now using RxJS 5.5.7 in an Angular application and using finalize
operator has a weird behavior for my use case since is fired before success or error callbacks.
Simple example:
// Simulate an AJAX callback...
of(null)
.pipe(
delay(2000),
finalize(() => {
// Do some work after complete...
console.log('Finalize method executed before "Data available" (or error thrown)');
})
)
.subscribe(
response => {
console.log('Data available.');
},
err => {
console.error(err);
}
);
I have had to use the add
medhod in the subscription to accomplish what I want. Basically a finally
callback after the success or error callbacks are done. Like a try..catch..finally
block or Promise.finally
method.
Simple example:
// Simulate an AJAX callback...
of(null)
.pipe(
delay(2000)
)
.subscribe(
response => {
console.log('Data available.');
},
err => {
console.error(err);
}
)
.add(() => {
// Do some work after complete...
console.log('At this point the success or error callbacks has been completed.');
});