diff --git a/CHANGELOG.md b/CHANGELOG.md index a9206cd..cefd22f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) +## [0.2.7] - 2019-3-1 +### Changed +- [set](docs/set.md) only adds new items once at the end instead of progressively + ## [0.2.6] - 2019-2-17 ### Changed - Added ignoreKeys arg to [mapOwn](docs/mapOwn.md) and [clone](docs/clone.md) @@ -47,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [diffUpdate](docs/diffUpdate.md) - [intersection](docs/intersection.md) +[0.2.7]: https://github.com/DarrenPaulWright/object-agent/compare/v0.2.6...0.2.7 [0.2.6]: https://github.com/DarrenPaulWright/object-agent/compare/v0.2.5...0.2.6 [0.2.5]: https://github.com/DarrenPaulWright/object-agent/compare/v0.2.4...0.2.5 [0.2.4]: https://github.com/DarrenPaulWright/object-agent/compare/v0.2.3...0.2.4 diff --git a/docs/set.md b/docs/set.md index d400de3..1a05095 100644 --- a/docs/set.md +++ b/docs/set.md @@ -14,7 +14,7 @@ A javascript library for working with objects ## set(object, path, value) -Sets a nested value in an object. +Sets a nested value in an object. Keys in the path that don't exist at any point in the object will be created and added to the object once. **Kind**: global function diff --git a/package-lock.json b/package-lock.json index b0e6d37..b1ea46a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "object-agent", - "version": "0.2.6", + "version": "0.2.7", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -6334,6 +6334,12 @@ "isobject": "^3.0.1" } }, + "on-change": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/on-change/-/on-change-1.0.0.tgz", + "integrity": "sha512-RTMayeLraQr8N+7SNEbuMuYYUnwJ+Myp22gs0CjEvC25S2CEeevTWmTMMREIQMa1Pz5Zh/Jsorh/98ZfQidCyw==", + "dev": true + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", diff --git a/package.json b/package.json index 3020306..ca78841 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "object-agent", - "version": "0.2.6", + "version": "0.2.7", "description": "A javascript library for working with objects", "main": "src/index.js", "scripts": { @@ -68,6 +68,7 @@ "karma-mocha": "^1.3.0", "karma-webpack": "^3.0.5", "mocha": "^5.2.0", + "on-change": "^1.0.0", "test-runner-config": "^0.5.0", "wallaby-webpack": "^3.9.13", "webpack": "^4.29.3", diff --git a/src/set.js b/src/set.js index c98590d..611e15d 100644 --- a/src/set.js +++ b/src/set.js @@ -1,8 +1,8 @@ -import { isNumber } from 'type-enforcer'; +import { isInteger } from 'type-enforcer'; import parsePath from './utility/parsePath'; /** - * Sets a nested value in an object. + * Sets a nested value in an object. Keys in the path that don't exist at any point in the object will be created and added to the object once. * * @example * ``` javascript @@ -36,14 +36,28 @@ import parsePath from './utility/parsePath'; export default (object, path, value) => { path = parsePath(path); const last = path.length - 1; + const buildNew = (index) => isInteger(path[index + 1], true) ? [] : {}; + let baseItem; + let baseKey; + let baseValue; path.forEach((key, index) => { if (index === last) { object[key] = value; } - else if (!object[key]) { - object[key] = isNumber(path[index + 1], true) ? [] : {}; + else if (!(key in object)) { + if (!baseItem) { + baseItem = object; + baseKey = key; + baseValue = object = buildNew(index); + return; + } + object[key] = buildNew(index); } object = object[key]; }); + + if (baseItem) { + baseItem[baseKey] = baseValue; + } }; diff --git a/tests/set.Test.js b/tests/set.Test.js index e5c6646..0c50e13 100644 --- a/tests/set.Test.js +++ b/tests/set.Test.js @@ -1,4 +1,5 @@ import { assert } from 'chai'; +import onChange from 'on-change'; import { set } from '../src/'; describe('set', () => { @@ -133,7 +134,10 @@ describe('set', () => { }); it('should create objects and arrays then set the value', () => { - const object = {}; + const object = onChange({}, () => { + testVar++; + }); + let testVar = 0; const compare = { level1: [, , { // eslint-disable-line no-sparse-arrays level2: { @@ -142,9 +146,10 @@ describe('set', () => { }] }; - set(object, ['level1', 2, 'level2', 'level3'], 'meh'); + set(object, ['level1', '2', 'level2', 'level3'], 'meh'); assert.deepEqual(object, compare); + assert.equal(testVar, 1); }); });