Scenario
We have a Firefly Semantics Slice Entity Store ( EStore<Todo>
) containing Todo Entity instances.
We want to add 2 slices, or live filtered observable collections, to the entity store. One for complete
Todo
instances and one for incomplete
Todo
instances.
We also want to observe the filters as we change the stores state.
Approach
In this demo we will create a Todo
interface for our entities and two Todo
objects that we will use for our initial entity store state and to display how the Slice
instances track modified state.
interface Todo {
gid?: string;
id?: string;
complete: boolean;
title: string;
}const TODO_ID_1 = '1';
const TODO_ID_2 = '2';
const TODO1: Todo = {
id: TODO_ID_1,
complete: false,
title: 'You complete me!'
};const TODO2: Todo = {
id: TODO_ID_2,
complete: true,
title: 'You completed me!'
};let todos: Todo[] = [TODO1, TODO2];
Next we will initialize our store with the todos
array we created and obtain references of the added Todo
instances from the store:
//==============================================
// Constructor Initialize the Store
//==============================================
let store: EStore<Todo> = new EStore<Todo>(todos);//==============================================
// Retrieve Entities from the Store by ID
//==============================================
let t1 = store.findOneByID(TODO_ID_1);
let t2 = store.findOneByID(TODO_ID_2);
Now we are going to add our slices for tracking complete
and incomplete
Todo
instances.
//==============================================
// Add Slices
//==============================================
// Create an enum to key slices
export const enum TodoSlices {
COMPLETE = 'Complete',
INCOMPLETE = 'Incomplete'
}
store.addSlice((todo) => todo.complete, TodoSlices.COMPLETE);
store.addSlice((todo) => !todo.complete, TodoSlices.INCOMPLETE);
We first create an enum
TodoSlices
containing the keys for the slices we will be adding to the store.
We then call store.addSlice
passing in the predicate
function
and the key.
As can be seen for the complete
slice we pass in (todo)=>todo.complete
as the predicate function. And this function will filter out all of the complete Todo
instances. We pass in TodoSlices.complete
as the key.
Next we will take a snapshot of each slice to see what is in it.
const completeTodos = store.getSlice(TodoSlices.COMPLETE).allSnapshot();//console.log(JSON.stringify(completeTodos));const incompletedTodos = store.getSlice(TodoSlices.INCOMPLETE).allSnapshot();//console.log(JSON.stringify(incompletedTodos));
And if we log each snapshot we will see that the completeTodos
one contains the complete Todo
instance, and the incompleteTodos
one contains the incomplete instance.
Next we will observe each the complete Todos slice:
const completeTodos$ = store.getSlice(TodoSlices.COMPLETE).obs;
completeTodos$.subscribe((todos) => {
//console.log('COMPLETED TODOS');
//console.log(JSON.stringify(todos));
});
If we log the todos
array emitted in our subscription function we will see that the array contains the completed
Todo
instance.
We will now post a third Todo
object to the store.
store.post({ id: '3', title: 'Adding a Complete Todo', complete: true });
And after doing this we notice that the subscription to the completed Todos slice now logs a new array with two completed items.
If we change the complete
property value to false
and do a put
on the entity store the subscription only logs one array.
T3.complete = false;
store.put(T3);
Now the subscription to the completed
Todos
slice only logs the first completed
todo we added. The third Todo
instance has been dynamically removed from the slice.