ember-render-modifiers icon indicating copy to clipboard operation
ember-render-modifiers copied to clipboard

@model hash and did-update don't play well together

Open jrjohnson opened this issue 5 years ago • 3 comments

I've created a reproduction of this issue which I'll attempt to describe here:

When returning a hash from the routes model hook and then passing that hash into a component as split properties <Consumer @one={{@model.one}} @two={{@model.two}} /> and then using those split properties in getters of the component to invoke did-update an exception will be thrown when leaving the route. You can see this in the reproduction by navigating between the routes with the console open. This same thing doesn't happen if this.model is used in place of @model.

What I suspect is happening is that @model gets torn down early and re-assigned to the incoming route. This causes the first property @model.first to change which triggers did-update to call the second getter which is now unable to access this.args.second because it is also gone.

I've reproduced this as a synchronous action, but we're hitting this issue when did-update calls a task which loads async state. That's why the modifier needs to trigger the action and it can't just be a getter itself.

I'm not sure if this is an issue with did-update or a broader issue with modifiers and tracked properties using the @model pattern, but this seemed like the right place to start.

jrjohnson avatar Mar 24 '20 05:03 jrjohnson

This sounds quite a bit like an issue that @wagenet was describing to me in an offline conversation. :thinking:

rwjblue avatar Mar 29 '20 15:03 rwjblue

@rwjblue I found this via another discussion; this is just a variant of the same issue you and I hit debugging internally a few weeks ago.

chriskrycho avatar Dec 01 '20 02:12 chriskrycho

Nearly the same observations here, but with a 'single' model being returned from the model-hook.

Invoking a component like this in the route template:

<FooComponent @model={{@model}} />

Observing @model changes in the component template like this:

<div
  class="foo-component"
  {{did-update this.handleModelUpdate @model}}
  ...attributes
>
  FOO
</div>

Problem: the handleModelUpdate action gets triggered when switching sub-routes although its own route is unchanged and the model hook never fired. Changing the model param value from @model to this.model fixes it:

<FooComponent @model={{this.model}} />

fpauser avatar Mar 10 '21 00:03 fpauser