-
Notifications
You must be signed in to change notification settings - Fork 27.4k
RELEASE: Document behavior change in watchGroup in master #16024
Comments
FWIW, here are my thoughts on this:
More on that last point: In the first case (old behavior), you are not able to tell which value has changed. In the second case (new behavior) you are able to tell, by comparing the old and new values. All that being said, when using The only valid usecase I can think of where the "old" values are important, is when you want to calculate the "diff" (i.e. what has changed wrt to the combined result of all the values). In that case, where for example you need to combine the "old" values and the "new" values and compare the results of each combination, the new behavior makes more sense. In any case, I don't feel strongly about going any direction (since both have their pros and cons and both are good enough for most usecases involving |
The 1.6.x docs update has been added in #16005, and we've changed the behavior for 1.7.0. Technically we can close this. But I wonder why this change made it only in 1.7? If it's no BC then it could go into 1.6.x. If it's technically a BC, we need to add a BC notice in the changelog. |
I think we agreed the new behavior is better and yes it is technically a BC. It would be good to add a mention in the changelog. This issue is for tracking that 😛:
We should also add some tests, indeed. |
Closes angular#16024 BREAKING CHANGE (caused by c2b8fab) Previously the entries in `newValues` and `oldValues` reflected the differences in each *individual* espression, and not the difference of the values between each call of the listener. Now the entries in `oldValues` will equal the `newValues` of the previous call of the listener. This means comparing the entries in `newValues` and `oldValues` can be used to determine which individual expressions changed.
Closes angular#16024 BREAKING CHANGE (caused by c2b8fab) Previously the entries in `newValues` and `oldValues` reflected the differences in each *individual* espression, and not the difference of the values between each call of the listener. Now the entries in `oldValues` will equal the `newValues` of the previous call of the listener. This means comparing the entries in `newValues` and `oldValues` can be used to determine which individual expressions changed. For example `$scope.$watchGroup(['a', 'b'], fn)` would previously: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `a=2` | [2, undefined] | [1, undefined] | | `b=3` | [2, 3] | [1, undefined] | Now the `oldValue` will always equal the previous `newValue`: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `a=2` | [2, undefined] | [1, undefined] | | `b=3` | [2, 3] | [2, undefined] | Note the last call now shows `a === 2` in the `oldValues` array. This also makes the `oldValue` of one-time watchers more clear. Previously the `oldValue` of a one-time watcher would remain `undefined` forever. For example `$scope.$watchGroup(['a', '::b'], fn)` would previously: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `b=2` | [1, 2] | [undefined, undefined] | | `a=b=3` | [3, 2] | [1, undefined] | Where now the `oldValue` will will lways equal the previous `newValue`: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `b=2` | [1, 2] | [1, undefined] | | `a=b=3` | [3, 2] | [1, 2] |
Closes angular#16024 BREAKING CHANGE: (caused by c2b8fab) Previously when using `$watchGroup` the entries in `newValues` and `oldValues` represented the *most recent change of each entry*. Now the entries in `oldValues` will always equal the `newValues` of the previous call of the listener. This means comparing the entries in `newValues` and `oldValues` can be used to determine which individual expressions changed. For example `$scope.$watchGroup(['a', 'b'], fn)` would previously: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `a=2` | [2, undefined] | [1, undefined] | | `b=3` | [2, 3] | [1, undefined] | Now the `oldValue` will always equal the previous `newValue`: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `a=2` | [2, undefined] | [1, undefined] | | `b=3` | [2, 3] | [2, undefined] | Note the last call now shows `a === 2` in the `oldValues` array. This also makes the `oldValue` of one-time watchers more clear. Previously the `oldValue` of a one-time watcher would remain `undefined` forever. For example `$scope.$watchGroup(['a', '::b'], fn)` would previously: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `b=2` | [1, 2] | [undefined, undefined] | | `a=b=3` | [3, 2] | [1, undefined] | Where now the `oldValue` will will lways equal the previous `newValue`: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `b=2` | [1, 2] | [1, undefined] | | `a=b=3` | [3, 2] | [1, 2] |
Closes angular#16024 BREAKING CHANGE: (caused by c2b8fab) Previously when using `$watchGroup` the entries in `newValues` and `oldValues` represented the *most recent change of each entry*. Now the entries in `oldValues` will always equal the `newValues` of the previous call of the listener. This means comparing the entries in `newValues` and `oldValues` can be used to determine which individual expressions changed. For example `$scope.$watchGroup(['a', 'b'], fn)` would previously: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `a=2` | [2, undefined] | [1, undefined] | | `b=3` | [2, 3] | [1, undefined] | Now the `oldValue` will always equal the previous `newValue`: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `a=2` | [2, undefined] | [1, undefined] | | `b=3` | [2, 3] | [2, undefined] | Note the last call now shows `a === 2` in the `oldValues` array. This also makes the `oldValue` of one-time watchers more clear. Previously the `oldValue` of a one-time watcher would remain `undefined` forever. For example `$scope.$watchGroup(['a', '::b'], fn)` would previously: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `b=2` | [1, 2] | [undefined, undefined] | | `a=b=3` | [3, 2] | [1, undefined] | Where now the `oldValue` will always equal the previous `newValue`: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `b=2` | [1, 2] | [1, undefined] | | `a=b=3` | [3, 2] | [1, 2] |
Closes angular#16024 BREAKING CHANGE: (caused by c2b8fab) Previously when using `$watchGroup` the entries in `newValues` and `oldValues` represented the *most recent change of each entry*. Now the entries in `oldValues` will always equal the `newValues` of the previous call of the listener. This means comparing the entries in `newValues` and `oldValues` can be used to determine which individual expressions changed. For example `$scope.$watchGroup(['a', 'b'], fn)` would previously: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `a=2` | [2, undefined] | [1, undefined] | | `b=3` | [2, 3] | [1, undefined] | Now the `oldValue` will always equal the previous `newValue`: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `a=2` | [2, undefined] | [1, undefined] | | `b=3` | [2, 3] | [2, undefined] | Note the last call now shows `a === 2` in the `oldValues` array. This also makes the `oldValue` of one-time watchers more clear. Previously the `oldValue` of a one-time watcher would remain `undefined` forever. For example `$scope.$watchGroup(['a', '::b'], fn)` would previously: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `b=2` | [1, 2] | [undefined, undefined] | | `a=b=3` | [3, 2] | [1, undefined] | Where now the `oldValue` will always equal the previous `newValue`: | Action | newValue | oldValue | |----------|------------|------------| | (init) | [undefined, undefined] | [undefined, undefined] | | `a=1` | [1, undefined] | [undefined, undefined] | | `b=2` | [1, 2] | [1, undefined] | | `a=b=3` | [3, 2] | [1, 2] |
Uh oh!
There was an error while loading. Please reload this page.
I'm submitting a ...
Current behavior:
In 1.6, a watchGroup, every expression is watched individually, and this means the oldValue in the actionFn only changes if the underlying expression has changed. This means if expression 2 changes, but expression 1 does not, in the next actionFn invocation, the oldVal / newVal for expression 1 will be the same as in the last invocation. This is logical, but unexpected since watch and watchCollection don't have this behavior. It also makes it impossible to see which expression has changed before the current invocation.
In master, the behavior is consistent with watch / watchCollection in a way that the oldVal / newVal diff is based on the invocation of the actionFn. However, now the oldVal can be the same as the newVal once the expression has changed at least once, which will never happen in watchC or watch after the first invocation.
This was changed accidentially (I assume) in c2b8fabThe validity of the 1.6 behavior has been discussed and approved here #8671 (comment)Expected / new behavior:
Either:revert the changeMinimal reproduction of the problem with instructions:
http://plnkr.co/edit/sFO6B2zUhRwwF9bkrxe3?p=preview
Angular version: master
Browser: [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
Anything else:
The text was updated successfully, but these errors were encountered: