Nested / complex data structure
- Dominant language
- JavaScript
- Stars
- 3.4k
- Forks
- 312
- PR merge metrics
- No merged PRs in 30d
Description
Not specifically to Alt, though. **I am not sure how to structure my stores with this certain situation.**
---
Let's say, we have 3 resources: `Member`, `Group`, and `Conversation`.
`Member` _belongsToMany_ `Conversation`; and vice-versa. (x:x)
`Member` _belongsTo_ `Group` (x:1)
`Group` and `Conversation` has no direct relationship. This is because `Group` is only being used to literally contain a `Member`.
* Note that the API route (`api/groups/` -- which is expected to return all groups also includes its contacts) . It returns something like this:
``` js
{
"id": 1,
// ....
"members": [
{
"id": 4,
// ...
}
]
}
```
---
This is the UI:

This is for creating a Message. A message requires contacts (ids) and a few fields. The Group checkbox is simply used to select all contacts under it. It does not have anything to do with the Message itself.
---
Currently, I just have a `GroupStore` and `SelectedContactStore`. However, I feel that the current setup is a bit tedious, and very prone to errors. I am not sure if this is due to _Immutable_.
Here's an idea of the code:
``` es6
// SelectedMemberStore
import { createStore } from 'alt/utils/decorators';
import Immutable from 'immutable';
import immutable from 'alt/utils/ImmutableUtil';
import alt from '../alt';
import MemberActions from '../actions/MemberActions';
import GroupStore from '../actions/GroupStore';
@createStore(alt)
@immutable
class SelectedMemberstore {
state = {
selected: Immutable.List()
};
constructor() {
this.bindListeners({
// onFetchAll: onFetchAll,
onSelectMember: MemberActions.SELECT_MEMBER,
onSelectGroup: MemberActions.SELECT_GROUP
});
this.exportPublicMethods({
getIndexById: ::this.getIndexById,
isMemberSelected: ::this.isMemberSelected,
isGroupSelected: ::this.isGroupSelected
});
}
isGroupSelected(groupId) {
const group = GroupStore.getById(groupId);
const { selected } = this.state;
const members = group.get('members');
return !members.size ? false : members
.filter(member => selected.indexOf(member.get('id')) !== -1)
.size === members.size;
}
isMemberSelected(id) {
return this.getIndexById(id) !== -1;
}
getIndexById(id) {
return this.state.selected.indexOf(id);
}
onSelectMember(id) {
this.setState({
selected: this.state.selected.push(id)
});
}
onSelectGroup(groupId) {
const group = GroupStore.getById(groupId);
const members = group.get('members');
const { selected } = this.state;
this.setState({
selected: !this.isGroupSelected(group) ? selected.concat(
members.filter(member => (
selected.indexOf(member.get('id')) === -1
)).map(member => member.get('id'))
) : selected.filter(id => (
members.map(member => member.get('id')).indexOf(id) === -1
))
});
}
}
export default SelectedMemberstore;
```
Any better way to do this?
Contributor guide
Assessment
This issue has not been assessed yet.