Middleware utility for your Promises
Add pre and post middleware hooks to any function returning a Promise.
Read the post on Medium for some example.
Install
yarn add promised-hooks# or npm install promised-hooks --save`
Warp your Class/function/object
In order to add "pre" and "post" hooks to your promise you need to wrap their containing object (Class/function/object)
const hooks = ; // Class // some method that returns a Promise { ... } // Function {}Userprototype { ... } // Objectconst api = { ... }; // Wrap them to add "pre" and "post" hooks functionalities to their methodshooks;hooks;
Add middleware
pre() method
Adds a middelware to a promise that will be resolved or rejected before the method you are targetting. If the middelware rejects the Promise the original method is not executed. All the parameters sent to the original methods are available in the arguments of your middleware.
const hooks = ; // instance methods { ... } // works also with static methods static { ... } hooks; User; { // Access the arguments passed if needed const args = Arrayprototypeslice; // the scope (this) is the original Object wrapped // return a Promise return { // ... do some async stuff // then resolve or reject ; };}
Override
You can override the original arguments sent to the target method by resolving the middleware with an object containing an "__override" property.
User; { return { // ... ; // single argument // or ; // multi arguments }; /** * With the above override, the User.save() method will * receive those arguments instead of the one originally provided */}
post() method
Adds a middelware to be executed after the method you are targetting has been resolved. If the post middleware fails and rejects the Promise, the original Promise still resolves and the "post" errors are added the response (see below).
If you resolve your post middelware with an object containing an "__override" property (same as with "pre" hook), it will override the original response.
const hooks = ; // instance methods { ... } // works also with static (prototype) methods static { ... } hooks; // Several middleware can be added at once with an ArrayUser; { // data is the resolved value from the original promised method // or previous "post" hooks with an __override property // do some async stuff ... // and resolve a Promise return Promise; // If needed, you can override the response return Promise;} { return { // call async service... myApi; };}
Errors in "post" hooks
If one of the "post" hook fails and rejects its Promise then a Symbol is added on the response containing an Array with the errors. If the response is a primitive('string', 'number', boolean) then it is first converted to an object with a "result" property.
// For example, if the response returned by the targeted method is:'my response' // in case there are "post" hooks error it will be converted to: result: 'my response'
You access the errors Array with the hooks.ERRORS
Symbol.
const hooks = ; { ... } hooks; User; { return { // call async service... myApi; };} // Somewhere else in your code const user = ; user;
Scope (this)
The scope (this) of the middelware is set by default on the "wrapped" object. If you need to change it at runtime, you can declare a __scopeHook
function
on the object that will be called for each hook. This method, when called, receives 3 parameters:
- the target method
- the arguments (array of arguments sent to the targeted method)
- the hook method name
{} { console; // "save" console; // [123] console; // "hashPassword" // You can here return any object for the scope if hookMethod === 'hashPassword' return x: 'abc' ; // set the scope // If you return "undefined" the scope is not changed return undefined; }hooks; User; // ... const user = ;user;
Example
const hooks = ; { return resolve reject // ...your logic to save a user then ; ; } // works also on static methods static { ... } // Wrap the class to add hooks functionalitieshooks; // Hash a user password before savingUser; // Let's email our newly created userUser; // Create new userconst user = ; // Save useruser ;
Credits
I have been inspired by the hooks-fixed library from @vkarpov15 to write this small utility.