UNPKG

@talend/json-schema-form-core

Version:

JSON-Schema and JSON-UI-Schema utilities for form generation.

75 lines (62 loc) 2.27 kB
import * as sfPath from './sf-path'; const numRe = /^\d+$/; /** * @description * Utility method to access deep properties without * throwing errors when things are not defined. * Can also set a value in a deep structure, creating objects when missing * ex. * var foo = Select('address.contact.name',obj) * Select('address.contact.name',obj,'Leeroy') * * @param {string} projection A dot path to the property you want to get/set * @param {object} obj (optional) The object to project on, defaults to 'this' * @param {Any} valueToSet (opional) The value to set, if parts of the path of * the projection is missing empty objects will be created. * @returns {Any|undefined} returns the value at the end of the projection path * or undefined if there is none. */ export function select(projection, obj, valueToSet) { if (!obj) { obj = this; } // Support [] array syntax let parts = typeof projection === 'string' ? sfPath.parse(projection) : projection; if (typeof valueToSet !== 'undefined' && parts.length === 1) { // special case, just setting one variable obj[parts[0]] = valueToSet; return obj; } if (typeof valueToSet !== 'undefined' && typeof obj[parts[0]] === 'undefined') { // We need to look ahead to check if array is appropriate obj[parts[0]] = parts.length > 2 && numRe.test(parts[1]) ? [] : {}; } let value = obj[parts[0]]; for (let i = 1; i < parts.length; i++) { // Special case: We allow JSON Form syntax for arrays using empty brackets // These will of course not work here so we exit if they are found. if (parts[i] === '') { return undefined; } if (typeof valueToSet !== 'undefined') { if (i === parts.length - 1) { // last step. Let's set the value value[parts[i]] = valueToSet; return valueToSet; } else { // Make sure to create new objects on the way if they are not there. // We need to look ahead to check if array is appropriate let tmp = value[parts[i]]; if (typeof tmp === 'undefined' || tmp === null) { tmp = numRe.test(parts[i + 1]) ? [] : {}; value[parts[i]] = tmp; } value = tmp; } } else if (value) { // Just get nex value. value = value[parts[i]]; } } return value; }