In this post, we are going to learn how we can keep our application state in sync when a user has multiple tabs open. We are going to make this happen by using the Web Storage API and Akita. Basic knowledge of Akita is needed.

Create Contacts Page

For our demo, we will create a contacts page, that allows our users to add, edit and remove a contact.



ng add @datorama/akita ng g af contacts

The above commands add Akita to our project and scaffold the files we need, entity store, entity query, model and service.

Now, let's add Akita's persistState :



// main.ts import { persistState } from ' @datorama/akita ' ; persistState ({ key : ' yourKey ' , include : [ ' contacts ' ] }); platformBrowserDynamic () . bootstrapModule ( AppModule ) . catch ( err => console . log ( err ));

From the docs: The persistState function gives you the ability to persist some of the app’s state, by saving it to localStorage/sessionStorage or anything that implements the StorageEngine API, and restore it after a refresh.

Now, the only thing we need to do is to listen to the window.storage event which fires when localStorage has been modified in the context of another document. When it emits, we filter the key we are interested in and call the snapshotManager.setStoresSnapshot method with the new value.



import { untilDestroyed } from ' ngx-take-until-destroyed ' ; import { fromEvent } from ' rxjs ' ; import { snapshotManager } from ' @datorama/akita ' ; class AppComponent { ngOnInit () { fromEvent < StorageEvent > ( window , ' storage ' ). pipe ( filter ( event => event . key === ' yourKey ' ) untilDestroyed ( this ) ). subscribe ( event => { snapshotManager . setStoresSnapshot ( event . newValue , { skipStorageUpdate : true }); }); } }

The setStoresSnapshot method takes the application state object which looks like:



{ " storeName " : state , " storeName " : state }

and updates each store with the given value.

Try it. Open your application in two tabs, change the store's value in one of them and see it reflected in the second one.

The inspiration for the article came from the ngrx version of it.