The issue arises when the export function is triggered within the getStaticPaths() method, preventing the top-level

For my Next.js SSG (static site generation) app, I decided to optimize the database connection process by exporting a global promise from one file and then utilizing it in another file called controllers.js. This file houses multiple functions that directly interact with the database. These functions are then invoked within the getStaticProps() and getStaticPaths() methods of the respective components. Below is the implementation found in controllers.js:

import clientPromise from "./clientPromise";

let client;
let db;

(async function () {
  // We must place the await inside this async function that immediately executes instead of at the top level.
  client = await clientPromise;
  db = client.db("dev"); // using development database
})();

// Query the "technologies" collection:
export async function getTechnologies() {
  const technologies = await db
    .collection("technologies")
    .find({})
    .toArray();
  return JSON.parse(JSON.stringify(technologies));
}

// Query the "projects" collection:
export async function getProjects() {
  const projects = await db
    .collection("projects")
    .find({})
    .toArray();
  return JSON.parse(JSON.stringify(projects));
}

Here's a snippet showcasing how I'm leveraging these controllers:

// Working perfectly fine:
export async function getStaticProps() {
    const projects = await getProjects();

    return {
        props: { projects: projects },
    }
};

// Causing an error:
export async function getStaticPaths() {
    const projects = await getProjects();

    return {
        paths: [{ params: {_id: "placeholder"} }],
        fallback: false,
    };
}

The encountered error indicates that db is undefined and hence the method "collection" cannot be utilized on it. My analysis suggests that the anonymous async function, intended to execute immediately, does not run when calling getProjects() within getStaticPaths(), leading to db remaining undefined and causing the error. Interestingly, everything works as expected when invoking getProjects() in getStaticProps(). What could possibly be causing this issue?

Answer №1

In the event that db is not defined when you call getProjects, there are two potential scenarios:

  1. You are executing getProjects before await clientPromise has been resolved.
  2. The value returned by clientPromise is actually undefined.

Without more information, it is difficult to troubleshoot the second possibility, so let's focus on the first one for now.


(async function () {
  // Since await cannot be used at the top level/module scope, we need to use it inside an immediately invoked async function like this.
  client = await clientPromise;
  db = client.db("dev"); // using development database
})();

Your current setup includes an async function that returns a promise, which could be leveraged to determine when the result becomes available.

However, instead of managing the promise, you have chosen a fire-and-forget approach that relies on timing-dependent side effects.

Consider utilizing the returned promise for better control over timing.

