I am developing an enterprise frontend which is kind of like a CRM for insurances. This is my first big Angular project and thats why I haven't used NGRX until now. Instead I made a StateService for each page like contract-list, contract-details, ... with a stateobject and a behavioursubject to make the state reactive. But now I have to subscribe, unsubscribe and implement an updateState function in each component, that uses this service.
I guess this will be an Antipattern in the long term and it might be time to invest into NGRX. Can you give me your two cents on it and how you would approach state management? Please keep in mind, that I am a bit short in time because the deadline for the first release are two months.
Sorry, I am aware it is an opinionated question, but I am hoping to get some different ways of doing state management
CodePudding user response:
You didn't include any specific code for your solution but you can get pretty far in mimicking the redux pattern using a simple select / modify function.
@Injectable({ providedIn: 'root' })
export class StateService {
state: StateModel;
stateSubject$: BehaviorSubject<any>;
constructor() {
this.setInitialState();
this.stateSubject$ = new BehaviorSubject<any>(this.state);
}
select(propPath: keyof StateModel | '' = ''): Observable<any> {
let observable: Observable<any> = this.stateSubject$.asObservable();
if (propPath.length > 0) {
propPath.split('.').forEach((prop) => {
observable = observable.pipe(map((state) => state[prop]));
});
}
return observable;
}
modify(modFn: (state: StateModel) => Partial<StateModel>) {
this.state = { ...this.state, ...modFn(this.state) };
this.stateSubject$.next(this.state);
}
setInitialState() {
this.state = {
someProp: { a: 10, b: 20 },
somethingElse: 'Hello world',
};
}
}
usage
// some.component
// select a value from your state
this.somethingElse = state.select('somethingElse');
this.a = state.select('someProp.a');
// modify the state
state.modify((state) => ({ somethingElse: 'Foobar' }));
state.modify((state) => ({ someProp: { a: 310, b: state.someProp.b } }));
You don't have to re-implement any logic as the state modification is merely a callback function which returns a partial object of your state model which overwrites the current state object.
This approach is similar to the Redux pattern, but cuts away all the boilerplate and "safety" of a stable library.