angular: checkBindingNoChanges() attempting to check an index that does not exist
I’m submitting a…
[X] Bug report
Minimal reproduction of the problem with instructions
@lishichao1002 was kind enough to provide a repro case at http://plnkr.co/edit/FcuEqLLp8UeS5JXinsGi?p=preview which is similar to what I’m seeing (the error seems limited to cases where visibility of a component is toggled).
To see the error:
- Open the above Plunker
- Open the Chrome console
- Press “Open OK” to see that the overlay appears when it is opened with a direct function call
- Press “Open Appear Error” to see the
Cannot read property 'name' of undefined
error incheckBindingNoChanges()
when a binding is used to display the overlay.
Environment
Angular version: 5.2.2
Browser:
- [X] Chrome (desktop) version 64.0.3282.119
There seems to be a bug or unhandled error problem related to checkBindingNoChanges()
in /core/src/view/util.ts
.
The function looks like this:
export function checkBindingNoChanges(view, def, bindingIdx, value) {
var /** @type {?} */ oldValue = view.oldValues[def.bindingIndex + bindingIdx];
if ((view.state & 1 /* BeforeFirstCheck */) || !devModeEqual(oldValue, value)) {
var /** @type {?} */ bindingName = def.bindings[def.bindingIndex].name;
throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, def.nodeIndex), bindingName + ": " + oldValue, bindingName + ": " + value, (view.state & 1 /* BeforeFirstCheck */) !== 0);
}
}
During unit testing, I’m intermittently getting an error from checkBindingNoChanges()
: Cannot read property 'name' of undefined at checkBindingNoChanges
I was able to trigger this while “break on exceptions” was on, and took the following screenshot. checkBindingNoChanges()
tries to look up the binding name via def.bindings[def.bindingIndex].name
. But since def.bindingIndex
is currently 20, this evaluates to def.bindings[20].name
. But def.bindings
only has 10 elements in it, which results in the error I’m seeing.
Unfortunately, I have no real way to try and build a repro case for this, since I have no idea how Angular is getting into this state. But something seems to be getting out of sync somewhere, possibly the compiler? Should there at least be a check to make sure the index that is being checked exists?
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 12
- Comments: 19 (5 by maintainers)
Commits related to this issue
- fix(core): fix retrieving the binding name when an expression changes fixes #21735 fixes #21788 — committed to vicb/angular by vicb 6 years ago
- fix(core): fix retrieving the binding name when an expression changes (#21814) fixes #21735 fixes #21788 PR Close #21814 — committed to angular/angular by vicb 6 years ago
- fix(core): fix retrieving the binding name when an expression changes (#21814) fixes #21735 fixes #21788 PR Close #21814 — committed to jbogarthyde/angular by vicb 6 years ago
- fix(core): fix retrieving the binding name when an expression changes (#21814) fixes #21735 fixes #21788 PR Close #21814 — committed to leo6104/angular by vicb 6 years ago
Facing the same problem too. By the way, i use ChangeDetectorRef as a workaround to fix this
Using http://plnkr.co/edit/FcuEqLLp8UeS5JXinsGi?p=preview provided by @lishichao1002
I also met this problem。
I write a plunker to display this question http://plnkr.co/edit/FcuEqLLp8UeS5JXinsGi?p=preview
Upgrading to 5.2.9 fixed this for me, I was previously on 5.2.2.
Thanks, @vicb. Looks like the change has the lookup index use
bindingIdx
instead ofdef.bindingIndex
, which seems like it would make a big difference. From the debug screenshot I sent, that would change things to dodef.bindings[2].name
instead ofdef.bindings[20].name
. Which is obviously critical, since the former is a valid index while the latter is not!Is there a way to actually test this before a new version is pushed to NPM? I think there’s a way to point the dependency to Github in the package.json, but I’m not sure I’ve ever needed to do that. I’ll Google around and see if I can find the answer.
@vicb Updated to latest angular, still have the issue. Or has this not reached release yet (5.2.2)?
Message is still the same, pointing to the
bindingName = def.bindings[def.bindingIndex].name;
It’s a simple element:
The removing the ngClass row fixes it.