Skip to main content

The Store

The createStore function is used to initialize a store with a state. The first argument is a configuration object where a name of the store is specified. After the first argument any number of features can be specified which describe the nature of the store.

An example of a simple store:

import { createStore, withProps } from '@ngneat/elf';

interface AuthProps {
user: { id: string } | null;
}

const authStore = createStore(
{ name: 'auth' },
withProps<AuthProps>({ user: null })
);

An example of a store that contains multiple state features:

const store = createStore(
{ name: 'todo' },
withEntities<Todo>(),
withUIEntities<UIEntity>(),
withProps<{ foo: string }>({ foo: '' })
);

The features can be either one or more of the available features in Elf, or additional features you can create or add from other sources.

Querying the Store

A store is a BehaviorSubject. Therefore, we can subscribe to it to get its initial value and its subsequent values:

authStore.subscribe((state) => {
console.log(state);
});

The select operator

Select a slice from the store:

import { select } from '@ngneat/elf';

const user$ = authStore.pipe(select((state) => state.user));

The select() operator returns an observable that calls distinctUntilChanged() internally, meaning it will only fire when the state changes, i.e., when there is a new reference to the selected state.

We can also query its value once without the need to subscribe:

const state = authstore.getValue();

Updating the Store

To update the store, we can use the update method which receives a callback function, which gets the current state, and returns a new immutable state, which will be the new value of the store:

authStore.update((state) => ({
...state,
user: { id: 'foo' },
}));

Updating a root property

import { setProp, setProps } from '@ngneat/elf';

store.update(setProp('foo', 'bar'));
store.update(setProp('count', (count) => count + 1));

store.update(
setProps({
count: 1,
child: 2,
})
);

store.update(
setProps((state) => ({
count: 1,
nested: {
...state.nested,
bar: 'baz',
},
}))
);