Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DONT BACKPORT][BUGFIX lts] Ensure hash objects correctly entangle as dependencies v2 #19584

Merged
merged 1 commit into from
Jun 21, 2021

Conversation

pzuraq
Copy link
Contributor

@pzuraq pzuraq commented Jun 1, 2021

This is an alternative to #19583

The previous bugfixes to {{hash}} caused a change to the semantics of
computed properties that depend on a hash. Specifically, because
{{hash}} objects are now proxies, they are constant, never updating
again after they are initially created. This is fine if you depend on
an individual key in a hash, but breaks if you depend directly on the
hash itself:

computed('hash.foo', function() {}) // this works

computed('hash', function() {}) // this will no longer rerun

This is used occasionally when you wish to depend on the dynamic keys
of a dictionary, like so:

computed('hash', function() {
  let values = [];

  for (let key in this.hash) {
    values.push(hash[key]);
  }

  return values;
})

Notably, this is not a problem with autotracking, because autotracking
will entangle the usage of these keys dynamically. So this is only a
problem with legacy systems such as computed and observer which
cannot dynamically add dependencies based on the function's runtime.

To fix this, we need to determine if a dependency is a hash when a
computed or an observer depends upon it, and then entangle all of its
keys if it is. We do this whenever the value is the last value in the
chain.


This PR/fix ended up not working out, so we're not backporting

The previous bugfixes to `{{hash}}` caused a change to the semantics of
computed properties that depend on a hash. Specifically, because
`{{hash}}` objects are now proxies, they are _constant_, never updating
again after they are initially created. This is fine if you depend on
an individual key in a hash, but breaks if you depend directly on the
hash itself:

```js
computed('hash.foo', function() {}) // this works

computed('hash', function() {}) // this will no longer rerun
```

This is used occasionally when you wish to depend on the dynamic keys
of a dictionary, like so:

```js
computed('hash', function() {
  let values = [];

  for (let key in this.hash) {
    values.push(hash[key]);
  }

  return values;
})
```

Notably, this is not a problem with autotracking, because autotracking
will entangle the usage of these keys dynamically. So this is only a
problem with legacy systems such as `computed` and `observer` which
cannot dynamically add dependencies based on the function's runtime.

To fix this, we need to determine if a dependency is a hash when a
computed or an observer depends upon it, and then entangle all of its
keys if it is. We do this whenever the value is the last value in the
chain.
@pzuraq pzuraq force-pushed the bugfix/hash-computed-chains-only branch from 6eb24ff to 03b20d8 Compare June 21, 2021 17:22
@pzuraq pzuraq merged commit dec26de into master Jun 21, 2021
@pzuraq pzuraq deleted the bugfix/hash-computed-chains-only branch June 21, 2021 19:34
@pzuraq pzuraq changed the title [BUGFIX lts] Ensure hash objects correctly entangle as dependencies v2 [DONT BACKPORT][BUGFIX lts] Ensure hash objects correctly entangle as dependencies v2 Jun 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants