Implementing A Method To Get Single Values In Aurelia Store

The Aurelia Store plugin is a great way to add powerful and easy to use state management into your Aurelia applications. For some, the paradigm shift in how you work can be confusing to work with at first. One such task you might find yourself needing to do is obtaining a singular value from the state.

As you will soon discover, state management in Aurelia Store requires you to subscribe to the entire state and react to all changes. Sometimes you just want to get a single value from the state to reference inside of your view-models.

While I cannot guarantee Vildan (Aurelia core team member and author of Aurelia Store) will approve of my solution, it works 😂

The solution I came up with which fits my needs perfectly is a method to subscribe, get one or more values from the state and then unsubscribe.

export const getStatePropertyOnce = async (...properties: string[]) => {
  return new Promise(async (resolve, reject) => {
    const subscription = store.state.pipe(pluck(...properties)).subscribe(
      (value) => { resolve(value); },
      (error) => { reject(error); }
    );
    subscription.unsubscribe();
  });
};

The beautiful thing about this method is it not only supports top-level properties, but it also works for nested properties in your state object as well. In a real use case, I have the locality value of the user’s client stored in the state.

async getAppClient() {
    this.appClient = await getStatePropertyOnce('appClient');
}

There might be some pitfalls I have yet to encounter with the above functionality and you should also make sure your await is wrapped in a try/catch block as well to handle errors, but it works for my needs. If the thought of having to use @connectTo or manually setup a subscriber and then dispose of it within your view-models sounds like a lot of work, this helper method can be a good time saver.

async getValueFromStore() {
    // Object in state is represented as user.details.email
    this.someValue = await getStatePropertyOnce('user', 'details', 'email');
}

In the above example, we are using the method to get a property of email which exists on an object called details which lives inside of a main user object. The method handles getting nested properties with ease.