Observe a property and do something with it before it changes?


#1

I had this thought with my app I’m building where I would like a bid amount to animate up when the bid is increased. Currently the way this works is either if the user increases it or if a websocket type push from pubnub comes in and fires an action in my route to update the item with the new bid amount.

What I would really like to do is animate that value up using some simple javascript so it doesn’t just pop into place (possible add a little css animation to the text itself, like a pulse) to show the user that something is being changed and they need to know about it.

I know I should be able to use a psudo bid amount that I manually update, but I also saw observables and wondered if there was something there that could be used to keep it as clean and ember friendly as possible?

Thoughts?


#2

You should take a look at computed properties as they should be able to aid you here. Also, it’s a good idea to avoid using Observers at this point. Take a look at this article for a great explanation on why and how you can refactor your code to not use them!


#3

So does getting a property inside the computed return the existing value or the new value, and I assume anything I do inside the callback runs before the computed renders to the browser correct? Meaning if I can get the existing property and the new property, I should be able to animate it before actually setting the value to the ending value?


#4

This might be a good place to use the didReceiveAttrs hook in components. Something like:

export default Ember.Component.extend({
  previousValue: 0,
  didReceiveAttrs() {
    let previousValue = this.previousValue;
    let newValue = this.getAttr('value');

    // Trigger something here to do the animation. 
    this.previousValue = newValue;
  }
});

And invoking it:

{{count-up value=value}}

#5

[edit: cross-posted with spencer_price, basically the same idea, but on an observer]

New property only. But getting the old one is easy, just cache current value so it is available in next call.

observeThing: Ember.observer('thing', function () {
    const thing = get(this, 'thing');
    if (this._thing_cache !== undefined) {
        do_stuff(this._thing_cache, thing);
    }
    this._thing_cache = thing;
})

Invoke it in your init so it caches the initial value, if relevant.