• 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

Implementing A Method To Get Single Values In Aurelia Store

Aurelia 1, Aurelia Store · October 15, 2019

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.

Dwayne

Leave a Reply Cancel reply

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Jon
Jon
3 years ago

You can use rx first (https://www.learnrxjs.io/operators/filtering/first.html) for this use case, as it gets the first value and automatically subscribes, eg:

this.store.state.pipe(first()).subscribe(action)

We don’t actually use connectTo at all or subscribe directly to the store. We create a class called StateSubscriber that provides a bunch of methods that use various rx operators in ways which make sense for our state structure.

For the example in your article, using typescript keysof operator you can also ensure that the properties exist on both the viewmodel and the state:

set(…keys: (keyof U & keyof T)[]) {
return this.observable.pipe(distinctUntilKeysChanged(…keys))
.subscribe(x => keys.forEach(y => (this.viewModel as any)[y] = x[y]));
}

Other methods include subscribe to only changes for a property and another for projecting an ordered array from an object (we tend to use objects with ids as keys for entities as it makes updating the state easier).

0
Jon
Jon
3 years ago

Mistake in comment, should say the first automatically unsubscribes

0
Vildan Softic
Vildan Softic
3 years ago

Jon said it perfectly right. Use operators like first or take(1) which are creating an observable which is going to complete automatically afterwards. Saves you the unsubscribe call and reads much nicer in my opinion.

Whether your approach at all is right/wrong as always depends on the use case but implementation-wise its absolutely fine.

0
Dwayne
Dwayne
Author
3 years ago

@Jon

Amazing. Thank you for sharing. I am still very much an RxJS newbie, but I love it. Aurelia Store is my first and only introduction to RxJS, I really need to learn it better. Do you have any code publicly available what you have done? It sounds like a good way to go about state changes. Or better yet, creating a custom decorator that adds these methods to a class something like `@useState`.

Knowing RxJS has some methods that automatically unsubscribe is huge. Thanks for that.

@Vildan

Those auto-unsubscribe methods are amazing. The approach works, but now I see it can definitely be improved.

0

Primary Sidebar

Popular

  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Waiting for an Element to Exist With JavaScript
  • Thoughts on the Flipper Zero
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • How To Paginate An Array In Javascript
  • Reliably waiting for network responses in Playwright
  • How To Mock uuid In Jest
  • How to Copy Files Using the Copy Webpack Plugin (without copying the entire folder structure)
  • Wild Natural Deodorant Review

Recent Comments

  • Dwayne on Is Asking Developers How to Write FizzBuzz Outdated?
  • kevmeister68 on Is Asking Developers How to Write FizzBuzz Outdated?
  • Kevmeister68 on Start-Ups and Companies That Embrace Work From Anywhere Will Be More Likely to Survive the Coming Recession in 2023
  • kevmeister68 on What Would Get People Back Into the Office?
  • Dwayne on PHP Will Not Die

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz