diff --git a/packages/core/src/data_sources/index.ts b/packages/core/src/data_sources/index.ts index 9a216b3a4..b9d1cbc9b 100644 --- a/packages/core/src/data_sources/index.ts +++ b/packages/core/src/data_sources/index.ts @@ -24,7 +24,7 @@ import { ItemManagerModule, ModuleConfig } from '../abstract/Module'; import { AddOptions, collectionEvents, ObjectAny, RemoveOptions } from '../common'; import EditorModel from '../editor/model/Editor'; -import { get, stringToPath } from '../utils/mixins'; +import { get, set, stringToPath } from '../utils/mixins'; import DataRecord from './model/DataRecord'; import DataSource from './model/DataSource'; import DataSources from './model/DataSources'; @@ -95,8 +95,11 @@ export default class DataSourceManager extends ItemManagerModule { return (index && index == length ? object : undefined) ?? def; }; +export const set = (object: ObjectAny, path: string | string[], value: any): boolean => { + if (!isObject(object)) return false; + const paths = castPath(path, object); + const length = paths.length; + const lastIndex = length - 1; + let index = -1; + let nested = object; + + while (nested != null && ++index < length) { + const key = paths[index]; + let newValue = value; + + if (index != lastIndex) { + const objValue = nested[key]; + newValue = isObject(objValue) ? objValue : !isNaN(+paths[index + 1]) ? [] : {}; + } + nested[key] = newValue; + nested = nested[key]; + } + return true; +}; + export const serialize = (obj: ObjectAny) => JSON.parse(JSON.stringify(obj)); export const isBultInMethod = (key: string) => isFunction(obj[key]); diff --git a/packages/core/test/specs/data_sources/index.ts b/packages/core/test/specs/data_sources/index.ts index 23f898bad..efc505307 100644 --- a/packages/core/test/specs/data_sources/index.ts +++ b/packages/core/test/specs/data_sources/index.ts @@ -113,7 +113,10 @@ describe('DataSourceManager', () => { // Update array item expect(dsm.setValue('ds1.id4.metadata.roles[1]', 'editor')).toBe(true); - expect(dsm.getValue('ds1.id4.metadata.roles[1]')).toBe('editor'); + expect(dsm.getValue('ds1.id4.metadata')).toEqual({ + address: { city: 'NewCity' }, + roles: ['admin', 'editor'], + }); // Set entirely new nested object const newAddress = { city: 'AnotherCity', country: 'SomeCountry' };