Skip to content

Instantly share code, notes, and snippets.

@joebalancio
Last active August 29, 2015 14:21
Show Gist options
  • Save joebalancio/23fb5879ecbe16c7c055 to your computer and use it in GitHub Desktop.
Save joebalancio/23fb5879ecbe16c7c055 to your computer and use it in GitHub Desktop.
Overriding default behavior in Mio using wrapper Resources
/**
* I want to be able to post a list of items, filter out relevant items, then continue with the post
* Afterwards I want to get the collection that was just created and add some stuff to it
*
* 1. Post list
* 2. Filter items from list
* 3. Continue with post
* 4. Add stuff to collection after
*/
var mio = require('mio')
var Item = mio.Resource.extend({
attributes: {
id: {
primary: true
},
foo: {}
}
})
Item.Collection.hook('collection:post', function (data, cb) {
// Stuck at #2
// This doesn't work because data is a reference
data = data.filter(function (item) {
return item.bad
})
cb()
})
Item.Collection.hook('collection:post', function (data, cb) {
// `data` is a reference and needs to be modified in-array because this reference gets passed around
var filtered = data.filter(function (item) {
return item.bad
})
while (filtered.length) {
data.splice(data.indexOf(filtered.pop()), 1)
}
// Ok, now I'm ready to continue to the next hook (mio-mongo)
// At this point I'm stuck at #3
// Can't call Item.Collection.post(data, cb) because it will execute this current hook again which is not what we wanted
cb()
})
// To avoid a wrapper Resource (unless it is the intention), mio needs to implement after callbacks
Item.Collection.hook('collection:post', function (data, cb) {
// `data` is a reference and needs to be modified in-array because this reference gets passed around
var filtered = data.filter(function (item) {
return item.bad
})
while (filtered.length) {
data.splice(data.indexOf(filtered.pop()), 1)
}
cb()
})
})
// If an after hook is available then we can modify the collection after data is retrieved. It also allows to fetch
// additional data not related to a the current resource
Item.Collection.hook('after:collection:post', function (collection, cb) {
items.forEach(function (item) {
// Modify the resource (as long as it's part of the schema)
item.extra = 'hello'
})
cb(null, items)
})
// Need to create a wrapper Resource
var WrapItem = Item.extend()
// Clear out existing hooks and listeners because they get copied over
WrapItem.hooks = []
WrapItem.listeners = []
// Add any events and hooks that we need
// WrapItem.on('request', modifyRequest)
WrapItem.Collection.hook('collection:post', function (data, cb) {
// `data` is a reference and needs to be modified in-array because this reference gets passed around
var filtered = data.filter(function (item) {
return item.bad
})
while (filtered.length) {
data.splice(data.indexOf(filtered.pop()), 1)
}
// Now we call the actual Item.Collection.post
Item.Collection.post(data, function (err, items) {
if (err) return cb(err)
items.forEach(function (item) {
// Modify the resource (as long as it's part of the schema)
item.extra = 'hello'
})
// Need to keep in mind that `this` is actually Item and not WrapItem so if there is a hook that tries to do something
// specifically with WrapItem like WrapItem.doSomething then it will fail.
cb(null, items)
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment