diff --git a/addon/helpers/find-by.js b/addon/helpers/find-by.js index 030c3346..0e8f81df 100644 --- a/addon/helpers/find-by.js +++ b/addon/helpers/find-by.js @@ -1,6 +1,6 @@ import { helper } from '@ember/component/helper'; import { isEmpty } from '@ember/utils'; -import { A as emberArray } from '@ember/array'; +import { get } from '@ember/object'; import asArray from '../utils/as-array'; export function findBy([byPath, value, array]) { @@ -8,7 +8,9 @@ export function findBy([byPath, value, array]) { return []; } - return emberArray(asArray(array)).findBy(byPath, value); + return asArray(array).find((item) => { + return get(item, byPath) === value; + }); } export default helper(findBy); diff --git a/addon/helpers/includes.js b/addon/helpers/includes.js index c91c3940..dbcbaf3d 100644 --- a/addon/helpers/includes.js +++ b/addon/helpers/includes.js @@ -1,4 +1,3 @@ -import { A as emberArray } from '@ember/array'; import { isArray as isEmberArray } from '@ember/array'; import { helper } from '@ember/component/helper'; import asArray from '../utils/as-array'; @@ -9,10 +8,10 @@ export function includes(needleOrNeedles, haystack) { } let needles = isEmberArray(needleOrNeedles) ? needleOrNeedles : [needleOrNeedles]; - let haystackAsEmberArray = emberArray(asArray(haystack)); + let haystackArray = asArray(haystack); return asArray(needles).every((needle) => { - return haystackAsEmberArray.includes(needle); + return haystackArray.includes(needle); }); } diff --git a/addon/helpers/next.js b/addon/helpers/next.js index 9492a8c8..0d442671 100644 --- a/addon/helpers/next.js +++ b/addon/helpers/next.js @@ -1,9 +1,9 @@ import { helper } from '@ember/component/helper'; import getIndex from '../utils/get-index'; import { isEmpty } from '@ember/utils'; -import { A as emberArray } from '@ember/array'; import getValueArrayAndUseDeepEqualFromParams from '../-private/get-value-array-and-use-deep-equal-from-params'; import asArray from '../utils/as-array'; +import arrayAt from '../utils/array-at'; export function next(currentValue, maybeArray, useDeepEqual = false) { let array = asArray(maybeArray); @@ -14,7 +14,7 @@ export function next(currentValue, maybeArray, useDeepEqual = false) { return; } - return currentIndex === lastIndex ? currentValue : emberArray(array).objectAt(currentIndex + 1); + return currentIndex === lastIndex ? currentValue : arrayAt(array, currentIndex + 1); } export default helper(function(params) { diff --git a/addon/helpers/object-at.js b/addon/helpers/object-at.js index 547df354..a00da6a2 100644 --- a/addon/helpers/object-at.js +++ b/addon/helpers/object-at.js @@ -1,5 +1,6 @@ import { helper } from '@ember/component/helper'; -import { A, isArray as isEmberArray } from '@ember/array'; +import { isArray as isEmberArray } from '@ember/array'; +import arrayAt from '../utils/array-at'; export function objectAt(index, array) { if (!isEmberArray(array)) { @@ -8,7 +9,7 @@ export function objectAt(index, array) { index = parseInt(index, 10); - return A(array).objectAt(index); + return arrayAt(array, index); } export default helper(function([index, array]) { diff --git a/addon/helpers/previous.js b/addon/helpers/previous.js index ec4a8e18..67202d01 100644 --- a/addon/helpers/previous.js +++ b/addon/helpers/previous.js @@ -1,8 +1,8 @@ import { helper } from '@ember/component/helper'; import getIndex from '../utils/get-index'; import { isEmpty } from '@ember/utils'; -import { A as emberArray } from '@ember/array'; import getValueArrayAndUseDeepEqualFromParams from '../-private/get-value-array-and-use-deep-equal-from-params'; +import arrayAt from '../utils/array-at'; export function previous(currentValue, array, useDeepEqual = false) { let currentIndex = getIndex(array, currentValue, useDeepEqual); @@ -11,7 +11,7 @@ export function previous(currentValue, array, useDeepEqual = false) { return; } - return currentIndex === 0 ? currentValue : emberArray(array).objectAt(currentIndex - 1); + return currentIndex === 0 ? currentValue : arrayAt(array, currentIndex - 1); } export default helper(function(params) { diff --git a/addon/helpers/reverse.js b/addon/helpers/reverse.js index 0abe25fc..a1af8a2c 100644 --- a/addon/helpers/reverse.js +++ b/addon/helpers/reverse.js @@ -1,12 +1,12 @@ import { helper } from '@ember/component/helper'; -import { A as emberArray, isArray as isEmberArray } from '@ember/array'; +import { isArray as isEmberArray } from '@ember/array'; export function reverse([array]) { if (!isEmberArray(array)) { return [array]; } - return emberArray(array).slice(0).reverse(); + return array.slice(0).reverse(); } export default helper(reverse); diff --git a/addon/helpers/without.js b/addon/helpers/without.js index 67b7356a..4871686e 100644 --- a/addon/helpers/without.js +++ b/addon/helpers/without.js @@ -1,9 +1,5 @@ import { helper } from '@ember/component/helper'; -import { A as emberArray, isArray as isEmberArray } from '@ember/array'; - -function contains(needle, haystack) { - return emberArray(haystack).includes(needle); -} +import { isArray as isEmberArray } from '@ember/array'; export function without(needle, haystack) { if (!isEmberArray(haystack)) { @@ -12,13 +8,13 @@ export function without(needle, haystack) { if (isEmberArray(needle) && needle.length) { return haystack.reduce((acc, val) => { - return contains(val, needle) ? acc : acc.concat(val); + return needle.includes(val) ? acc : acc.concat(val); }, []); } - return emberArray(haystack).without(needle); + return haystack.filter(val => val !== needle); } export default helper(function([needle, haystack]) { return without(needle, haystack); -}); +}); \ No newline at end of file diff --git a/addon/utils/array-at.js b/addon/utils/array-at.js new file mode 100644 index 00000000..fe2eb972 --- /dev/null +++ b/addon/utils/array-at.js @@ -0,0 +1,12 @@ +// Array.at isn't universally supported yet https://caniuse.com/?search=Array.at +// from https://github.com/tc39/proposal-relative-indexing-method#polyfill +export default function arrayAt(array, n) { + // ToInteger() abstract op + n = Math.trunc(n) || 0; + // Allow negative indexing from the end + if (n < 0) n += array.length; + // OOB access is guaranteed to return undefined + if (n < 0 || n >= array.length) return undefined; + // Otherwise, this is just normal property access + return array[n]; +} diff --git a/tests/integration/helpers/includes-test.js b/tests/integration/helpers/includes-test.js index 5eebeb74..506e087c 100644 --- a/tests/integration/helpers/includes-test.js +++ b/tests/integration/helpers/includes-test.js @@ -51,7 +51,7 @@ module('Integration | Helper | {{includes}}', function(hooks) { assert.dom().hasText('true', 'should render true'); - run(() => this.get('wishlist').removeObject(games[0])); + run(() => this.set('wishlist', games.slice(1))); assert.dom().hasText('false', 'should render false'); diff --git a/tests/unit/utils/array-at-test.js b/tests/unit/utils/array-at-test.js new file mode 100644 index 00000000..85892d1f --- /dev/null +++ b/tests/unit/utils/array-at-test.js @@ -0,0 +1,19 @@ +import arrayAt from 'ember-composable-helpers/utils/array-at'; +import { module, test } from 'qunit'; + +module('Unit | Utility | array-at', function() { + + test('it works', function(assert) { + const val = {}; + assert.strictEqual(arrayAt([{}, {}, val], 2), val); + }); + + test('it works for negative values', function(assert) { + const val = {}; + assert.strictEqual(arrayAt([{}, val, {}], -2), val); + }); + + test('missing value return undefined', function(assert) { + assert.deepEqual(arrayAt([], 3), undefined); + }); +});