fix(ivy): host-styling throws assert exception inside *ngFor (#35133)

Inside `*ngFor` the second run of the styling instructions can get into situation where it tries to read a value from a binding which has not yet executed. As a result the read is `NO_CHANGE` value and subsequent property read cause an exception as it is of wrong type.

Fix #35118

PR Close #35133
This commit is contained in:
Miško Hevery
2020-02-03 12:23:00 -08:00
parent a8609ba0ad
commit ab931cf872
3 changed files with 63 additions and 2 deletions

View File

@ -834,8 +834,20 @@ function findStylingValue(
const containsStatics = Array.isArray(rawKey);
// Unwrap the key if we contain static values.
const key = containsStatics ? (rawKey as string[])[1] : rawKey;
let currentValue = key === null ? keyValueArrayGet(lView[index + 1], prop) :
key === prop ? lView[index + 1] : undefined;
const isStylingMap = key === null;
let valueAtLViewIndex = lView[index + 1];
if (valueAtLViewIndex === NO_CHANGE) {
// In firstUpdatePass the styling instructions create a linked list of styling.
// On subsequent passes it is possible for a styling instruction to try to read a binding
// which
// has not yet executed. In that case we will find `NO_CHANGE` and we should assume that
// we have `undefined` (or empty array in case of styling-map instruction) instead. This
// allows the resolution to apply the value (which may later be overwritten when the
// binding actually executes.)
valueAtLViewIndex = isStylingMap ? EMPTY_ARRAY : undefined;
}
let currentValue = isStylingMap ? keyValueArrayGet(valueAtLViewIndex, prop) :
key === prop ? valueAtLViewIndex : undefined;
if (containsStatics && !isStylingValuePresent(currentValue)) {
currentValue = keyValueArrayGet(rawKey as KeyValueArray<any>, prop);
}