I've got an Angular route resolver that has a list of items that gets loaded when my parent route gets loaded, like /users
. I have implemented an Angular resolver that looks more or less like this:
export class UsersResolver implements Resolve<UsersResponse> {
constructor(private usersService: UsersService) {}
resolve(): Observable<UsersResponse> {
return this.usersService.getUsers();
}
}
The child components consume that resolver data in the standard way:
this.route.data.subscribe((data) => {const users = data['users']} )
That works fine...until I perform any action that might change that list (add/delete/alter a user). In that case, I want that resolver to re-run. Well, more specifically, I want the data returned by the resolver to reflect the updated data. I don't think the static options on runGuardsAndResolvers
will do the trick, nor do I think in my case that using the function you can hand to runGuardsAndResolvers
will work in my case, either, because these data changes might not happen in concert with a route change.
I think what I want is something along the lines of this:
export class UsersResolver implements Resolve<UsersResponse> {
constructor(private usersService: UsersService) {}
resolve(): Observable<UsersResponse> {
return this.usersService.users$;
}
}
...where this.usersService.users$
is an rxjs Subject
. That would mean I could update that subject via other means and (I think) the data in the resolver would update, and therefore any child component subscribed to that resolver would get updated. But if that's right, then where do I trigger the initial data fetch, and how do I ensure that my resolver doesn't actually resolve until the initial data fetch completes?
Is this a common issue with a reasonable solution, or am I going about this in the wrong way?
Angular resolver is there just to provide data while navigation and should not do more.
There are many ways to keep data consistent in your application.
One known way is the state management (store), there are many libraries out there like NgRx that offer the necessary tools to keep your data consistent.
Read this article about state management for more details.
Another way is to build your own simple store concept, by creating a singleton service that spread the change of your data. Then you can subscribe and handle the change in your components.
in your user data service:
data$: Observable<any>;
in your component
data: any;
data$.subscribe(data => this.data = data);
somewhere else in other component
data$.next(data);
Other way is to store your data in a singleton store service and access it directly from your components. The service will have the update and get methods to set and update the data in the service.