Which hook in components is best practise for teardown?

All the previous topics seem out of date and inaccurate resurrecting topic.

In a component where do we tear down Dom events / jQuery listeners? willDestroyElement or willDestroy ?

  • Glimmer components do not have a willDestroyElement hook.
  • API docs say willDestroy is for teardown and leave willDestroyElement vague and unhelpful.
  • Guides specifically call out willDestroyElement and do not offer willDestroy as a lifecycle hook.

Trying to settle a debate at work. Thankx

1 Like

Unfortunately, this is a slightly mixed story, as you can see using this Twiddle: the guides recommend what they do because the element is destroyed by the time willDestroy runs. This means that if you don’t tear down event listeners during willDestroyElement and you haven’t saved a reference to them to remove in some other way, you’re going to leak that event listener. This is why the existing guides are written the way they are.

However, if instead you are using outerHTML semantics (via tagName in Ember components, or as the only way in Glimmer components), there is no such this.element—you have to use various other workarounds to track any event listeners you set up and make sure they’re disposed of correctly.

By and large, the need for the hook is largely eliminated by the use of template-side constructs, though: setting up handlers with the {{on}} element modifier means they’ll be automatically torn down when that section of the component tree is removed, for any reason. If you’re using that pattern, you basically don’t have to worry about the kinds of concerns you normally put into willDestroy or willDestroyElement at all: you get the right behavior for “free” as a developer.

In Glimmer Components, using {{on}} is really your only option!

So, if you must use it in an Ember Component, you should use willDestroyElement—but you’re better off migrating that component to have outerHTML semantics and using the {{on}} modifier (once you’re on Ember 3.11)!

5 Likes

Thank you. You articulated that better then I could have imagined.

1 Like

@chriskrycho could you please provide a simple example of what this will look like with Glimmer components? We are on Ember 3.12. I am assuming I need to use {{will-destroy (action this.willDestroyElement)}} from @ember/render-modifiers? What do you mean exactly by

migrating that component to have outerHTML semantics

? What if my component doesn’t have an outer HTML element? It has several top level elements.

Thank you!

Hey @MariannaAtPlay,

First, welcome to the forums! Hopefully we can be of help!

Second, I’d be happy to help, but probably the best way to tackle this is if you can start a new thread with a more concrete set of details—that way I can respond in specific and with appropriate details and recommendations for your specific scenario! The trick is that while {{will-destroy}} (and the other modifiers from @ember/render-modifiers) will work, and are very helpful for a migration path, there are two important things to remember when transitioning to Octane and Glimmer components:

  1. A lot of times, there’s a much better way than just directly re-implementing the existing semantics using {{will-destroy}}: sometimes it’s via another modifier, sometimes via a totally different approach.
  2. It’s often that “totally different approach” because in many cases, if you truly convert to the Octane paradigm, you simply don’t need to do the things you did in Ember Classic approach in the first place. A great example is handling event listeners: in Ember Classic, with Ember Components, you needed to manage tearing down event listeners correctly yourself. In Octane, with {{on}}, the modifier itself handles it for you.

If you open a new thread and work through your specific example, I’ll happily help you think it through (and others may be able to chime in as well)!