Reputation: 1173
I'm seeing the http request happen - in the Chrome Network tab, and also by using then()
within the fetch promise - with the below code, despite never subscribing to the inner observable (saveCourses$
).
I modified to use from()
rather than fromPromise()
as per the updated rxjs documentation, but the same occurs.
My understanding is that the inner Observable should not run?
ngOnInit() {
this.form.valueChanges.pipe(
filter(() => this.form.valid)
)
.subscribe(changes => {
const saveCourses$ = fromPromise(fetch(`/api/courses/${this.course.id}`, {
method: 'PUT',
body: JSON.stringify(changes),
headers: {
'content-type': 'application/json'
}
}));
});
}
Upvotes: 2
Views: 1712
Reputation: 12879
While it is common for Observable-based interfaces to defer expensive work (like network calls) until they are subscribed, that's not strictly necessarily. Sometimes, a method that returns an Observable will already have done, or begun, a lot of work even before its subscribe method is called. If the Observable does work before its is subscribed, it's often referred to as "hot" (as opposed to "cold" Observables that don't do work unless subscribers are attached). See the "Hot and Cold Observables" section here.
Promise-based interfaces work a lot like "hot" Observables. That is, we expect that the potentially expensive operation will be started as soon as we call the function that gives us the Promise. We learn about the result of the operation when the Promise is resolved, but it will resolve whether or not we actually listen to it (i.e., hook up a "then" handler to the Promise).
In your example, your Observable is created with the fromPromise
method:
fromPromise(fetch(`/api/courses/${this.course.id}`...)
fromPromise works, essentially, by waiting for a Promise to be resolved, and when it is, emitting the Promise's resolved value via a newly-created Observable. The important thing here is that fromPromise
has to call fetch() in order to get the Promise from which the Observable is built. And the act of calling fetch causes the network call to be initiated.
So in this case, but unlike most "typical" uses of Observables for network or other long operations, you needn't call .subscribe() for the operation to be executed. It will execute as soon as fetch
is called, and fetch
is called when the Observable is created, not when subscribed.
Upvotes: 2
Reputation: 1270
Stop using fetch
and use HttpClient
. If you open a console and type fetch('foo')
you will see a net request. It's the invocation before fromPromise
that's the issue.
Upvotes: 0