Group
A Group
categorizes and preserves the ordering of structured data.
It allows us to cluster together data from a Collection as an array of item keys
.
// The actual Collection
Collection
data -> [Item('id1'), Item('id2'), Item('id10'), Item('id7'), Item('id5')]
// Group1 which represetns the Collection Items in a particular structure
Group1
value -> ['id1', 'id5', 'id7']
output -> [Item('id1'), Item('id5'), Item('id7')]
// Group2 which represetns the Collection Items in another structure
Group2
value -> ['id7', 'id1', 'id10', 'id99']
output -> [Item('id7'), Item('id1'), Item('id10'), Item('id99')]
We instantiate a Group with the help of an existing Collection. By doing so, the Group is automatically bound to the Collection it was created from and has access to its data. A Group can be created during the creation of a Collection in the configuration object.
const MY_COLLECTION = new Collection((collection) =>({
groups: {
groupName: collection.Group([/*initial Items*/])
}
}));
// or just with the name
const MY_COLLECTION_2 = new Collection({
groups: ['groupName']
});
Or dynamically, after the Collection has been instantiated.
const MY_GROUP = MY_COLLECTION.createGroup("groupName", [/*initial Items*/]);
We can add any number of Groups to the Collection,
and the Collection won't lose its redundancy.
This is because a Group only caches the Item values
based on the array of item keys
it represents,
to avoid unnecessary recomputations.
However, it does not manage or store these Items,
as this is the job of the Collection.
MY_GROUP.output; // Cached Item values
As you can see, the cached Item values are not stored in the value
property.
Instead, they are stored in the output
property.
The value
property represents the actual value of the Group
and is used to keep track of the item keys
represented by the Group.
MY_GROUP.value; // Returns [1, 20, 5]
MY_GROUP.output; // Returns (see below)
/* [
{id: 1, name: "frank"},
{id: 20, name: "jeff"},
{id: 5, name: "hans"}
]
*/
The Group Class is an extension of the State Class
and offer the same powerful functionalities as a normal State.
// Undo the latest Group value change
MY_STATE.undo();
// Reset the Group to its intial Value
MY_GROUP.reset();
// Permanently store the Group value in an external Storage
MY_STATE.persist();
Want to learn more about the Group's specific methods? Check out the Group Methods documentation. Most methods we use to modify, mutate and access the Group are chainable.
MY_GROUP.add(1).persist().remove(2).reset().undo();
๐ช default
Groupโ
By default, each collected data object is added to the default
Group,
representing the default Collection pattern.
// Returns default Group of the Collection
const DEFAULT_GROUP = MY_COLLECTION.getDefaultGroup();
// Returns all collected Item values of the Collection
DEFAULT_GROUP.output;
๐จ Use caseโ
For example, we can use a Group to cluster a Post Collection into 'User Posts' of the different users.
// Add userA, userB to the USERS Collection
USERS.collect([userA, userB]);
// Add userA posts and cluster it by the userA id
POSTS.collect(userA.posts, userA.id);
// Add userB posts and cluster it by the userB id
POSTS.collect(userB.posts, userB.id);
// Returns '[1, 2, 6]' (userA posts)
POSTS.getGroup(userA.id).value;
// Returns '[3, 10, 20]' (userB Posts)
POSTS.getGroup(userB.id).value;
// Returns '[1, 2, 3, 4, 5, 6, 10, ..]' (all posts)
POSTS.getDefaultGroup().value;
In the above code snippet, we have two Collections, one for users and another for posts. We can collect posts specific to a user and automatically group them by the user's id.
โณ๏ธ Sandboxโ
Test the Group yourself. It's only one click away. Just select your preferred Framework below.
๐ญ Propsโ
MY_COLLECTION.createSelector(initialItems, config);
initialItems
โ
The itemKeys
of the Items that the Group represents.
const MY_GROUP = MY_COLLECTION.createGroup([1, 2, 3]);
MY_GROUP.value; // Returns '[1, 2, 3]'
config
โ
Beside the initial รฎtemKeys
a Group
takes an optional configuration object.
MY_COLLECTION.createGroup([1, 2, 3], {
key: "myGroup",
});
Here is a Typescript Interface for quick reference. However, each property is explained in more detail below.
export interface GroupConfigInterface {
key?: GroupKey;
isPlaceholder?: boolean;
}
key
โ
The optional property key/name
should be a unique string/number
to identify the Group later.
MY_COLLECTION.createGroup([1, 2, 3], {
key: "myKey"
});
We recommend giving each Group a unique key
since it has only advantages:
- helps us during debug sessions
- makes it easier to identify the Group
- no need for separate persist Key
Type | Default | Required |
---|---|---|
string \| number | undefined | No |
isPlaceholder
โ
warning
This property is mainly thought for the internal use.
Defines whether the Group is a placeholder
.
const MY_GROUP = createGroup([1, 2, 3], {
isPlaceholder: true
});
MY_GROUP.exists(); // false
Groups are placeholder
when AgileTs needs to hold a reference to them,
even though they aren't instantiated yet.
This can be the case if we use the getGroupWithReference()
method,
which returns a placeholder
Group if the Group we are looking for doesn't exist yet.
const myGroup = useAgile(MY_COLLECTION.getGroupWithReference("group1")); // Causes rerender if Group got created
const myGroup2 = useAgile(MY_COLLECTION.getGroup("group2")); // Doesn't causes rerender if Group got created
This reference is essential to rerender the Component, whenever the Group got instantiated.
Type | Default | Required |
---|---|---|
boolean | false | No |
๐ฆ Typescriptโ
The Group Class
is almost 100% typesafe.