简体   繁体   中英

NEXT.JS: Can't connect to mongoDB Database using getInitialProps

I'm trying to connect to my sample mongoDB collection using getInitialProps inside my _app.js but I'm having this issue of Module not found: Can't resolve 'dns'

_app.js

import { connectToDatabase } from '../middlewares/mongodb';

function MyApp({ Component, pageProps, prop }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

MyApp.getInitialProps = async (appContext) => {
  const { db } = await connectToDatabase();
  const data = await db
    .collection('listingsAndReviews')
    .find({})
    .limit(10)
    .toArray();

  const prop = JSON.parse(JSON.stringify(data));
  return { ...prop };
};

getInitialProps runs on the server during initial page load and on the client during client navigations. As such getInitialProps should contain isomorphic code - code able to run in both server and client environments.

In your case you have code that requires a Node.js environment (server), and as such will fail when running on the browser.


A possible solution is to move your database fetching logic to an API route.

// pages/api/listings

export const fetchDbData = async () => {
    const { db } = await connectToDatabase();
    const data = await db
        .collection('listingsAndReviews')
        .find({})
        .limit(10)
        .toArray();
    return JSON.parse(JSON.stringify(data));
}

export default async (req, res) => {
    const data = await fetchDbData()
    res.status(200).json(data)
}

In your getInitialProps you can then call the fetchDbData logic directly when it's running on the server, or make an API call when it's running on the client.

import { fetchDbData } from './api/listings';

MyApp.getInitialProps = async (appContext) => {
    let prop;

    if (appContext.ctx.req) { // Checks if running on server
        prop = await fetchDbData(); // Call logic directly on the server
    } else {
        const res = await fetch('/api/listings'); // Make API call on the client
        prop = await res.json();
    }

    return { ...prop };
};

This ensures your database fetching logic will always run in the server environment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM