Skip to content

Modifier Managers should not re-consume their args on destroy #19162

@NullVoxPopuli

Description

@NullVoxPopuli

According to the current modifier manager spec:

destroyModifier will be called when the modifier is no longer needed. This is intended for performing object-model level cleanup.

then, in the following code example:

 destroyModifier(instance, args) {
    if (instance.willDestroyDOM !== undefined) {
      instance.willDestroyDOM();
    }
  }

args are passed to destroyModifier.

I think this is a bug because:

  • it means that args are all re-consumed on destruction of a render / component tree
  • if guards in templates no longer can guarantee the safety of the shape of data
  • in order for modifiers' destruction to not trigger exceptions wherever args' derived data is derived, you need to add additional guards all over your code, or do foo?.bar?.bax everywhere (this generates a lot of boilerplate)

I propose we remove args from the destroyModifier hook so that

  • none of the above issues exist anymore
  • teardown is slightly faster due to not re-consuming args

For example, today, the following isn't safe:

{{#if this.data.foo}}
  <SomeComponent @data={{this.data}} />
{{/if}}
// some-component
export default setComponentTemplate(hbs`
  <span {{some-modifier this.nestedData}}>breaks</span>
`, class extends Component {
  get nestedData() {
    // you should be able to assume foo exists, because of the condition in the previous template
    // but today, you can't assume that :(
    return this.args.data.foo.dataOnFoo;
  }
});

Minimal Reproduction / Description of the Problem: https://ember-twiddle.com/5a3fa797b26e8807869340792219a5ee?openFiles=components.demo%5C.hbs%2Ccomponents.demo%5C.hbs

Relevant Discord Threads:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions