0

I'm building an api with NextJS and MongoDB. I do a basic setup on the top of the API file:

const { db } = await connectToDatabase();
const scheduled = db.collection('scheduled');

and I continue the code with my handler function:

export default async function handler(req, res) {
  otherFunctionCalls()
  ...
}

const otherFunctionCalls = async () => {
  ...
}

I know await will work only within an async function, but I would like to use the scheduled constant in other functions what the handler calls, that's why I need to call it on the top.

If I put the constant to every single function, then it's code duplication.

What's the best practice to access to scheduled constant? Should I add the otherFunctionCalls declaration into the handler function?

The complete error what I got:

Module parse failed: The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)
File was processed with these loaders:
 * ./node_modules/next/dist/build/babel/loader/index.js
You may need an additional loader to handle the result of these loaders.
Error: The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)
5
  • 2
    "I know await will work only within an async function..." Well, no, that's the point of top-level await -- it works at the top level of a module, outside an async function. Commented Nov 1, 2021 at 11:22
  • 1
    As the error message is telling you, you can only use top-level await if you enable it in the tool giving you that error, because it's still experimental in whatever tool is showing you that error message. (Top-level await is not experimental anymore in JavaScript itself, but it's quite new, and some tools are still catching up.) Commented Nov 1, 2021 at 11:24
  • @T.J.Crowder My bad, thanks for the heads-up Commented Nov 1, 2021 at 11:24
  • @T.J.Crowder yes, for that reason I would like to go with an other solution Commented Nov 1, 2021 at 11:25
  • Would you update the question to say that? I didn't understand that from the question at all. Thanks. :-) Commented Nov 1, 2021 at 11:26

1 Answer 1

1

In the comments you've said you want to find another solution rather than enabling the top-level await experiment in the tool you're using.

To do that, you'll have to adjust the module code to handle the fact that you don't have the scheduled collection yet, you just have a promise of it. If the only exported function is handler and all of the other functions are going to be called from handler, they it makes sense to handle that (no pun!) in handler, along these lines:

// A promise for the `scheduled` collection
const pScheduled = connectToDatabase().then(db => db.collection("scheduled"));

export default async function handler(req, res) {
    const scheduled = await pScheduled;
    await otherFunctionCalls(scheduled);
    // ...
}

const otherFunctionCalls = async (scheduled) => {
    // ...use `scheduled` here...
};

There are lots of ways you might tweak that, but fundamentally you'll want to get the promise (just once is fine) and await it to get its fulfillment value anywhere you need its fulfillment value. (For the avoidance of double: await doesn't re-run anything; if the promise is already fulfilled, it just gives you back the fulfillment value the promise already has.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.