-
Notifications
You must be signed in to change notification settings - Fork 0
/
helpers.js
68 lines (60 loc) · 1.88 KB
/
helpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
module.exports = class Helpers {
constructor() {}
// Get all the paths in the given object as strings array
// eg. ["objA.objB.objC.field", "obj.objA.field"]
getAllPaths(o, p) {
const keys = Object.keys(o)
const prefix = p ? `${p}.` : ''
return keys.reduce((result, key) => {
let accPath = result
if (this.isObject(o[key])) {
accPath = accPath.concat(this.getAllPaths(o[key], prefix + key))
} else {
accPath.push(prefix + key)
}
return accPath
}, [])
}
getPathTo(field, obj) {
// Throw error for wrong arguments
if (!this.isObject(obj) || arguments.length !== 2) {
throw new Error(
`Bad arguments to "getPathTo" - Arguments passed: ${field}, ${obj}`,
)
}
const paths = this.getAllPaths(obj)
// Find the path contains given field
const containingPath = paths.filter((path) =>
path.split('.').includes(field),
)[0]
// Throw error if the path doesn't exist
if (!containingPath) {
throw new Error(
`[Error occured in function "getPathTo"] >>> "${field}" <<< does not exist in object.`,
)
}
// Slice the wanted part of containing path
const sliceIndex =
containingPath.split('.').findIndex((el) => el === field) + 1
const result = containingPath.split('.').slice(0, sliceIndex)
return result
}
getValueOf(field, obj) {
const path = this.getPathTo(field, obj)
const value = path.reduce((acc, key) => {
return acc && Object.prototype.hasOwnProperty.call(acc, key)
? acc[key]
: 'does not exist'
}, obj)
if (value === 'does not exist') {
throw new Error(
`[Error occured in function "getValueOf"] >>> "${field}" <<< does not exist in object.`,
)
} else {
return value
}
}
isObject(x) {
return Object.prototype.toString.call(x) === '[object Object]'
}
}