I am using a signal store in my application to manage the state related to projects and sites. Here is my current implementation:
interface State {
selectedProject: Project | null,
selectedSite: Site | null,
projects: Project[],
sites: Site[],
}
export const Store = signalStore(
withState<State>({
selectedProject: null,
selectedSite: null,
projects: [],
sites: []
}),
withMethods(state => {
const sitesService = inject(SitesService);
const projectsService = inject(ProjectsService);
return {
loadSites: async () => {
const sites = await sitesService.getSites();
patchState(state, { sites });
},
loadProjectsBySiteId: async (siteId: number) => {
const projects = await projectsService.getProjectsBySiteId(siteId);
patchState(state, { projects });
},
setSelectedSite: (selectedSite: Site) => {
patchState(state, { selectedSite, selectedProject: null });
},
setSelectedProject: (selectedProject: Project) => {
patchState(state, { selectedProject });
}
};
}),
withHooks({
onInit({ loadSites }) {
loadSites();
}
})
);
I need to load the projects whenever selectedSite
changes. Currently, I am not sure about the best way to achieve this in my signal store setup.
I am either considering to use the withComputed in some way, or to do it inside the setter setSelectedSite (trigger here a fetch or ...)
What is the best practice for loading projects based on the selectedSite
change in this context?
Basically this was my solution. I am not very sure If the updating of a store Value in an effect could potentially create Problems...
withHooks({
onInit({ loadSites, selectedSite, loadProjectsBySiteId }) {
loadSites();
effect(() => {
const selectedSiteId = selectedSite()?.id;
if(selectedSiteId) {
loadProjectsBySiteId(selectedSiteId);
}
}, { allowSignalWrites: true });
}