MCPcopy Index your code
hub / github.com/angular/angular / rxResource

Function rxResource

packages/core/rxjs-interop/src/rx_resource.ts:53–136  ·  view source on GitHub ↗
(opts: RxResourceOptions<T, R>)

Source from the content-addressed store, hash-verified

51 */
52export function rxResource<T, R>(opts: RxResourceOptions<T, R>): ResourceRef<T | undefined>;
53export function rxResource<T, R>(opts: RxResourceOptions<T, R>): ResourceRef<T | undefined> {
54 if (ngDevMode && !opts?.injector) {
55 assertInInjectionContext(rxResource);
56 }
57 return resource<T, R>({
58 ...opts,
59 loader: undefined,
60 stream: (params) => {
61 let sub: Subscription | undefined;
62
63 // `abort` can fire synchronously while the subscription is not initialized yet.
64 // Use this flag to unsubscribe immediately once `sub` exists.
65 let aborted = false;
66
67 // Start off stream as undefined.
68 const stream = signal<ResourceStreamItem<T>>({value: undefined as T});
69 const {resolve, promise} = promiseWithResolvers<Signal<ResourceStreamItem<T>>>();
70 let hasResolved = false;
71
72 function resolveOnce(): void {
73 if (!hasResolved) {
74 hasResolved = true;
75 resolve(stream);
76 }
77 }
78
79 // Track the abort listener so it can be removed if the Observable completes (as a memory
80 // optimization).
81 const onAbort = () => {
82 aborted = true;
83 sub?.unsubscribe();
84 // Remove the listener immediately since unsubscribe won't trigger the subscription's
85 // error/complete handlers. This ensures the promise resolves and PendingTask is released.
86 params.abortSignal.removeEventListener('abort', onAbort);
87 // Resolve the promise with the current stream state if it hasn't been resolved yet.
88 // This ensures the PendingTask created for this request is released.
89 resolveOnce();
90 };
91 params.abortSignal.addEventListener('abort', onAbort);
92
93 function send(value: ResourceStreamItem<T>): void {
94 stream.set(value);
95 resolveOnce();
96 }
97
98 const streamFn = opts.stream;
99 if (streamFn === undefined) {
100 throw new ɵRuntimeError(
101 ɵRuntimeErrorCode.MUST_PROVIDE_STREAM_OPTION,
102 ngDevMode && `Must provide \`stream\` option.`,
103 );
104 }
105
106 sub = streamFn(params).subscribe({
107 next: (value) => send({value}),
108 error: (error: unknown) => {
109 send({error: encapsulateResourceError(error)});
110 params.abortSignal.removeEventListener('abort', onAbort);

Callers 1

Calls 10

assertInInjectionContextFunction · 0.90
resourceFunction · 0.90
signalFunction · 0.90
promiseWithResolversFunction · 0.90
encapsulateResourceErrorFunction · 0.90
sendFunction · 0.85
addEventListenerMethod · 0.65
subscribeMethod · 0.65
removeEventListenerMethod · 0.65
unsubscribeMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…