66 * found in the LICENSE file at https://angular.io/license
77 */
88
9- import { assertInInjectionContext , assertNotInReactiveContext , computed , DestroyRef , inject , Injector , signal , Signal , WritableSignal , ɵRuntimeError , ɵRuntimeErrorCode } from '@angular/core' ;
9+ import {
10+ assertInInjectionContext ,
11+ assertNotInReactiveContext ,
12+ computed ,
13+ DestroyRef ,
14+ inject ,
15+ Injector ,
16+ signal ,
17+ Signal ,
18+ WritableSignal ,
19+ ɵRuntimeError ,
20+ ɵRuntimeErrorCode ,
21+ } from '@angular/core' ;
1022import { Observable , Subscribable } from 'rxjs' ;
1123
1224/**
@@ -61,23 +73,27 @@ export interface ToSignalOptions {
6173}
6274
6375// Base case: no options -> `undefined` in the result type.
64- export function toSignal < T > ( source : Observable < T > | Subscribable < T > ) : Signal < T | undefined > ;
76+ export function toSignal < T > ( source : Observable < T > | Subscribable < T > ) : Signal < T | undefined > ;
6577// Options with `undefined` initial value and no `requiredSync` -> `undefined`.
6678export function toSignal < T > (
67- source : Observable < T > | Subscribable < T > ,
68- options : ToSignalOptions & { initialValue ?: undefined , requireSync ?: false } ) : Signal < T | undefined > ;
79+ source : Observable < T > | Subscribable < T > ,
80+ options : ToSignalOptions & { initialValue ?: undefined ; requireSync ?: false } ,
81+ ) : Signal < T | undefined > ;
6982// Options with `null` initial value -> `null`.
7083export function toSignal < T > (
71- source : Observable < T > | Subscribable < T > ,
72- options : ToSignalOptions & { initialValue ?: null , requireSync ?: false } ) : Signal < T | null > ;
84+ source : Observable < T > | Subscribable < T > ,
85+ options : ToSignalOptions & { initialValue ?: null ; requireSync ?: false } ,
86+ ) : Signal < T | null > ;
7387// Options with `undefined` initial value and `requiredSync` -> strict result type.
7488export function toSignal < T > (
75- source : Observable < T > | Subscribable < T > ,
76- options : ToSignalOptions & { initialValue ?: undefined , requireSync : true } ) : Signal < T > ;
89+ source : Observable < T > | Subscribable < T > ,
90+ options : ToSignalOptions & { initialValue ?: undefined ; requireSync : true } ,
91+ ) : Signal < T > ;
7792// Options with a more specific initial value type.
7893export function toSignal < T , const U extends T > (
79- source : Observable < T > | Subscribable < T > ,
80- options : ToSignalOptions & { initialValue : U , requireSync ?: false } ) : Signal < T | U > ;
94+ source : Observable < T > | Subscribable < T > ,
95+ options : ToSignalOptions & { initialValue : U ; requireSync ?: false } ,
96+ ) : Signal < T | U > ;
8197
8298/**
8399 * Get the current value of an `Observable` as a reactive `Signal`.
@@ -104,28 +120,31 @@ export function toSignal<T, const U extends T>(
104120 * @developerPreview
105121 */
106122export function toSignal < T , U = undefined > (
107- source : Observable < T > | Subscribable < T > ,
108- options ?: ToSignalOptions & { initialValue ?: U } ) : Signal < T | U > {
123+ source : Observable < T > | Subscribable < T > ,
124+ options ?: ToSignalOptions & { initialValue ?: U } ,
125+ ) : Signal < T | U > {
109126 ngDevMode &&
110- assertNotInReactiveContext (
111- toSignal ,
112- 'Invoking `toSignal` causes new subscriptions every time. ' +
113- 'Consider moving `toSignal` outside of the reactive context and read the signal value where needed.' ) ;
127+ assertNotInReactiveContext (
128+ toSignal ,
129+ 'Invoking `toSignal` causes new subscriptions every time. ' +
130+ 'Consider moving `toSignal` outside of the reactive context and read the signal value where needed.' ,
131+ ) ;
114132
115133 const requiresCleanup = ! options ?. manualCleanup ;
116134 requiresCleanup && ! options ?. injector && assertInInjectionContext ( toSignal ) ;
117- const cleanupRef =
118- requiresCleanup ? options ?. injector ?. get ( DestroyRef ) ?? inject ( DestroyRef ) : null ;
135+ const cleanupRef = requiresCleanup
136+ ? options ?. injector ?. get ( DestroyRef ) ?? inject ( DestroyRef )
137+ : null ;
119138
120139 // Note: T is the Observable value type, and U is the initial value type. They don't have to be
121140 // the same - the returned signal gives values of type `T`.
122- let state : WritableSignal < State < T | U > > ;
141+ let state : WritableSignal < State < T | U > > ;
123142 if ( options ?. requireSync ) {
124143 // Initially the signal is in a `NoValue` state.
125144 state = signal ( { kind : StateKind . NoValue } ) ;
126145 } else {
127146 // If an initial value was passed, use it. Otherwise, use `undefined` as the initial value.
128- state = signal < State < T | U > > ( { kind : StateKind . Value , value : options ?. initialValue as U } ) ;
147+ state = signal < State < T | U > > ( { kind : StateKind . Value , value : options ?. initialValue as U } ) ;
129148 }
130149
131150 // Note: This code cannot run inside a reactive context (see assertion above). If we'd support
@@ -135,8 +154,8 @@ export function toSignal<T, U = undefined>(
135154 // subscription. Additional context (related to async pipe):
136155 // https://github.com/angular/angular/pull/50522.
137156 const sub = source . subscribe ( {
138- next : value => state . set ( { kind : StateKind . Value , value} ) ,
139- error : error => {
157+ next : ( value ) => state . set ( { kind : StateKind . Value , value} ) ,
158+ error : ( error ) => {
140159 if ( options ?. rejectErrors ) {
141160 // Kick the error back to RxJS. It will be caught and rethrown in a macrotask, which causes
142161 // the error to end up as an uncaught exception.
@@ -150,8 +169,9 @@ export function toSignal<T, U = undefined>(
150169
151170 if ( ngDevMode && options ?. requireSync && state ( ) . kind === StateKind . NoValue ) {
152171 throw new ɵRuntimeError (
153- ɵRuntimeErrorCode . REQUIRE_SYNC_WITHOUT_SYNC_EMIT ,
154- '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.' ) ;
172+ ɵRuntimeErrorCode . REQUIRE_SYNC_WITHOUT_SYNC_EMIT ,
173+ '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.' ,
174+ ) ;
155175 }
156176
157177 // Unsubscribe when the current context is destroyed, if requested.
@@ -170,8 +190,9 @@ export function toSignal<T, U = undefined>(
170190 // This shouldn't really happen because the error is thrown on creation.
171191 // TODO(alxhub): use a RuntimeError when we finalize the error semantics
172192 throw new ɵRuntimeError (
173- ɵRuntimeErrorCode . REQUIRE_SYNC_WITHOUT_SYNC_EMIT ,
174- '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.' ) ;
193+ ɵRuntimeErrorCode . REQUIRE_SYNC_WITHOUT_SYNC_EMIT ,
194+ '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.' ,
195+ ) ;
175196 }
176197 } ) ;
177198}
@@ -196,4 +217,4 @@ interface ErrorState {
196217 error : unknown ;
197218}
198219
199- type State < T > = NoValueState | ValueState < T > | ErrorState ;
220+ type State < T > = NoValueState | ValueState < T > | ErrorState ;
0 commit comments