最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

rxjs - Angular Query Tanstack Query cleanup logic - Stack Overflow

programmeradmin3浏览0评论

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!

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!

Share Improve this question edited Mar 20 at 13:58 Naren Murali 60.4k5 gold badges44 silver badges78 bronze badges asked Mar 19 at 23:08 Eternal SunshineEternal Sunshine 951 silver badge7 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 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/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/repos/tanstack/query', {
      signal: signal,
    }).then((x) => x.json()),
}));

Stackblitz Demo

发布评论

评论列表(0)

  1. 暂无评论