# Aurelia-store and observable properties: a cautionary tale

**URL:** <https://discourse.aurelia.io/t/aurelia-store-and-observable-properties-a-cautionary-tale/1698>\
**Category:** Best Practices\
**Created:** [October 6, 2018, 7:37am UTC](https://discourse.aurelia.io/t/aurelia-store-and-observable-properties-a-cautionary-tale/1698 "2018-10-06T07:37:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jlapointe](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jlapointe/32/931_2.png) [@jlapointe](https://discourse.aurelia.io/u/jlapointe)\
**Post date:** [October 6, 2018, 7:37am UTC](https://discourse.aurelia.io/t/aurelia-store-and-observable-properties-a-cautionary-tale/1698/1 "2018-10-06T07:37:52Z")

</div>

I’m posting this in case anyone else runs into this little snag.

While experimenting with aurelia-store, I decided I’d like to avoid making “temporary” properties on my view-model for the purpose of binding to form data. Instead, I wanted to bind my user input directly to the properties `pluck`ed from the state, and furthermore make them `@observable`, so I could easily `dispatch` a state update whenever any of them changed. (Is this a good idea? I don’t know; someone please weigh in if you have an opinion.)

```auto
import stuff

@autoinject
@connectTo({
    selector: (store) => store.state.pipe(pluck("myProperty")),
    target: "myProperty"
})
export class MyVM {
    @observable myProperty; // OK - this will hold the latest plucked value, *and* be observable
    myPropertyChanged(newVal, oldVal){
        this.store.dispatch("updateMyProperty", newVal);
    }

    constructor(store){
        store.registerAction("updateMyProperty", (state, newVal) => return Object.assign({},state, {myProperty: newVal});
    }
}

```

```auto
<template>
    <form><input type="text" value.bind="myProperty"></input></form>
</template>

```

Now assuming my syntax is correct (I haven’t tested the exact code above), this should pipe the value of `store.state.myProperty` into `MyVM.myProperty`; and any changes to `MyVM.myProperty` should dispatch an update to the store. And conveniently, `@observable` properties only call their change handler if `newVal` is different from `oldVal`, so we shouldn’t get stuck in an endless update loop that crashes our browser.

…right?

But that code _will_ crash your browser!

Luckily, the reason and the solution are very simple: the `@observable` decorator and the `@connectTo` decorator _both_ look for a change handler, and they both expect it to be named according to the same convention: `[property-name]Changed(newVal, oldVal)`. Writing a single change handler that accidentally fits both those slots is very easy to do, and it causes some wild behaviour.

Solution: just use the syntax `@observable({changeHandler: 'someOtherFunctionName'})` to define your observable change handler, and you’re all set. You can connectTo, pluck, observe/dispatch, and bind using a single property name, and it all works seamlessly.

---

<div class="post-metadata">

**Author:** ![zewa666](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zewa666/32/19_2.png) [@zewa666](https://discourse.aurelia.io/u/zewa666)\
**Post date:** [October 9, 2018, 6:09am UTC](https://discourse.aurelia.io/t/aurelia-store-and-observable-properties-a-cautionary-tale/1698/2 "2018-10-09T06:09:17Z")

</div>

In general you should try to avoid to manipulate the state by any means other than dispatching a new action. Using two-way bindings directly on a state slice will do pretty much exactly that. If you’re writing a history aware app you’ll pretty soon recognize that your previous states have been modified without the store noticing it.

I’ve updated the docs with a [new section](https://aurelia.io/docs/plugins/store#two-way-binding-and-state-management) to explain how to avoid it

---

<div class="post-metadata">

**Author:** ![jlapointe](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jlapointe/32/931_2.png) [@jlapointe](https://discourse.aurelia.io/u/jlapointe)\
**Post date:** [October 10, 2018, 12:23pm UTC](https://discourse.aurelia.io/t/aurelia-store-and-observable-properties-a-cautionary-tale/1698/3 "2018-10-10T12:23:53Z")

</div>

Thanks! Yes, after giving your post some thought I see this is a bad design choice.

It works when only this component is modifying the local state, but if there were another component trying to send state update through the same observable, it would get muddy – we lose the concept of “current state”, since a single property is expected to do double duty representing the original state _and_ the modified state.

---

<div class="post-metadata">

**Author:** ![dwaynecharrington](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/dwaynecharrington/32/11_2.png) [@dwaynecharrington](https://discourse.aurelia.io/u/dwaynecharrington)\
**Post date:** [November 4, 2018, 10:19pm UTC](https://discourse.aurelia.io/t/aurelia-store-and-observable-properties-a-cautionary-tale/1698/5 "2018-11-04T22:19:44Z")

</div>

Two-way binding and Aurelia Store is a recipe for a bad time. If I get the time, I would love to have a stab at creating a forms plugin for Aurelia Store which would bypass the issues of directly mutating state from a subscription. I am not sure of the design of such a plugin, but I know Redux has a plugin for this called Redux Form to address the same problem of pass-by-reference mutation on source values.
