• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

Shared State in Aurelia

Aurelia 1, Javascript · February 7, 2016

In a single page application (SPA) like Aurelia, shared state is one of those important things every developer mostly encounters. Sharing the current state of a logged in user or sharing a shopping cart’s contents throughout the app.

Fortunately, Aurelia makes it easy to build applications with shared state.

By default a class in Aurelia is a singleton. If you create a service called UserService and inject it throughout different parts of your app, provided you’re injecting it without telling Aurelia to do anything non-standard, it will be a singleton.

As you know objects in Javascript are passed by reference. This is what a singleton class is: a shared object. Any other class in your app that asks for it gets the same copy as every other part. If you change something, it changes everywhere.

The standard way to have shared state is singletons, but another is also a server-side data store or even using client-side storage mechanisms like; sessionstorage, localstorage and IndexedDB.

My personal choice for most apps I have used Aurelia for is a shared singleton service class. If you come from an Angular background, shared services are probably something you used often.

Although, there might be times when storing data using local storage might be a better choice, especially if you want to survive manual page reloads which the router does not catch or preventing multiple server requests.

A user service

Here is a basic example of a user service which handles getting user data and storing it (including the current logged in user).

export class UserService {
    _currentUserLoggedIn = false;
    _userStore = {};
    _users = [];

    getCurrentUser() {
        return this._userStore;
    }

    findUser(username) {
        // Do something server side and return the user
    }

    findUsers(criteria) {
        // Will find one or more users and then return them
        // They will also be stored on this class in the _users variable
    }
}

Now if we inject this same class using the standard @inject(UserService) decorator, into multiple classes in our app, they all get the same version. They get any populated class variables, the current user login status and more.

Some ideas for extending this with redundancy include using client-side storage mechanisms like local or session storage to survive page reloads and server requests.

Conclusion

There is very little to explain. A class by default in Aurelia is a singleton and unless you specify otherwise using a decorator like @transient() then that is guaranteed.

As always if you need further explanation, want to discuss shared state strategies or correct an error: hit the comments section.

Dwayne

Leave a Reply Cancel reply

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Vali Dumitru
Vali Dumitru
6 years ago

What exactly do you mean by “shared state?” I’m asking because it’s quite confusing what actually happens in RL. Take the following class:

import {inject} from ‘aurelia-framework’;
import {Router} from ‘aurelia-router’;
import {List} from ‘./list’;

@inject(Router, List)
export class Add {
constructor(router, list) {
this.pageTitle = “Add item”;
this.title = null;
this.description = null;

this.router = router;
this.list = list;
}

add() {
// Add item to parent list
this.list.addItem({
‘title’: this.title,
‘description’: this.description
});

// navigate to list
this.router.navigateToRoute(‘list’);
}
}

and the List class:

export class List {
items = [];

construct() {
this.pageTitle = “All items”;
}

addItem(item) {
this.items.push(item);
}
}

After going to the “add” state and adding an item, when getting back to the “list” state via the navigateToRoute method of the router, the items property is still empty, even though the addItem method is properly called and looks like the values are retained, but they are definitely not.

0
Pedro Luz
Pedro Luz
6 years ago

I have the same problem.

0
Serkan Serttop
Serkan Serttop
6 years ago

@Vali “construct” under “List” class should be “constructor” and I would put “items = [];” into constructor function with “this.items = [];”.
I think “items = [];” works with Typescript, and could work with certain transpiling options, but not sure.

0

Primary Sidebar

Popular

  • I Joined Truth Social Using a VPN and Editing Some HTML to Bypass the Phone Verification
  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Thoughts on the Flipper Zero
  • Waiting for an Element to Exist With JavaScript
  • Handling Errors with the Fetch API
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • How To Paginate An Array In Javascript
  • Wild Natural Deodorant Review
  • How To Install Eufy Security Cameras Without Drilling or Using Screws

Recent Comments

  • CJ on Microsoft Modern Wireless Headset Review
  • Dwayne on Microsoft Modern Wireless Headset Review
  • CJ on Microsoft Modern Wireless Headset Review
  • john on Microsoft Modern Wireless Headset Review
  • Dwayne on Why You Should Be Using globalThis Instead of Window In Your Javascript Code

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz