Storage
Back your stores with localStorage
, sessionStorage
or any other mechanism you wish.
Installation
Usage
When calling provideStore
, include withNgxsStoragePlugin
in your app config:
If you are still using modules, include the NgxsStoragePluginModule
plugin in your root app module:
It is recommended to register the storage plugin before other plugins so initial state can be picked up by those plugins.
Options
The plugin has the following optional values:
keys
: State name(s) to be persisted. You can pass an array of strings that can be deeply nested via dot notation. If not provided, you must explicitly specify the*
option.namespace
: The namespace is used to prefix the key for the state slice. This is necessary when running micro frontend applications which use storage plugin. The namespace will eliminate the conflict between keys that might overlap.storage
: Storage strategy to use. This defaults to LocalStorage but you can pass SessionStorage or anything that implements the StorageEngine API.deserialize
: Custom deserializer. Defaults toJSON.parse
serialize
: Custom serializer. Defaults toJSON.stringify
migrations
: Migration strategiesbeforeSerialize
: Interceptor executed before serializationafterDeserialize
: Interceptor executed after deserialization
Keys option
The keys
option is used to determine what states should be persisted in the storage. keys
shouldn't be a random string, it has to coincide with your state names. Let's look at the below example:
In order to persist all states, you have to provide *
as the keys
option:
But what if we wanted to persist only NovelsState
? Then we would have needed to pass its name to the keys
option:
It's also possible to provide a state class as opposed to its name:
And if we wanted to persist NovelsState
and DetectivesState
:
Or using state classes:
You can even combine state classes and strings:
This is very useful for avoiding the persistence of runtime-only states that should not be saved to any storage.
It is also possible to provide storage engines for individual keys. For example, if we want to persist NovelsState
in the local storage and DetectivesState
in the session storage, the signature for the key will appear as follows:
LOCAL_STORAGE_ENGINE
and SESSION_STORAGE_ENGINE
are injection tokens that resolve to localStorage
and sessionStorage
, respectively. These tokens should not be used in apps with server-side rendering as it will throw an exception stating that these symbols are not defined in the global scope. Instead, it is recommended to provide a custom storage engine. The engine
property can also refer to classes that implement the StorageEngine
interface:
Namespace Option
The namespace option should be provided when the storage plugin is used in micro frontend applications. The namespace may equal the app name and will prefix keys for state slices:
Custom Storage Engine
You can add your own storage engine by implementing the StorageEngine
interface:
Serialization Interceptors
You can define your own logic before or after the state get serialized or deserialized.
beforeSerialize
: Use this option to alter the state before it gets serialized.afterSerialize
: Use this option to alter the state after it gets deserialized. For instance, you can use it to instantiate a concrete class.
Migrations
You can migrate data from one version to another during the startup of the store. Below is a strategy to migrate my state from animals
to newAnimals
.
In the migration strategy, we define:
version
: The version we are migratingversionKey
: The identifier for the version key (Defaults to 'version')migrate
: A function that accepts a state and expects the new state in return.key
: The key for the item to migrate. If not specified, it takes the entire storage state.
Note: Its important to specify the strategies in the order of which they should progress.
Feature States
We can also add states at the feature level when invoking provideStates
, such as within Route
providers. This is useful when we want to avoid the root level, responsible for providing the store, from being aware of any feature states. If we do not specify any states to be persisted at the root level, we should specify an empty list:
If keys
is an empty list, it indicates that the plugin should not persist any state until it's explicitly added at the feature level.
After registering the AnimalsState
at the feature level, we also want to persist this state in storage:
Please note that at the root level, keys
should not be set to *
because *
indicates persisting everything.
Last updated