I want to use observer in Ember 3.15

I want to use observer in Ember 3.15

Here is my source in Ember 3.14

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { observer } from '@ember/object';


export default Controller.extend({
   session: service(),
    
   ooUserId : observer('session.user.id', function(){
     console.log("session.user.id changed!!");
   })
})

Here is my source in Ember 3.15

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action, observer } from '@ember/object';

export default class ApplicationController extends Controller {
	@service session;
}

How should I change?

Generally, ember is moving away from observers, as they have proven time and again that they are hard to debug (though the team acknowledges there do exist some rare use cases where they may be required (integrating with external systems, such as window menus in Electron apps).

Today, the most common way to get rid of observers is to trigger the change at the source – so, based on your pre-octane code, something is changing the session.user.id? Do you know what is causing that change? (could you paste your service as well?)

Kind of generally, it would go like this though:

async loadUser() {
  let user = ... // fetch / load whichever
  this.user = user;
  
  this.performSomeAction(); // <-- this is what takes the place of most observers
}

There are also other techniques, but first, I’d like to hear more about your setup / use case?

1 Like

thank you very much ! your answer was very helpful.

I want to use observer when observing to change other properties but return nothing

You have two options for using observers in a native class. This example shows both:

import Controller from '@ember/controller';
import { observes } from '@ember-decorators/object';

export default class ApplicationController extends Controller {
  constructor(...args) {
    super(...args)
    this.addObserver('foo', this, this.fooDidChange1);
  }

  fooDidChange1() {
    console.log('addObserver example fired');
  }

  @observes('foo')
  fooDidChange2() {
    console.log("ember-decorator observer fired");
  }
}

addObserver is built in and continues to work and be supported on all Ember Objects (and that includes Controller).

The @observes decorator comes from an addon, which you can install with ember install ember-decorators.

The default lint rules will warn you that observers are usually a mistake, which is indeed true. But observers are still supported because there are a small number of legitimate use cases, around syncing data out of Ember and into some non-Ember system. Unless you’re doing that, it’s probably a good idea to share more about your use case show we can offer non-observer alternatives.

Finally, the new Glimmer Component class is not an Ember Object and doesn’t have addObserver. That is indeed a gap, if you have one of the rare use cases that truly needs observers. The solution to that is probably going to be @use and Resources.

1 Like

thank you very much!! I’ll consider that but I’ll try not to use the observer as much as possible!