MCPcopy Create free account
hub / github.com/angular/angular / FetchBackend

Class FetchBackend

packages/common/http/src/fetch.ts:74–438  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

72 */
73@Service()
74export class FetchBackend implements HttpBackend {
75 // We use an arrow function to always reference the current global implementation of `fetch`.
76 // This is helpful for cases when the global `fetch` implementation is modified by external code,
77 // see https://github.com/angular/angular/issues/57527.
78 private readonly fetchImpl =
79 inject(FetchFactory, {optional: true})?.fetch ?? ((...args) => globalThis.fetch(...args));
80 private readonly ngZone = inject(NgZone);
81 private readonly destroyRef = inject(DestroyRef);
82 private readonly maxResponseSize = inject(HTTP_FETCH_MAX_RESPONSE_SIZE);
83
84 handle(request: HttpRequest<any>): Observable<HttpEvent<any>> {
85 return new Observable((observer) => {
86 const aborter = new AbortController();
87 let done = false;
88 const wrappedObserver: Observer<HttpEvent<any>> = {
89 next: (val) => {
90 if (val.type === HttpEventType.Response) {
91 done = true;
92 }
93 observer.next(val);
94 },
95 error: (err) => {
96 done = true;
97 observer.error(err);
98 },
99 complete: () => {
100 done = true;
101 observer.complete();
102 },
103 };
104
105 this.doRequest(request, aborter.signal, wrappedObserver).then(noop, (error) =>
106 wrappedObserver.error(new HttpErrorResponse({error})),
107 );
108
109 let timeoutId: ReturnType<typeof setTimeout> | undefined;
110 if (request.timeout) {
111 // TODO: Replace with AbortSignal.any([aborter.signal, AbortSignal.timeout(request.timeout)])
112 // when AbortSignal.any support is Baseline widely available (NET nov. 2026)
113 timeoutId = this.ngZone.runOutsideAngular(() =>
114 setTimeout(() => {
115 if (!aborter.signal.aborted) {
116 aborter.abort(new DOMException('signal timed out', 'TimeoutError'));
117 }
118 }, request.timeout),
119 );
120 }
121
122 return () => {
123 if (timeoutId !== undefined) {
124 clearTimeout(timeoutId);
125 }
126 if (!done && !aborter.signal.aborted) {
127 aborter.abort();
128 }
129 };
130 });
131 }

Callers

nothing calls this directly

Calls 2

injectFunction · 0.90
fetchMethod · 0.45

Tested by

no test coverage detected