I'm trying to implement Rxjs based state management in Angular, but I've been stuck with sharing the state with components.
Here it is my implementation:
private readonly _policies = new BehaviorSubject(<Policy[]>([]));
readonly policies$ = this._policies.asObservable();
get policies(): Policy[] {
return this._policies.getValue();
}
set policies(val: Policy[]) {
this._policies.next(val);
}
async fetchAll() {
this.policies = await this._policyService.index().toPromise();
}
async delete(policyId: string): Promise<any> {
try {
await this._policyService
.destroy(policyId)
.toPromise();
this.policies = this.policies.filter(policy => policy.id !== policyId);
} catch (e) {
}
}
In shell component I just pass the variables to the child component;
<policy-list
[policies]="_policyStoreService.policies$ | async"
(deletePolicyEmitter)="_policyStoreService.delete($event)">
FetchAll is called in resolver;
resolve(route: ActivatedRouteSnapshot): any {
return this._leavePolicyStoreService.fetchAll();
}
I want to keep _policyStoreService.policies$
as shared observable in my components. So, when I add/delete/update policy push that change to all subscribers. Use the service also in lazy loading modules, and fetch the data from api only if it is not loaded before.
The question is how do I use this store service as a singleton service. I've already removed from lazy loading module's providers and insert @Injectable({providedIn: 'root'}) to its metada. But still getting the injection error.
Solution: I just added {providedIn: 'root'} metadata to service dependencies.
Subject
in a service is a reasonable way of handling state. Here is an article describing this pattern. If you want help with a specific issue you are having, I suggest a StackBlitz that shows the issue.