Hello,
How can I use ABP's hookToQuery() pattern with an InputSignal in Angular so that whenever its value is changed, the table should refresh itself? I could not see an example in tutorial documents. What should be the approach in the example below?
Thanks.
export class EagleComponent implements OnInit {
eagleId = input.required<string>();
public readonly listService = inject(ListService<GetListEagleDto>);
private eagleService = inject(EagleService);
eagles: PagedResultDto<EagleDto> | null = null;
ngOnInit(): void {
this.createQueryHook();
}
createQueryHook() {
const req = (query) => this.eagleService.getList({
...query,
eagleId: this.eagleId()
});
this.listService.hookToQuery(req).subscribe(res => {
this.eagles = res;
});
}
query() {
this.listService.get();
}
}
4 Answer(s)
-
0
ListService.hookToQuery(...)runs its stream when you calllistService.get(). So to refresh the table when anInputSignalchanges, the ABP-side pattern is: keep your hookToQuery as-is, and triggerlistService.get()from a signaleffect()whenever the input changes.
import { Component, DestroyRef, effect, inject, OnInit, input, untracked } from '@angular/core'; import { ListService, PagedResultDto } from '@abp/ng.core'; import { EagleDto, GetListEagleDto, EagleService } from '@proxy/eagles'; @Component({ // ... }) export class EagleComponent implements OnInit { eagleId = input.required<string>(); public readonly listService = inject(ListService<GetListEagleDto>); private readonly eagleService = inject(EagleService); eagles: PagedResultDto<EagleDto> | null = null; ngOnInit(): void { const req = (query) => this.eagleService.getList({ ...query, eagleId: this.eagleId(), // read signal here (fine) }); this.listService.hookToQuery(req).subscribe(res => { this.eagles = res; }); // Re-run query whenever eagleId changes effect(() => { this.eagleId(); // track changes untracked(() => this.listService.get()); // trigger refresh without tracking ListService internals }); } }- Notes:
untrackedprevents the effect from accidentally re-running due to anythinglistService.get()touches internally; the only dependency will beeagleId().- You don’t need a separate
query()method anymore unless you also want a manual refresh button.
Sources:
- https://abp.io/docs/10.6/framework/ui/angular/list-service
- https://abp.io/docs/latest/framework/ui/angular/list-service
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
hookToQueryre-runs its request callback only when theListService's internal query stream emits (paging, sorting, filter changes or alistService.get()call), so it doesn't react to signal changes by itself. The way to connect them is to triggerlistService.get()from aneffectwhenevereagleIdchanges:import { effect, untracked } from '@angular/core'; constructor() { effect(() => { this.eagleId(); untracked(() => this.listService.get()); }); }You can keep the rest of your component as-is. The request callback reads
this.eagleId()on every run, so each refresh picks up the current value. One thing to watch out for: create the effect in the constructor —ngOnInitis not an injection context, soeffectthere throws NG0203 unless you pass an injector.With
ListService's default 300ms debounce, there is also no duplicate request on the first load — the initialget()fromListServiceand the effect's first run are debounced into a single request.Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)