0
votes

To preface this, I must clarify that I am using the legacy-controller and the legacy-view for the interim period while transitioning to Ember 2.3, found here:

https://github.com/emberjs/ember-legacy-controllers

Now, I have a property called currentTopPost on my (legacy) controller.

In Ember 1.7, I had this setup:

// before observer
currentTopPostBeforeObserver: function(){
...
}.observesBefore('currentTopPost'),

// observer
currentTopPostBeforeObserver: function(){
...
}.observes('currentTopPost'),

The reason I had it this way was that when the currentTopPost changed, I wanted it save the old topPost before it switched its value to the new property, as it was a Post object (I had a Post model).

Of course, in 1.7, I saved the old post in the beforeObserver and then did whatever else I had to do in the observer. Now, In Ember 2.3, I have this set up:

currentTopPostObserver: Ember.observer('currentTopPost', function(){
...

}),

Which works fine as far as performing functions with the new value goes. But I've lost the ability to process an action before the value changes. Now according to an answer to this question:

How can an observer find out the before and after values of the observed property in Ember.js?

the observesBefore function has been deprecated and we should be following this:

doSomething: Ember.observer( 'foo', function() {
  var foo = this.get('foo');
  var oldFoo = this.get('_oldFoo');

  if (foo === oldFoo) { return; }

  // Do stuff here

  this.set('_oldFoo', foo);
})

However, on trying to use this.get("_oldCurrentTopPost"), I get nothing. How do I access the old value of this property before it changes ?

2

2 Answers

3
votes

What I use as a replacement is:

propWillChange(prop) {
  //your new before observer
},

propDidChange: Ember.observer('prop', function() {

  let prop = this.get('prop');

  if (this._oldProp !== prop) {
    this.propWillChange(this._oldProp);
    this._oldProp = prop;
  }

  //Do stuff

})

Of course, on the first run, _oldProp will be undefined, but that's expected, right? It is the first time prop is being changed.

I also disagree that observers shouldn't be used. I agree that observers should be avoided if possible, because many people don't fully grasp their side-effects, but in many cases they are very useful, especially when building 3rd party plugin integrations.

Since the question specifically asks about a beforeObserver replacement, here it is. However, I recommend to reconsider if your use case can be rebuilt without observers if possible.

Twiddle: https://ember-twiddle.com/045b7b9c1562ceb6bbdc

0
votes

As far as I can tell, there is no particularly nice way to get that mechanism back. Observers themselves are "considered harmful" in many cases, but I'll try my best to give you a practical alternative solution.

The best quick and relatively dirty way to do this that I can think of is to make a "proxy" computed property with a getter and setter. Within the setter you can get the previous value of the "real" property, call out to a function to do whatever, and then set the new value on the real property.

Here's an example that you could use:

myProxyProperty: Ember.computed('myRealProperty', {
  get() {
    return this.get('myRealProperty');
  },
  set(key, value) {
    const oldValue = this.get('myRealProperty');

    this.doSomethingWithOldValue(oldValue);

    this.set('myRealProperty', oldValue);
  }
})

Unfortunately I don't know of a better way of doing this in new Ember at the moment.