I have a larger application (Aurelia, Firebase, Typescript) and as a learning path, I would like to start using aurelia’s state management, but I still struggle with some basic.
If I have a multiple Services (CustomerService, SchoolService, ParentService, … ) and each service does it’s own data manipulation (crud, etc.), how do I go about creating a store? Should the store look like this:
I think there is no silver bullet to this. Recently I’ve talked with few people about how Vuex approaches this with Modules, but that pumps up the whole system with yet another concept.
Looking at redux and the likes, you’d typically design your app to work with one store. So everything that is handled, comes into one state. The reason for one state has been repeated over and over again, with values like Single-source-of-truth, easier history navigation etc.
So yes, in your case I’d stuff all in the state, as depicted above by you.
Now I agree that this might become a bit unhandy, as lets say the CustomerService is only interested in the customer prop but doesn’t care about the others. So to avoid that you can simply pluck your streamed state to exactly the part you’re interested in.
With the @connectTo decorator that would look like the following:
So this would already help you with only seeing the slice of the state you’re interested at.
When it comes to heavier work on top of a large state, you can get some ideas from flattening/normalizing your state.
To sum up … Aurelia-Store uses RxJS, so it uses streams. That means you can take whatever advantage of the vast eco-system of RxJS operators that you like, to create streams or subscriptions in such a way you need.
So the idea is really to keep the state of the whole application in one place. That was the part I struggled to digest. I’ve read more about redux and state management and everything is starting to make a more sense. Thank you for your reply!
I have similar issue but then I still haven’t decided which way to go. I just keep it stupid simple for now, but not sure if it’s the right way without considering performance issue
So, I have one class where it holding my app state
import {Store} from 'aurelia-store'
export class AppStore {
static inject = [Store];
constructor(store) {
this.store = store;
// here is the magic lol
this.storeSubscriber = this.store.state.subscribe((state) => {
this.instance = state
);
}
}
And I inject the AppState class to my components / services
import {AppStore} from './app-store'
export class MyComponent {
static inject = [AppStore];
constructor(appStore) {
this.appStore = appStore;
// then I can use this.appStore.instance[propName] to get the state
}
}
@zewa666 could you help with your opinion about my approach?
Your approach is fine to start with. Often you have a service oriented architecture, where your approach fits well in the beginning. In the long run I would personally structure my components to take state slices only via custom attributes which are bound all from the top App component.
So all data would get to component only via bound attributes? Does it mean that the main app component would get the data prior to child component and update it accordingly? Do you have an sample app with this aproach? Thank you!