In my Angular 2 app utilizing Redux (with @ngrx/store), I have structured the store in the following way:
{
modelA: {
ids: [1, 2],
entities: { 1: { name: "name modelA 1" },
2: { name: "name modelA 2" }
}
},
modelB: {
ids: [5, 8],
entities: { 5: { name: "name modelB 5" },
8: { name: "name modelA 8" },
9: { name: "name modelA 9" }
}
}
}
Currently, I have two object types: modelA and modelB. This setup works fine at the moment. However, I am struggling to determine the optimal way to establish a relationship between them, such as representing that modelA has many modelB entries (one-to-many). Is it viable to structure it like this?
modelAmodelB: {
entities: {
1: [5],
2: [8, 9]
}
}
This is positioned at the root of the store, not nested within 'modelA'. While this approach might function, how would I then access the modelB entries from a specific modelA using @ngrx/store methods? For example, composing selector functions:
compose(getModelAEntities(number[]), getModelAModelBRelations(modelA_id: number), getModelAModelBState() );
I can retrieve this data using Observable.combineLatest
Observable
.combineLatest(
this.store.select('contentContents'),
this.store.select('contents'),
(relations: any, contents: any) => {
return relations.entities[1].map( id => {
return contents.entities[id]
})
}
).subscribe( data => {
console.log(data);
})
Yet, I'm uncertain if this method is correct: whenever I update the modelA entities object (e.g., adding a new one), the subscribe() is triggered, but the output remains unchanged because neither the modelA entity nor its associated modelB objects have altered.
Alternatively, I could perform the query like this
export const getModelAModelBs = (id) => {
return state =>
state.select( (s: any) => [s.modelAModelB.entities[id], s.modelB.entities])
.distinctUntilChanged( (prev, next) => {
const new_m = (next[0] || []).map( id => {
return next[1][id];
});
const old_m = (next[0] || []).map( id => {
return prev[1][id];
});
return prev[0] === next[0] && (JSON.stringify(new_m) === JSON.stringify(old_m))
})
.map( ([ids = [], modelBs]) => ids.map( id => modelBs[id]) );
};
//implementing the selector
this.store.let(getModelAModelBs(1)).subscribe( data => {
console.log(data)
})
Still, I am unsure if this represents the optimal approach.