const db = (async function () { 
    const client = await clientPromise;
    const devdb = client.db("dev");
    return devdb;
}();

With this change, db will immediately resolve to the desired value rather than remaining as undefined and potentially changing later.

Remember to adjust the rest of your module accordingly. For instance:

const projects = await db
    .collection("projects")

will need to be updated to:

const devdb = await db;
const projects = devdb.collection("projects")

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

ExpressJS and cookies - Struggling to initialize a cookie with express-cookie

I recently followed a tutorial on YouTube (https://youtu.be/hNinO6-bDVM?t=2m33s) that demonstrated how to display a cookie in the developer tools Application tab by adding the following code snippet to the app.js file: var session = require('express- ...

Is there a way to customize the animation for a button in material UI?

Trying to implement material UI in React and looking for a button that does not have the standard wave animation effect upon clicking, which you can see demonstrated here. Instead, I am searching for an animation that instantly fills the entire button wit ...

Guide on how to change a Next.js app deployed on Heroku to use HTTPS instead of HTTP?

I have a Next.js application deployed on Heroku. The app does not have a custom server, and accessing the site directly using the HTTPS URL works without any issues. However, I would like to set up a redirection from the HTTP URL to the HTTPS page for use ...

Trigger the submission of Rails form upon a change in the selected value within a dropdown form

I am working on a Rails application that has a table of leads. Within one of the columns, I display the lead's status in a drop-down menu. My goal is to allow users to change the lead's status by simply selecting a different value from the drop-d ...

What are some effective ways of using the parent, before, and children selectors?

<table> <tr><td><input type="text" value="123"></td><td><input class="here" type="text"></td></tr> <tr><td><input type="text" value="333"></td><td><input class=" ...

Angular's implementation of a web socket connection

I am facing an issue with my Angular project where the web socket connection only opens upon page reload, and not when initially accessed. My goal is to have the socket start as soon as a user logs in, and close when they log out. Here is the custom socke ...

Is there a way to prevent Chrome from highlighting text that matches the content of a `position: fixed` element?

I currently have a Toc element in my HTML with the property position: fixed. (This means it remains in place as you scroll) My goal is to prevent Chrome's Find Text feature from recognizing text within that Toc element. (Ideally using JavaScript) ...

The content located at “http://localhost:3000/public/static/” was restricted because of a mismatch in MIME type (text/html) which triggered the X-Content-Type-Options:nosniff protocol

https://i.stack.imgur.com/7Etn7.png Every time I try to run the server with nodemon, I keep encountering the error mentioned in the title. Below is the code snippet from the JavaScript file: const express = require('express') const path = requir ...

How to shuffle the elements of an array saved in a JSON file using discord.js

I've been working on a Discord bot as a way to learn more about Javascript. While creating a command that pulls random quotes from an array stored in a separate JSON file, I encountered an issue that has me stumped. var config = require("./settings.j ...

The Next JS application that was created using the output of 'export' is experiencing rendering issues

There seems to be an issue with the CSS rendering in a Next JS app built using the output: 'export' method. To Reproduce Create a new Next.js app Update the Next config to output as a static site Open the page from the out folder that was outpu ...

Enhance the Material UI Data Grid by customizing the toolbar's default slots with the option to disable the

https://i.stack.imgur.com/0YV9m.png Background In my current project, I am utilizing the Datagrid component from MUI [email protected]. I have disabled the column menu to display the toolbar at the top of the table instead of on individual columns. ...

Chatting with a Discord bot

I am currently working on a Discord bot that will execute specific functions based on the questions asked, most of which are yes or no queries. Upon responding with "yes," a particular function should be performed, while answering "no" would terminate t ...

Tips on creating type definitions for CSS modules in Parcel?

As someone who is brand new to Parcel, I have a question that may seem naive. In my project, I am using typescript, react, less, and parcel. I am encountering an error with typescript stating 'Cannot find module 'xxx' or its corresponding t ...

Transferring PHP variables to Javascript variables

I'm working on a basic php script that updates specific elements of a game through JavaScript. I've encountered an issue where the variable data doesn't seem to transfer when passing them from the script to the game using forms. Currently, t ...

What sets apart the process of installing AngularJS and AngularJS Core using NuGet?

I am curious about the difference between these two packages in my packages.config file. Would it be advisable to uninstall one of them? <?xml version="1.0" encoding="utf-8"?> <packages> <package id="angularjs" version="1.3.15" targetFr ...

ReactForms Deprication for NgModel

According to Angular, certain directives and features are considered deprecated and could potentially be removed in upcoming versions. In a hypothetical scenario, let's say I am using NgModel with reactive forms, which Angular has marked as deprecate ...

Updating Values in Nested Forms with Angular Reactive Form

I have been grappling with a form setup that looks something like this: itemEntities: [ {customisable: [{food: {..}, quantity: 1}, {food: {..}, quantity: 5}]}, {customisable: [{food: {..}, quantity: 0}]}, ] My challenge lies in trying to u ...

Is it possible for me to utilize NextJs API routes to manage both web and mobile applications?

Exploring ways to develop a web app in Nextjs and later transition to building a mobile app in React Native. Unsure about which api to utilize for both platforms. Can the Nextjs api effectively support both web and mobile apps? Is this feasible and advis ...

Additional NextJS routes are not functioning properly on the server side

Currently, I have successfully set up a NextJS app on Firebase and it's working well up to a certain point. I can easily access the app using this URL: Now, my next goal is to create a new route that I can access via: The current file structure of ...

Using VueJs, create a dynamic css class name to be applied inline

Can VueJs handle a scenario like this? Html: <div class="someStaticClass {{someDynamicClass}}">...</div> JS: var app = new Vue({ data: { someDynamicClass: 'myClassName' }, mounted: function() { ...