1

I'm creating a utilities class to handle some of our common functions to help reduce code copy/past in our modules: I created an exports module. All that's happening here is the export of an object which contains three functions.

module.exports = { 
    //retrieve a secret object from the AWS Secrets Manager
    //Parameter should be string value of the Secret ID

     getSecretIdAsync : async (param) => {
        return await new Promise((resolve, reject) => {
            scrtmgr.getSecretValue({SecretId: param}, (err, data) => {
                if(err){ 
                    reject(console.log('Error getting SecretId: ' + err, err.stack)); 
                } else{
                    if('SecretString' in data)
                    return resolve(JSON.parse(data.SecretString));
                }
             });
        });
    },

    //retrieves the AWS Paramter value from the AWS Paramter store
    //param should be string value of parameter hierarchical id

    getParameterValueFromStoreAsync : async (param) => {
        return await new Promise((resolve, reject) => {
            servmgr.getParameter({ Name: param}, (err, data) => {
                if(err){
                    reject(console.log('Error getting parameter: ' + err, err.stack));
                } 
                return resolve(data.Parameters.Value);
            });
        });
    },

    //retrieves the AWS Paramter "object" from the AWS Paramter store
    //param should be string value of parameter hierarchical id

    getParameterFromStoreAsync : async (param) => {
        return await new Promise((resolve, reject) => {
            servmgr.getParameter({ Name: param}, (err, data) => {
                if(err){
                    reject(console.log('Error getting parameter: ' + err, err.stack));
                } 
                return resolve(data.Parameters);
            });
        });
    }
}

Whenever I attempt to reference this module (say in my unit test I reference to module as:

let chai = require('chai');
let ut = require('../utilities.js');
let expect = chai.expect;
let aws = require('aws-sdk-mock');


describe('get parameter value', ()=>{

    it('resolves', (done)=>{
        var result = aws.mock('SSM', 'putParameter' , {"Name": "someName", "Value": "someValue"} );
        console.log('###### ' + JSON.stringify(ut));

        //console.log(obj);
    });
});

directory structure is utilities.js is located in the root, where the unit test is in a folder called test.

Whenever I try to import the utilities module the object it always empty. console.log('###### ' + JSON.stringify(ut)); generates ###### {}

I've exported individual functions in the past and I thought a group of functions would just require exporting a constructor.

Should multiple functions be exported in a different manner?

rlcrews
  • 3,482
  • 19
  • 66
  • 116
  • Do you have any circular dependencies between the modules? – Bergi Feb 25 '19 at 22:33
  • It's kinda weird path in `require()` that you use. Try `'./utilities'` if you use it in the same directory, or `'./../utilities' `if you use it in directory of your root directory.. – Guseyn Ismayylov Feb 25 '19 at 22:34
  • Btw, [don't use `return await`](https://stackoverflow.com/a/43985067/1048572), and [don't use `async function`s if you're returning a promise anyway](https://stackoverflow.com/questions/47880415/what-is-the-benefit-of-prepending-async-to-a-function-that-returns-a-promise) – Bergi Feb 25 '19 at 22:34
  • Also, I would recommend to use `const` instead of `let` in statements with `require()` – Guseyn Ismayylov Feb 25 '19 at 22:35

2 Answers2

4

MDN web docs offers an explanation for the behavior that you're seeing with JSON.strigify():

If undefined, a Function, or a Symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array).

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

edit: To clarify, I think you're exporting your utility functions correctly, but JSON.stringify() explicitly promises to not print functions.

Austin Hill
  • 119
  • 1
  • 7
  • Didn't know it, just confirmed it:```const x = { add: (a,b)=>a+b, sub: (a,b)=>a-b }; console.log(x); console.log(JSON.stringify(x));``` – Radu Luncasu Feb 25 '19 at 23:04
0

JSON.stringify doesn't serialize functions, if you need to do so you have to use a custom stringify function like this https://github.com/braceslab/json-stringify-extended

so, running

console.log(ut)

will print

{ getSecretIdAsync: [AsyncFunction: getSecretIdAsync],
  getParameterValueFromStoreAsync: [AsyncFunction: getParameterValueFromStoreAsync],
  getParameterFromStoreAsync: [AsyncFunction: getParameterFromStoreAsync] }

also, you can remove async and await from your functions, are useless using return new Promise

Simone Sanfratello
  • 1,520
  • 1
  • 10
  • 21