Reputation: 1415
I'm creating an interface and i need to run a check function before most methods, repeating the code over and over doesn't seem great. Is there a way I can run a function before a function?
Example of my current code
const uploadObject = async (object) => {
if (!ipfs) noProvider()
const buffer = objectToIpfsBuffer(object)
return ipfs.add(buffer)
}
const uploadString = async (string) => {
if (!ipfs) noProvider()
const buffer = stringToIpfsBuffer(string)
return ipfs.add(buffer)
}
const uploadBuffer = async (buffer) => {
if (!ipfs) noProvider()
return ipfs.add(buffer)
}
...
module.exports = {
uploadObject,
uploadString,
uploadBuffer,
...
}
The function I wish to run before is if (!ipfs) noProvider()
Upvotes: 1
Views: 1922
Reputation: 85102
I would probably just do it inline like you are, but to add another tool to your toolbelt: you could create a higher order function which takes in a function and the produces a new function that will do the check, and then do the work.
const checkIpfs = fxn => {
return (...args) => {
if (!ipfs) noProvider();
return fxn(...args);
}
}
const uploadObject = checkIpfs(async (object) => {
const buffer = objectToIpfsBuffer(object)
return ipfs.add(buffer);
});
const uploadString = checkIpfs(async (string) => {
const buffer = stringToIpfsBuffer(string)
return ipfs.add(buffer)
})
const uploadBuffer = checkIpfs(async (buffer) => {
return ipfs.add(buffer)
})
Upvotes: 2
Reputation: 4306
I see no issue with handling this the way you are; however, another approach to "hook" a property accessor is to use a Javascript Proxy.
The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).
When initializing a Proxy, you'll need to provide two function inputs:
target
: A target object (can be any sort of object, including a native array, a function or even another proxy) to wrap with Proxy.handler
: An object which is a placeholder object which contains traps for Proxy. All traps are optional. If a trap has not been defined, the default behavior is to forward the operation to the target.Here's an example:
const handler = {
get: function(target, prop, receiver) {
console.log('A value has been accessed');
return Reflect.get(...arguments);
}
}
const state = {
id: 1,
name: 'Foo Bar'
}
const proxiedState = new Proxy(state, handler);
console.log(proxiedState.name);
Upvotes: 1
Reputation: 71
You could use the Proxy Object that intercepts internal operation of other object.
var newObject = new Proxy(yourObject, {
get(target, prop, receiver){
if(['uploadObject', 'uploadString','uploadBuffer'].includes(prop) && type(target[prop]) == typeof(Function)) {
if (!ipfs) noProvider()
return Reflect.get(target, prop, receiver);
}
},
});
newObject.uploadObject();
Upvotes: 0