objectProperties.ts 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * @category Services/utils
  3. * @class ObjectProperties
  4. * Classe aidant à manipuler des Objets
  5. */
  6. import {AnyJson} from "~/types/types";
  7. class ObjectProperties {
  8. /**
  9. * What do you think about an option on find method to flatten the response, and an other one on update to nest the data before updating ?
  10. Example :
  11. * Flatten un objet nested en un objet avec un seul niveau avec des noms de propriétés transformées comme cela 'foo.bar'
  12. * L'objet passé en paramètre reste inchangé car il est cloné
  13. * @example cloneAndFlatten({ a: 1, b: { c: 2 }, d: { e: 3, f: { g: 4, h: 5 } }, i: { j: 6 } }, ['i']) => { a: 1, 'b.c': 2, 'd.e': 3, 'd.f.g': 4, 'd.f.h': 5, i: { j: 6 } } }
  14. * @param {AnyJson} object
  15. * @param {Array<string>} excludedProperties
  16. * @param excludedProperties
  17. * @return {AnyJson}
  18. */
  19. cloneAndFlatten(object:AnyJson, excludedProperties:Array<string> = []):AnyJson {
  20. if (typeof object !== 'object') {
  21. throw new Error('Expecting an object parameter');
  22. }
  23. return Object.keys(object).reduce((values: AnyJson, name: string) => {
  24. if (!object.hasOwnProperty(name)) return values;
  25. if (this.isObject(object[name])) {
  26. if (excludedProperties.indexOf(name) === -1) {
  27. let flatObject = this.cloneAndFlatten(object[name]);
  28. Object.keys(flatObject).forEach(flatObjectKey => {
  29. if (!flatObject.hasOwnProperty(flatObjectKey)) return;
  30. values[name + '.' + flatObjectKey] = flatObject[flatObjectKey];
  31. })
  32. } else {
  33. values[name] = this.clone(object[name]);
  34. }
  35. } else {
  36. values[name] = object[name];
  37. }
  38. return values;
  39. }, {});
  40. };
  41. /**
  42. * Trasnforme un objet flattened en un objet nested. L'objet passé en paramètre reste inchangé
  43. * @example cloneAndNest({ a: 1, 'b.c': 2, 'd.e': 3, 'd.f.g': 4, 'd.f.h': 5 } ) => { a: 1, b: { c: 2 }, d: { e: 3, f: { g: 4, h: 5 } } }
  44. * @param {AnyJson} object
  45. * @return {AnyJson}
  46. */
  47. cloneAndNest(object:AnyJson):AnyJson {
  48. if (typeof object !== 'object') {
  49. throw new Error('Expecting an object parameter');
  50. }
  51. return Object.keys(object).reduce((values, name) => {
  52. if (!object.hasOwnProperty(name)) return values;
  53. name.split('.').reduce((previous: AnyJson, current: string, index: number, list: Array<string>) => {
  54. if (previous != null) {
  55. if (typeof previous[current] === 'undefined') previous[current] = {};
  56. if (index < (list.length - 1)) {
  57. return previous[current];
  58. };
  59. previous[current] = object[name];
  60. }
  61. }, values)
  62. return values;
  63. }, {})
  64. }
  65. /**
  66. * Test si le paramètre est un objet
  67. * @param {AnyJson} value
  68. * @return {boolean}
  69. */
  70. isObject(value:any):boolean {
  71. if (value === null) return false;
  72. if (typeof value !== 'object') return false;
  73. if (Array.isArray(value)) return false;
  74. if (Object.prototype.toString.call(value) === '[object Date]') return false;
  75. return true;
  76. }
  77. /**
  78. * Clone l'objet et ces propriétés.
  79. * @param {Object} object
  80. * @return {Object}
  81. */
  82. clone(object: AnyJson): AnyJson {
  83. return Object.keys(object).reduce((values: AnyJson, name: string) => {
  84. if (object.hasOwnProperty(name)) {
  85. values[name] = object[name];
  86. }
  87. return values;
  88. }, {});
  89. }
  90. }
  91. export const $objectProperties = new ObjectProperties()