My base requirement is to start and stop the Resource API
at will. By start/stop I mean to start/stop listening for signal changes (signals provided within the request
callback).
By start I mean, the resource API is supposed to act normally, eagerly load the request based on the input signal and react to signal changes.
By stop I mean, do not have any value and remain idle
, even when there are new signal changes from the request signals.
Below is my minimal reproducible code along with a working stackblitz for debugging:
<div>
<div>
Resource Request triggers:
</div>
<div>
<input [(ngModel)]="id" type="number"/>
</div>
</div>
<div>
@if(![rs.Loading, rs.Reloading].includes(rxResource.status())) {
{{rxResource.value() | json}}
} @else{
Loading...
}
</div>
<hr/>
<div>
@if(![rs.Loading, rs.Reloading].includes(resource.status())) {
{{resource.value() | json}}
} @else{
Loading...
}
</div>
<hr/>
<div>
<button (click)="start()">Start Listening</button>
<button (click)="stop()">Stop Listening</button>
</div>
export class App {
id = signal(1);
rs = ResourceStatus;
http = inject(HttpClient);
resourceRequest = (): ResourceRequest => {
return {
id: this.id(),
};
};
resource: ResourceRef<any> = resource<ResourceRequest, any>({
request: this.resourceRequest,
loader: ({ request: { id }, abortSignal }) => {
return fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, {
signal: abortSignal,
}).then((res: any) => res.json());
},
});
rxResource: ResourceRef<any> = rxResource<ResourceRequest, any>({
request: this.resourceRequest,
loader: ({ request: { id } }) => {
return this.http.get<any>(
`https://jsonplaceholder.typicode.com/todos/${id}`
);
},
});
start() {
// how to start the resource API programmatically.
}
stop() {
// how to stop the resource API programmatically.
}
It's not about stop/starting a resource, it's about having a having a state that represents the parameters of a loader that should pull the async data.
If resource were meant to be enabled/disabled they would have dedicated methods for that.
Either you have all your request parameters and you can return them.
request: () => {
if(myState().param1 && myState().param2) {
return { param1: myState().param1, param2: myState.param2 }
}
return undefined // I don't have all my params
}
or you don't and you return undefined
, telling the resource that you don't have the necessary data to perform the async request.