-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathcomputed.js
More file actions
66 lines (53 loc) · 1.95 KB
/
computed.js
File metadata and controls
66 lines (53 loc) · 1.95 KB
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
'use strict'
const debug = require('debug')('loopback:mixin:computed')
const _ = require('lodash')
const Promise = require('bluebird')
module.exports = (Model, options) => {
// Trigger a warning and remove the property from the watchlist when one of
// the property is not found on the model or the defined callback is not found
_.mapKeys(options.properties, (callback, property) => {
if (_.isUndefined(Model.definition.properties[property])) {
debug('Property %s on %s is undefined', property, Model.modelName)
}
if (typeof Model[callback] !== 'function') {
debug('Callback %s for %s is not a model function', callback, property)
}
})
debug('Computed mixin for Model %s with options %o', Model.modelName, options)
// The loaded observer is triggered when an item is loaded
Model.observe('loaded', (ctx, next) => {
// We don't act on new instances
if (ctx.isNewInstance) {
return next()
}
// Skip if specified in options
if (ctx.options.skipComputed) {
return next()
}
return Promise.map(Object.keys(options.properties), property => {
const callback = options.properties[property]
if (typeof Model[callback] !== 'function') {
debug('Function %s not found on Model', callback)
return false
}
debug('Computing property %s with callback %s', property, callback)
// `Promise.resolve` will normalize promises and raw values
return Promise
.resolve(Model[callback](ctx.data))
.then(value => (ctx.data[property] = value))
})
})
// The loaded observer is triggered when an item is loaded
Model.observe('before save', (ctx, next) => {
Object.keys(options.properties || {}).forEach(property => {
debug('Removing computed property %s', property)
if (ctx.instance) {
ctx.instance.unsetAttribute(property)
}
if (ctx.data) {
delete ctx.data[property]
}
})
return next()
})
}