diff --git a/packages/@ember/-internals/metal/lib/chain-tags.ts b/packages/@ember/-internals/metal/lib/chain-tags.ts index ac20aad1e2f..eaea2d8a3de 100644 --- a/packages/@ember/-internals/metal/lib/chain-tags.ts +++ b/packages/@ember/-internals/metal/lib/chain-tags.ts @@ -125,12 +125,14 @@ export function getChainTagsForKey(obj: any, path: string) { for (let i = 0; i < arrLength; i++) { let item = objectAt(current as Array, i); - assert( - `When using @each to observe the array \`${current.toString()}\`, the items in the array must be objects`, - typeof item === 'object' - ); + if (item) { + assert( + `When using @each to observe the array \`${current.toString()}\`, the items in the array must be objects`, + typeof item === 'object' + ); - chainTags.push(tagForProperty(item, segment)); + chainTags.push(tagForProperty(item, segment)); + } } // Push the tag for the array length itself diff --git a/packages/@ember/-internals/runtime/tests/system/object/computed_test.js b/packages/@ember/-internals/runtime/tests/system/object/computed_test.js index be8ce95cbce..a4acd7e493c 100644 --- a/packages/@ember/-internals/runtime/tests/system/object/computed_test.js +++ b/packages/@ember/-internals/runtime/tests/system/object/computed_test.js @@ -457,6 +457,28 @@ moduleFor( assert.deepEqual(n.normalized, []); } + ['@test @each works on array with falsy values'](assert) { + let obj = EmberObject.extend({ + falsy: [null, undefined, false, '', 0, {}], + truthy: [true, 'foo', 123], + + falsyComputed: computed('falsy.@each.foo', () => { + assert.ok(true, 'falsy computed'); + }), + + truthyComputed: computed('truthy.@each.foo', () => { + assert.ok(true, 'truthy computed'); + }), + }).create(); + + // should throw no errors + obj.falsyComputed; + + expectAssertion(() => { + obj.truthyComputed; + }, /When using @each to observe the array `true,foo,123`, the items in the array must be objects/); + } + ['@test @each works with array-likes'](assert) { class ArrayLike { constructor(arr = []) {