1

I'm using Angular 18 with TanStack Angular Query and have a question about handling observables in the queryFn.

In my queryFn, I'm using lastValueFrom() with an HTTP request like this:

queryFn: () => {
        return lastValueFrom(this.#http.get<Array<string>>('/api/tasks'));
    }   

My Question:

Since lastValueFrom automatically unsubscribes once it emits a value, do I need to explicitly add .pipe(takeUntilDestroyed()) or any other cleanup logic for proper resource management?

Additionally, does Angular Query automatically cancel in-flight requests if the component is destroyed or the query is invalidated?

I want to ensure I'm following best practices for both Angular and TanStack Angular Query. Any insights would be greatly appreciated!

1 Answer 1

1

Looking at the documentation, I can find the DestroyRef being used to complete the stream, so .pipe(takeUntilDestroyed()) is not needed.

create-base-query.ts

  effect(() => {
    // observer.trackResult is not used as this optimization is not needed for Angular
    const observer = observerSignal()

    untracked(() => {
      const unsubscribe = ngZone.runOutsideAngular(() =>
        observer.subscribe(
          notifyManager.batchCalls((state) => {
            ngZone.run(() => {
              ...
        ...
      }),
    ),
  )
  destroyRef.onDestroy(unsubscribe)

Looks like the previous in-flight requests are not cancelled by injectQuery, I searched for a possible workaround, but did not find any.

export class SimpleExampleComponent {
  readonly #http = inject(HttpClient);

  readonly query = injectQuery(() => ({
    queryKey: ['repoData'],
    queryFn: ({ signal }) =>
      lastValueFrom(
        this.#http.get<Response>('https://api.github.com/repos/tanstack/query')
      ),
  }));

  reload() {
    this.query.refetch();
  }
}

Set network to 3G and click the refresh button and see the output in network tab.

Stackblitz Demo


Due to availability of signal property, we can use it with fetch API to achieve this behavior.

readonly query = injectQuery(() => ({
  queryKey: ['repoData'],
  queryFn: ({ signal }) =>
    fetch('https://api.github.com/repos/tanstack/query', {
      signal: signal,
    }).then((x) => x.json()),
}));

Stackblitz Demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.