Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observing a property on a service from a route in EmberJS

I think I'm not understanding a concept here. As far as I know any Ember.object can observe properties on another Ember.object.

So, I have a service, a router, and a component. I need the component and the router to be able to observe a property on the service. It's entirely possible that I'm just structuring the solution in the wrong way, I'll include an overview of what I'm trying to do at the end.

Here is approximately what I have:

/services/thing-manager.js

export default Ember.Service.extend({
  observedProperty: 'original value'
});

/components/thing-shower.js

export default Ember.Component.extend({
  thingManager: Ember.inject.service(),
  myObserver: Ember.observer(
    'thingManager.observedProperty',
    function() {
      // This shows up as anticipated, unlike the one in the routes
      console.log('THING SHOWER COMPONENT observed change on thingManager')
    }
  ),
 actions: {
   changeObservedProperty: function() {
     let thingManager = this.get('thingManager')
     let newText = thingManager.get('observedProperty') + '!'
     // here i am sure to call `set` to make sure observers fire
     thingManager.set('observedProperty', newText)
   }
 }

});

/routes/things.js

export default Ember.Route.extend({
  thingManager: Ember.inject.service(),

  underObservation: Ember.observer('thingManager.observedProperty', function() {
    // This is what I expect to fire, but does not.
    console.log('THINGS ROUTE observed change on thingManager')
  }),
});

As you can see, I'm expecting console output from both observers in the component and router. Why doesn't this work?

Twiddle here!

My Overall Goals

This is perhaps a separate question, but I'd like to know if there is a better way to accomplish what I'm trying to do. I've been learning about 'data down, actions up', which led me to this approach. I'm building a website that load a json file with a bunch of GPS coordinates and sticks them on a map.

The goal is to click a map marker, and have that load the corresponding data. This should also change the route. So, my thinking was, to keep track of my markers in a service, and when the selected marker changes, the router would observe that and transition to the next route. The component would also notice the changed property and update the map.

Thanks folks!

like image 803
counterbeing Avatar asked Jul 19 '17 12:07

counterbeing


1 Answers

In things.js route file you haven't used accessed/used thing-manager service, so observer will not be triggered.

routes/thing.js

init(){
    this._super(...arguments);
    this.get('thingManager');
},

introducing this will make your observer to be fired.

I would say, if you are following the DDAU priniciple, then your component should not mutate the thing-manager service properties. it should send action to service and mutate it.

Note: You can have observers and computed properties inside any Ember.Object which means you have it thing-manager service too.

like image 75
Ember Freak Avatar answered Oct 19 '22 10:10

Ember Freak