How to store a list of items when items can exist in different modules?
One state to items or Multi states to items? I assume there will be a lot of different modules that will store items and the more of these modules, the more I want to move away from one state
One state
class Item {
id: number;
name: string;
location: "equipment" | "magazine" | "shop" // | and other in future...
}
class AppState {
items: Item[];
}
const getItems = (store: Store): Observable<Item[]> => {
return store.select((appStore: AppStore) => appStore.items);
}
const getItemsInEquipment = (store: Store): Observable<Item[]> => {
const items$: Observable<Item[]> = getItems(store);
return items$.pipe(
map(items => items.filter(item => item.location === "equipment"))
);
}
const getItemsInMagazine = (store: Store): Observable<Item[]> => {
const items$: Observable<Item[]> = getItems(store);
return items$.pipe(
map(items => items.filter(item => item.location === "magazine"))
);
}
const getItemsInShop = (store: Store): Observable<Item[]> => {
const items$: Observable<Item[]> = getItems(store);
return items$.pipe(
map(items => items.filter(item => item.location === "shop"))
);
}
or...
Multi states
class Item {
id: number;
name: string;
}
class AppState {
itemsInEquipment: Item[];
itemsInMagazine: Item[];
itemsInShop: Item[];
// | and other in future...
}
const getItemsInEquipment = (store: Store): Observable<Item[]> => {
return store.select((appStore: AppStore) => appStore.itemsInEquipment);
}
const getItemsInMagazine = (store: Store): Observable<Item[]> => {
return store.select((appStore: AppStore) => appStore.itemsInMagazine);
}
const getItemsInShop = (store: Store): Observable<Item[]> => {
return store.select((appStore: AppStore) => appStore.itemsInShop);
}
const getItems = (store: Store): Observable<Item[]> => {
const itemsInEquipment$: Observable<Item[]> = getItemsInEquipment(store);
const itemsInMagazine$: Observable<Item[]> = getItemsInMagazine(store);
const itemsInShop$: Observable<Item[]> = getItemsInShop(store);
return combineLatest([itemsInEquipment$, itemsInMagazine$, itemsInShop$]);
}
What are the advantages and disadvantages of both approaches?
I would suggest a different approach. In NgRx, for example, we would set up a single Entity state for all
Items
, and then simply store arrays of the IDs of theItems
in each list. NGXS Labs has an Entity state adapter that might be worth trying.Basically, you have all of your
Items
stored in an Object, where the keys are theid
field for eachItem
:This allows for direct lookup, and prevents performance losses caused by Array actions.
Then, each of your
itemsInEquipment
,itemsInStore
etc are all simple Arrays ofids
, allowing you to grab them from the Entity state.