0

What's the best way to connect to MongoDB with typescript that reuses the existing connection. I recently migrated my JavaScript codebase to typescript and the MongoDB connection in typescript throws an error

Please I need how to connect with MongoDB driver with typescript in such a way that I can reuse the existing database connection or help me fix my connection problem

Here is the error from the code below (node:3732) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'conn' of undefined

import { MongoClient, Db } from "mongodb";

const { DATABASE_URL, DATABASE_NAME } = process.env;

type MongoConnection = {
  client: MongoClient;
  db: Db;
};

declare global {
  namespace NodeJS {
    interface Global {
      mongodb: {
        conn: MongoConnection | null;
        promise: Promise<MongoConnection> | null;
      };
    }
  }
}
let cached = global.mongodb;
async function connectToDatabase() {
  if (cached.conn) {
    return cached.conn;
  }

  if (!cached.promise) {
    const opts = {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    };

    cached.promise = MongoClient.connect(DATABASE_URL as string, opts).then(
      (client) => {
        return {
          client,
          db: client.db(DATABASE_NAME),
        };
      }
    );
  }
  cached.conn = await cached.promise;
  return cached.conn;
}

export { connectToDatabase };

1 Answer 1

1

Try this

After your statement let cached = global.mongodb; add these lines

if (!cached) {
  cached = global.mongodb = { conn: null, promise: null };
}

So it should look like this

import { MongoClient, Db } from "mongodb";

const { DATABASE_URL, DATABASE_NAME } = process.env;

type MongoConnection = {
  client: MongoClient;
  db: Db;
};

declare global {
  namespace NodeJS {
    interface Global {
      mongodb: {
        conn: MongoConnection | null;
        promise: Promise<MongoConnection> | null;
      };
    }
  }
}
let cached = global.mongodb;
if (!cached) {
  cached = global.mongodb = { conn: null, promise: null };
}

async function connectToDatabase() {
  if (cached.conn) {
    return cached.conn;
  }

  if (!cached.promise) {
    const opts = {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    };

    cached.promise = MongoClient.connect(DATABASE_URL as string, opts).then(
      (client) => {
        return {
          client,
          db: client.db(DATABASE_NAME),
        };
      }
    );
  }
  cached.conn = await cached.promise;
  return cached.conn;
}

export { connectToDatabase };

For the reasoning, you have extended the Global interface to include the conn and promise to mongodb but you forgot to initialize the cached variable with that object.

After setting cached to { conn: null, promise: null } you have set their initial value to be null.

And the handy if check before setting them to null is to make sure you don't set them to null all the time, I am guessing this is being hosted in a serverless environment where you want to reuse the connection.

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.