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.