How to intercept & change set behavior?
I want to intercept get & set action to make the field value different in using & store, here are my code:
import { ActionTypes, Model } from 'mongorito'
// const defaults = (val, defaults) => typeof val === 'undefined' ? defaults : val
export function mapFields(mappings) {
const mapKeys = Object.keys(mappings)
return () => store => next => action => {
// action GET
if (action.type === ActionTypes.GET) {
let { fields } = store.getState()
const { key } = action
const { get: getter } = key ? mappings[key] : {}
// current key has getter and not null
if (getter) {
const val = fields[key]
return getter(val)
// get all fields
} else if (!key) {
fields = { ...fields }
return mapKeys.reduce((fields, key) => {
const val = fields[key]
fields[key] = mappings[key].get(val)
return fields
}, fields)
}
// action set
} else if (action.type === ActionTypes.SET) {
const { fields } = action
// set each field key with setter
for (let key in fields) {
const { set: setter } = mappings[key] || {}
if (setter) {
const val = fields[key]
fields[key] = setter(val)
}
}
}
return next(action)
}
}
class Users extends Model {
}
db.register(Users)
const Gender = {
MALE: 1,
FEMALE: 2,
UNKNOWN: 3,
}
const GenderReverse = {
1: 'MALE',
2: 'FEMALE',
3: 'UNKNOWN',
}
Users.use(mapFields({
gender: {
get: g => GenderReverse[g],
set: g => Gender[g],
},
}))
Then I reallize SET action is not only used by outside, but also inside when query from the db (in the constructor), so I couldn't tell which action is triggered by user input or query from the db.
Could you reformat your code or post it elsewhere? It's hard to follow it, because the indentation is broken and there's no spacing.
@vadimdemedes Sorry, added some annotations and a demo, hope it would be more clear.
Then I reallize SET action is not only used by outside, but also inside when query from the db (in the constructor), so I couldn't tell which action is triggered by user input or query from the db.
This is a good point, perhaps we'll need to introduce a specific action to dispatch on model initialization, like SEED or INITIAL_SET. @zaaack Any ideas for a better name?
@vadimdemedes I find out the feature I need is actual the virtual field feature in mongoose, and if I using another field name that doesn't exist in database, the problem solved.
But to solve the problem that there isn't a way to intercept query and persistence, I think we should let the models query from database using another action to initial, like INTERNAL_SET, not just in constructor, since this could still be called by user.