1
votes

With Ember 2.0, there is a deprecation for modifying properties in a component's didInsertElement hook. The following scenario exposes a problem when trying to integrate other third party libraries, in this case d3.

I have an ember component that wraps a d3 visualization, having as tagName: svg. There are two properties which are passed down from the parent into this component, the width and height. There are observers on these two properties within the d3 component to update the visualization to make it responsive to changes in the window size.

The problem arises in the parent component. I am currently binding to the window resize event, running Ember.run and a callback which sets the windowSize property in the component. I have two computed properties which depend on windowSize, the width and height which are computed according to the DOM's width and height (which are dynamic thanks to columns in bootstrap). Hence, the computed properties look like:

halfWidth: Ember.computed('windowSize', function() {
  return $(this.get('halfSelector')).first().width();
})

However, when passing the computed property to the d3 component as {{d3-component width=halfWidth}} there is no default. This computed property is only computed when the resize event on the window is fired. If I resize the window the d3 component updates correctly with the new width.

didInsertElement() {
  $(window).on('resize', () => {
    Ember.run(() => {
      this.set('windowSize', $(window).width());
    });
  });
  // In order have the computed properties to have defaults, one could do
  // $(window).trigger('resize')
  // However this line is responsible for raising the deprecation notice.
}

How do I give the computed property a default value which depends on a width of a DOM node after the component has been inserted into the DOM?

1

1 Answers

0
votes

In order to get rid of the deprecation, I changed the definition of the didInsertElement to the following:

didInsertElement() {
  let onWindowResize = () => {
    this.set('windowSize', $(window).width());
  };

  $(window).on('resize', () => { Ember.run(onWindowResize); });
  Ember.run.scheduleOnce('afterRender', onWindowResize);
}

I got inspiration from https://github.com/emberjs/ember.js/issues/11493. The problem was also referenced as Forcing layout calculations to use in further positioning. In order to avoid the deprecation of setting properties in the didInsertElement hook, one uses the afterRender queue to schedule the change.