diff --git a/spec/observables/dom/fetch-spec.ts b/spec/observables/dom/fetch-spec.ts index b8346a4f39..da9e6bb4d2 100644 --- a/spec/observables/dom/fetch-spec.ts +++ b/spec/observables/dom/fetch-spec.ts @@ -176,6 +176,25 @@ describe('fromFetch', () => { expect(mockFetch.calls[0].init.signal.aborted).to.be.true; }); + it('should not immediately abort repeat subscribers', () => { + const fetch$ = fromFetch('/foo'); + expect(mockFetch.calls.length).to.equal(0); + expect(MockAbortController.created).to.equal(0); + let subscription = fetch$.subscribe(); + expect(MockAbortController.created).to.equal(1); + expect(mockFetch.calls[0].init.signal.aborted).to.be.false; + + subscription.unsubscribe(); + expect(mockFetch.calls[0].init.signal.aborted).to.be.true; + + subscription = fetch$.subscribe(); + expect(MockAbortController.created).to.equal(2); + expect(mockFetch.calls[1].init.signal.aborted).to.be.false; + + subscription.unsubscribe(); + expect(mockFetch.calls[1].init.signal.aborted).to.be.true; + }); + it('should allow passing of init object', done => { const fetch$ = fromFetch('/foo', {method: 'HEAD'}); fetch$.subscribe({ diff --git a/src/internal/observable/dom/fetch.ts b/src/internal/observable/dom/fetch.ts index b91f8a7405..50c9df010d 100644 --- a/src/internal/observable/dom/fetch.ts +++ b/src/internal/observable/dom/fetch.ts @@ -58,6 +58,7 @@ export function fromFetch(input: string | Request, init?: RequestInit): Observab let abortable = true; let unsubscribed = false; + let perSubscriberInit: RequestInit; if (init) { // If a signal is provided, just have it teardown. It's a cancellation token, basically. if (init.signal) { @@ -72,12 +73,14 @@ export function fromFetch(input: string | Request, init?: RequestInit): Observab init.signal.addEventListener('abort', outerSignalHandler); } } - init = { ...init, signal }; + // init cannot be mutated or reassigned as it's closed over by the + // subscriber callback and is shared between subscribers. + perSubscriberInit = { ...init, signal }; } else { - init = { signal }; + perSubscriberInit = { signal }; } - fetch(input, init).then(response => { + fetch(input, perSubscriberInit).then(response => { abortable = false; subscriber.next(response); subscriber.complete();