MCPcopy
hub / github.com/angular/angular / OutputEmitterRef

Class OutputEmitterRef

packages/core/src/authoring/output/output_emitter_ref.ts:33–121  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

31 * @publicAPI
32 */
33export class OutputEmitterRef<T> implements OutputRef<T> {
34 private destroyed = false;
35 private listeners: Array<((value: T) => void) | null> | null = null;
36 private errorHandler = inject(ErrorHandler, {optional: true});
37 private isEmitting = false;
38 private hasNullListeners = false;
39
40 /** @internal */
41 destroyRef: DestroyRef = inject(DestroyRef);
42
43 constructor() {
44 // Clean-up all listeners and mark as destroyed upon destroy.
45 this.destroyRef.onDestroy(() => {
46 this.destroyed = true;
47 this.listeners = null;
48 });
49 }
50
51 subscribe(callback: (value: T) => void): OutputRefSubscription {
52 if (this.destroyed) {
53 throw new RuntimeError(
54 RuntimeErrorCode.OUTPUT_REF_DESTROYED,
55 ngDevMode &&
56 'Unexpected subscription to destroyed `OutputRef`. ' +
57 'The owning directive/component is destroyed.',
58 );
59 }
60
61 (this.listeners ??= []).push(callback);
62
63 return {
64 unsubscribe: () => {
65 const index = this.listeners ? this.listeners.indexOf(callback) : -1;
66 if (index > -1) {
67 // If we try to unsubscribe while an `emit` is happening, we can throw off the loop.
68 // Replace the listener with null so we can clean it up later. Note that it would be
69 // simpler to clone the array when iterating over it, but we're trying to avoid cloning
70 // since unsubscribing from within the event should be fairly uncommon.
71 if (this.isEmitting) {
72 this.hasNullListeners = true;
73 this.listeners![index] = null;
74 } else {
75 this.listeners!.splice(index, 1);
76 }
77 }
78 },
79 };
80 }
81
82 /** Emits a new value to the output. */
83 emit(value: T): void {
84 if (this.destroyed) {
85 console.warn(
86 formatRuntimeError(
87 RuntimeErrorCode.OUTPUT_REF_DESTROYED,
88 ngDevMode &&
89 'Unexpected emit for destroyed `OutputRef`. ' +
90 'The owning directive/component is destroyed.',

Callers

nothing calls this directly

Calls 1

injectFunction · 0.90

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…