angulartypescripttanstackreact-queryangular-signalstanstack

How to update TanStack query parameters with Angular signals?


How can I use query parameters with TanStack Query and Angular signals to be able to have a request like https://my-api/foo?filter=1,2,3?

I've created a service:

@Injectable()
export class FriendsService {
  #baseUrl = inject(BASE_URL)
  #http = inject(HttpClient)
  #query = injectQuery()

  labels$ = signal<Label[]>([])
  labelIds$ = computed(() => {
    return {
      labels:
        this.labels$()
          ?.map((label) => label.id)
          .join(',') || [],
    }
  })

  getEntries(): Result<QueryObserverResult<ListUser[]>> {
    return this.#query({
      enabled: !!this.labelIds$(),
      queryKey: ['friends', this.labelIds$()],
      queryFn: () => firstValueFrom(
          this.#http.get<ListUser[]>(`${this.#baseUrl}/users/friends?labels=${this.labelIds$()}`),
        ),
      retry: 1,
    })
  }
}

Which I then update in my .component.ts file like this

this.friendService.labels$.set([{id: 1, id: 2}])

For what I do understand, the labels$() should change, which then change the labelIds$() which should (but actually doesn't) trigger a reload of the query string with the new filter

Has somebody already implemented it?


Solution

  • If I understand your intent correctly, this should give you what you're looking for. I've left getEntries() in place to match your original code.

    @Injectable()
    export class FriendsService {
      #baseUrl = inject(BASE_URL)
      #http = inject(HttpClient)
      #query = injectQuery(() => ({
          enabled: !!this.labelIds$(),
          queryKey: ['friends', this.labelIds$()],
          queryFn: () => firstValueFrom(
              this.#http.get<ListUser[]>(`${this.#baseUrl}/users/friends?labels=${this.labelIds$()}`),
            ),
          retry: 1,
        }))
    
      labels$ = signal<Label[]>([])
      labelIds$ = computed(() => {
        return {
          labels:
            this.labels$()
              ?.map((label) => label.id)
              .join(',') || [],
        }
      })
    
      getEntries():ListUser[]|undefined{
        return this.#query.data();
      }
    }