Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to export a variable that has value assigned aysnchronoulsy from a module in javascript?

consider this,

let value = "";
value = DATABASE_CALL();

module.exports = value;

When I require the above module in an another module and try to access the variable ‘value’, it is an empty string. How can I make the module.exports wait until the above DB call is completed and the variable is assigned a value?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

I assume value = DATABASE_CALL(); is a stand-in for asynchronous code. (If it were really synchronous as shown there, you’d just use it as the initializer value on value.)

You have a few options for exporting a value that’s only available asynchronously:

  1. Using ESM instead of CommonJS and using top-level await to prevent he module from finishing loading until the database operation is complete.

    export default await DATABASE_CALL();
    

    …where DATABASE_CALL returns a promise. (If it doesn’t already, you can wrap it.)

    Code using it won’t have to await it, but the module won’t finish loading until the DB op is complete, and won’t load at all if the DB op fails.

    This is really only appropriate if the module cannot be used at all without that value.

  2. Exporting a promise of the value (whether you switch to ESM or keep using CommonJS):

    module.exports = DATABASE_CALL();
    

    …where (again) DATABASE_CALL returns a promise.

    Code using it would have to await the promise (or use explicit .then/.catch).

  3. Using ESM instead of CommonJS and using a flag value to indicate "not ready yet" (null and undefined are useful for that) and updating the value when the database call is complete:

    export let value = null;
    // ...later when DATABASE_CALL is complete
    value = /*...the value from the DB...*/;
    

    ESM exports are live bindings, meaning that if the source module updates the variable, imports in other modules see the updated value.

    Note: You can only do this with named exports (value in the example), not default exports.

    Of course, that means the code using it has to allow for the possibility it’s not loaded yet.

  4. Exporting a function that provides the value, and that handles telling the caller the value isn’t available yet (implementation left to the reader).

There are probably other choices.

In cases where the module is worthless without the asynchronous information, I usually use #1. If not, I usually use #2.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading