Source

utils/object.js

/**
 * @namespace Utils
 * @category Utils
 * @module Object*/

import {
  formatDatetimeWithSeconds,
  formatTimeWithSeconds,
} from '@/utils/dates.js'

/**
 *
 * Get nested value from object
 * @param {Object} value
 * @param {String/Array} path
 * @param {Any} defaultValue
 * @param {Function} options.transform Transform result
 * @param {Boolean} options.allowZero Allow zero as result (Will not fallback to default value if zero)
 * @param {Function} defaultValue Allow customize default value on the fly with a handler
 * @example
 * console.log(getNestedValue({foo:{speed:65}},'foo.speed'))
 * //65
 *
 * console.log(getNestedValue({foo:{}},'foo.speed'))
 * // (empty string)
 *
 * console.log(getNestedValue({foo:{}},'foo.speed', '0'))
 * //0 (default value)
 *
 * console.log(getNestedValue({foo:{dhh:'2021-10-05',date:'2020-10-05'}},['foo.dh','foo.date']))
 * //2020-10-05 (fallback to second path given)
 *
 * console.log(getNestedValue({foo:[10,11]},'foo.1'))
 * //11
 *
 * console.log(getNestedValue({foo:[{name:"FOO"},{name:"BAR"}]},'foo.1.name'))
 * //BAR
 *
 * @returns {Mixed} Nested value or default value
 */
export function getNestedValue(
  value,
  path = '',
  defaultValue = '',
  options = {}
) {
  if (!path) {
    console.trace('Path required')
  }
  options.rootValue = options.rootValue || value
  let defaultValueFn = (val) =>
    options.defaultValue ? options.defaultValue(val) : defaultValue

  if (path instanceof Array) {
    let response = ''
    path.forEach((currPath) => {
      response = response || getNestedValue(value, currPath)
    })
    return options.transform
      ? options.transform(
          response || defaultValueFn(response),
          response || defaultValueFn(response),
          options.rootValue
        )
      : response || defaultValueFn(response)
  }

  if (value != null && path.indexOf('.') !== -1) {
    let leftString = path.split('.')[0]
    if (value instanceof Array && !isNaN(parseInt(value[leftString]))) {
      value =
        value[parseInt(value[path])] ||
        defaultValueFn(value[parseInt(value[path])])
    } else {
      value = value[leftString] || defaultValueFn(value[leftString])
    }
    return getNestedValue(
      value,
      path
        .split('.')
        .splice(1, path.split('.').length - 1)
        .join('.'),
      defaultValue,
      options
    )
  } else {
    if (
      value != null &&
      value instanceof Array &&
      !isNaN(parseInt(value[path]))
    ) {
      return options.transform
        ? options.transform(
            value[parseInt(path)],
            value[parseInt(path)],
            options.rootValue
          )
        : value[parseInt(path)]
    }

    let originalValue = !!value && value[path]
    if (options.allowZero && value != null && value[path] === 0) {
      value = 0
    } else {
      value =
        (value != null && value[path]) ||
        defaultValueFn(value != null && value[path])
    }

    return options.transform
      ? options.transform(value, originalValue, options.rootValue)
      : value
  }
}

/**
 *
 * @param {Object} value i.g {foo:{bar:{api_datetime:"2019-11-12 13:30:00"}}}
 * @param {String} path i.g foo.bar.api_datetime
 * @param {String} defaultValue
 * @returns i18n formatted date
 */
export function getNestedValueFormattedDatetimeMilliseconds(
  value,
  path,
  defaultValue = '',
  options = {}
) {
  return getNestedValue(value, path, null)
    ? formatDatetimeWithSeconds(getNestedValue(value, path, defaultValue), {
        inputFormat: options.inputFormat || 'YYYY[-]MM[-]DD HH:mm:ss',
      })
    : defaultValue
}

export function getNestedValueFormattedTime(value, path, defaultValue = '') {
  let v = getNestedValue(value, path, defaultValue)
  return v ? formatTimeWithSeconds(v) : defaultValue
}

/*
 * Used by Diagnostic Module - Analyze segment
 * @todo Move to utils
 * @param {Object} rawData API rawData
 * @param {Object} normalizedConfiguration Convertion table
 * @example
 *
 * normalizeObject({foo:1},{
 *   foo:{
 *       key:'bar',
 *       transformKey:'barFormatted',
 *       transform: value => value * 3
 *   }
 * })
 * Output: {barFormatted: 3, bar: 1}
 *
 * @returns
 */
window.objectNormalizeObject = normalizeObject
export function normalizeObject(rawData, normalizedConfiguration) {
  return Object.keys(rawData).reduce((acum, key) => {
    if (
      typeof normalizedConfiguration[key] === 'undefined' ||
      normalizedConfiguration[key] === undefined
    ) {
      acum[key] = rawData[key] //As it is (tor/ana)
      return acum
    }

    if (typeof normalizedConfiguration[key] === 'string') {
      acum[normalizedConfiguration[key]] = rawData[key]
    } else {
      if (normalizedConfiguration[key].key) {
        if (!normalizedConfiguration[key].transform) {
          acum[normalizedConfiguration[key].key] = rawData[key]
        } else {
          if (normalizedConfiguration[key].transformKey) {
            acum[normalizedConfiguration[key].transformKey] =
              normalizedConfiguration[key].transform(rawData[key], rawData)
            acum[normalizedConfiguration[key].key] = rawData[key]
          } else {
            acum[normalizedConfiguration[key].key] = normalizedConfiguration[
              key
            ].transform(rawData[key], rawData)
          }
        }
      }
    }
    return acum
  }, {})
}