object/update.js

  1. import fpUpdate from 'lodash/fp/update'
  2. import isFunction from 'lodash/isFunction'
  3. import { lodashFpConvertOptions } from '../consts'
  4. const rawUpdate = fpUpdate.convert(lodashFpConvertOptions)
  5. /**
  6. * Internal version of <code>update</code> without support of <code>updater</code> only.
  7. * @memberof object
  8. * @param {Object} object The object to modify.
  9. * @param {Array|string} path The path of the property to set.
  10. * @param {function} updater The function to produce the updated value.
  11. * @param {...*} args The remaining args.
  12. * @return {Object} Returns the updated object.
  13. * @since 0.1.5
  14. * @private
  15. */
  16. export const updatePassingArgs = (object, path, updater, ...args) => rawUpdate(object, path, v => updater(v, ...args))
  17. /**
  18. * Updates the value at <code>path</code> of <code>object</code> using the <code>updater</code> function.<br/>
  19. * The updater is invoked with <code>value</code> and <code>…args</code>.<br/>
  20. * <code>update</code> can be called with <code>updater</code> only, returning a function taking only <code>object</code>, <code>path</code> and <code>…args</code>.
  21. * @function update
  22. * @memberof object
  23. * @param {Object} [object] The object to modify.
  24. * @param {Array|string} [path] The path of the property to set.
  25. * @param {function} updater The function to produce the updated value.
  26. * @param {...*} args The remaining args.
  27. * @return {Object|function} Returns the updated object or the wrapped function.
  28. * @example <caption>Updating a prop</caption>
  29. * const inc = (v, i = 1) => v + i // this function increments a number with an optional value which defaults to 1
  30. * const object = { nested: { prop: 4 } }
  31. * update(object, 'nested.prop', inc) // => { nested: { prop: 5 } }
  32. * update(object, 'nested.prop', inc, 2) // => { nested: { prop: 6 } }
  33. * @example <caption>Wrapping an updater</caption>
  34. * const inc = (v, i = 1) => v + i // this function increments a number with an optional value which defaults to 1
  35. * const incProp = update(inc)
  36. * const object = { nested: { prop: 4 } }
  37. * incProp(object, 'nested.prop') // => { nested: { prop: 5 } }
  38. * incProp(object, 'nested.prop', 2) // => { nested: { prop: 6 } }
  39. * @see {@link https://lodash.com/docs#update|lodash.update} for more information.
  40. * @since 0.1.5
  41. */
  42. export default (...args) => {
  43. if (args.length === 1 && isFunction(args[0]))
  44. return (obj, path, ...rest) => updatePassingArgs(obj, path, args[0], ...rest)
  45. return updatePassingArgs(...args)
  46. }