I want to keep an history of changes made to an entity. For example, user entity:
{
name: 'Raz',
places_visited: [
{ city: 'Jerusalem', street: 'King David', house_number: 10 }
]
}
Then these kind of changes may apply:
{ city: 'Tel Aviv', street: 'Ibn Gabirol', house_number: 30 }I want to store those changes somehow, probably in the DB in a dedicated History collection that will store just any changes, regardless the user entity. The history collection may look like this and have these fields:
EntityType, EntityId, KeyChanged, OldValue, NewValue, ...(IAT and By and etc)
So in our case, the history collection should contain the next 4 rows:
{ city: 'Jerusalem', street: 'King David', house_number: 20 }, { city: 'Tel Aviv', street: 'Ibn Gabiron', house_number: 30 }, today, by admin,{ city: 'Jerusalem', street: 'King David', house_number: 20 }, today, by adminI have tried to use the JS new built in Proxy class:
const handler = {
get(target, prop) {
if (typeof target[prop] === "object" && target[prop] !== null) {
handler.prefix += `${prop}.`
return new Proxy(target[prop], handler)
}
return target[prop]
},
set(target, prop, newValue) {
const oldValue = target[prop]
target[prop] = newValue
if (oldValue !== newValue) {
console.log(oldValue, newValue)
}
return true
}
}
const proxy = new Proxy(user, handler)
However, when using methods like push, unshift or so, are getting messy and the tracking is getting ruined. Also, the "condenced" style is not applying, like the "places_visited.0" - just the primitive value instead.
How this can be achieved?
Basic:
For simpler applications, you could set watchpoints in the Sources tab (top of the left pane) in the DevTools window on Chrome (accessible via Inspect on the right-click menu), though this has the downside of needing to watch the objects manually within closures. That may be good enough as a quick check for your use case if you're well-aware of when and how in the code the object changes.
Intermediate:
If you want to get into more longitudinal tracking of object changes (including mutations), a teammate recently introduced me to the Redux DevTools extension for Chrome, FireFox, and subsequent forks of these two browsers. As an extension, it's a more lightweight version of the NPM package of the same name that doesn't require installation in your yarn, etc. assembly.
Note that it was designed and is most helpful for Redux, but per the documentation, it's possible to use with other frameworks as well.
Advanced:
The more advanced capabilities provided by a full install of the redux-devtools package give access to customizable monitors tuneable to a variety of components, allowing you to orchestrate debug-level logging within normal runtime operation of the app.