How one can react to changes / perform side-effects when rxResource receives .value() instead of using effect()?
Current approach in component:
constructor() {
this.service.setItemId(1); //setting signal
effect(() => // work with data from async post request
}
in service:
resource$ = rxResource({
request: () => this.itemID$(), // signal
loader: ({ request: id }) => {
return this.http.post('http://');
}
});
As per the requirements, it looks like you want to react to the creation of a new item in the database, but fetching the elements from the database reactively.
In the below code, we trigger the post on change of itemID$
value, I have used a modal
here, this updates the database (PUT
) and then we need to read the data to see if it is updated.
updatePost: ResourceRef<any> = rxResource({
request: () => this.itemID$(), // signal
loader: ({ request: id }) => {
console.log(id);
return this.http.put(`http://localhost:3000/posts/1`, {
id: 1,
title: `from resource - ${id}`,
views: id * 200,
userId: 1,
});
},
});
All you need to do is pass the this.updatePost.value()
signal execution as a input to the request
method, this will trigger the GET api call (getPosts
resource), on each post request from the rxResource
(updatePost
)
getPosts: ResourceRef<any> = rxResource({
request: () => this.updatePost.value(), // signal
loader: (params: ResourceLoaderParams<any>) => {
console.log(params.request);
return this.http.get(`http://localhost:3000/posts`);
},
});
In the below stackblitz, we update a row in the database, then we get the rows, we can see that the row has been updated.
Open new terminal in stackblitz and run npx json-server db.json
.
Then restart the angular server and click on localhost:4200
in the terminal to view the app in the preview and try out the feature.
If you want to derive state from the original signal, then you can use computed
, linkedSignal
to do this.
But since you are doing DOM manipulations based on an API call, the best option is to use effect
to do this, else you can try to achieve the same result without any DOM manipulations.
constructor() {
effect(() => {
// .. DOM manuipulations.
})
}
Ideally you should be able to achieve the same result without DOM manipulations based on signal reactivity, but those details need to be provided for a clear answer.