Skip to content

Commit f8ae27e

Browse files
committed
Use tracking to fix some subtle bugs
1 parent 99b6d01 commit f8ae27e

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

packages/angular-query-experimental/src/create-base-query.ts

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { DestroyRef, NgZone, PendingTasks, computed, effect, inject, linkedSigna
22
import { QueryClient, notifyManager, shouldThrowError, } from '@tanstack/query-core'
33
import { signalProxy } from './signal-proxy'
44
import { injectIsRestoring } from './inject-is-restoring'
5-
import type { DefaultedQueryObserverOptions, QueryKey, QueryObserver, } from '@tanstack/query-core'
5+
import type {
6+
DefaultedQueryObserverOptions,
7+
QueryKey,
8+
QueryObserver,
9+
QueryObserverResult,
10+
} from '@tanstack/query-core'
611
import type { CreateBaseQueryOptions } from './types'
712

813
/**
@@ -54,6 +59,43 @@ export function createBaseQuery<
5459
return defaultedOptions
5560
})
5661

62+
const trackObserverResult = (
63+
result: QueryObserverResult<TData, TError>,
64+
notifyOnChangeProps?: DefaultedQueryObserverOptions<
65+
TQueryFnData,
66+
TError,
67+
TData,
68+
TQueryData,
69+
TQueryKey
70+
>['notifyOnChangeProps'],
71+
) => {
72+
if (!observer) {
73+
throw new Error('Observer is not initialized')
74+
}
75+
76+
const trackedResult = observer.trackResult(result)
77+
78+
if (!notifyOnChangeProps) {
79+
autoTrackResultProperties(trackedResult)
80+
}
81+
82+
return trackedResult
83+
}
84+
85+
const autoTrackResultProperties = (
86+
result: QueryObserverResult<TData, TError>,
87+
) => {
88+
for (const key of Object.keys(result) as Array<
89+
keyof QueryObserverResult<TData, TError>
90+
>) {
91+
if (key === 'promise') continue
92+
const value = result[key]
93+
if (typeof value === 'function') continue
94+
// Access value once so QueryObserver knows this prop is tracked.
95+
void value
96+
}
97+
}
98+
5799
const createOrUpdateObserver = (
58100
options: DefaultedQueryObserverOptions<
59101
TQueryFnData,
@@ -94,7 +136,11 @@ export function createBaseQuery<
94136
ngZone.onError.emit(state.error)
95137
throw state.error
96138
}
97-
resultSignal.set(state)
139+
const trackedState = trackObserverResult(
140+
state,
141+
observer!.options.notifyOnChangeProps,
142+
)
143+
resultSignal.set(trackedState)
98144
})
99145
}),
100146
)
@@ -108,7 +154,9 @@ export function createBaseQuery<
108154
source: defaultedOptionsSignal,
109155
computation: () => {
110156
if (!observer) throw new Error('Observer is not initialized')
111-
return observer.getOptimisticResult(defaultedOptionsSignal())
157+
const defaultedOptions = defaultedOptionsSignal()
158+
const result = observer.getOptimisticResult(defaultedOptions)
159+
return trackObserverResult(result, defaultedOptions.notifyOnChangeProps)
112160
},
113161
})
114162

packages/angular-query-experimental/src/inject-mutation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ export function injectMutation<
124124

125125
effect(
126126
(onCleanup) => {
127-
// observer.trackResult is not used as this optimization is not needed for Angular
128127
const observer = observerSignal()
129128
let taskCleanupRef: (() => void) | null = null
130129

0 commit comments

Comments
 (0)