<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: lonka pardhu</title>
    <description>The latest articles on DEV Community by lonka pardhu (@pardhu_99).</description>
    <link>https://dev.to/pardhu_99</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2117980%2Ff57ee828-55cf-4aed-bc61-25b1abc326a3.jpg</url>
      <title>DEV Community: lonka pardhu</title>
      <link>https://dev.to/pardhu_99</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pardhu_99"/>
    <language>en</language>
    <item>
      <title>I Fumbled on a Next.js MongoDB Error and Learned the Key Differences Between Mongoose and MongoClient</title>
      <dc:creator>lonka pardhu</dc:creator>
      <pubDate>Sat, 19 Oct 2024 17:53:32 +0000</pubDate>
      <link>https://dev.to/pardhu_99/i-fumbled-on-a-nextjs-mongodb-error-and-learned-the-key-differences-between-mongoose-and-mongoclient-1opb</link>
      <guid>https://dev.to/pardhu_99/i-fumbled-on-a-nextjs-mongodb-error-and-learned-the-key-differences-between-mongoose-and-mongoclient-1opb</guid>
      <description>&lt;p&gt;Recently, while building a Next.js application with MongoDB, I stumbled upon an error⚠️ that stumped me for a while&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MongooseError: Operation `spaces.insertOne()` buffering timed out after 10000ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was confusing because my connection seemed fine, and yet, I couldn't insert a document using Mongoose. This error taught me some valuable lessons about how Mongoose and MongoClient (MongoDB's native driver) handle database connections in different ways. Let’s dive into what happened, how I fixed it, and the key differences I learned between these two.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using MongoDB with Next.js
&lt;/h3&gt;

&lt;p&gt;I had a Next.js app where users could create "spaces" (think of them as categories or containers for user data). I wanted to store these spaces in MongoDB, and I had two ways to interact with the database:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;MongoClient (MongoDB's native driver): Offers low-level database interaction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mongoose: An Object Data Modeling (ODM) library that provides a schema-based solution for MongoDB. It’s great for validating, organizing, and manipulating data models.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  My Initial Approach
&lt;/h3&gt;

&lt;p&gt;In my Next.js project, I was using NextAuth.js (now Auth.js) for authentication and MongoDB for database storage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//MongoDB connection file (db.ts):

import { MongoClient, ServerApiVersion } from 'mongodb';

if (!process.env.MONGODB_URI) {
  throw new Error('Invalid/Missing environment variable: "MONGODB_URI"');
}

const uri = process.env.MONGODB_URI;
const options = {
  serverApi: {
    version: ServerApiVersion.v1,
    strict: true,
    deprecationErrors: true,
  },
};

let client: MongoClient;

if (process.env.NODE_ENV === 'development') {
  let globalWithMongo = global as typeof globalThis &amp;amp; { _mongoClient?: MongoClient };
  if (!globalWithMongo._mongoClient) {
    globalWithMongo._mongoClient = new MongoClient(uri, options);
  }
  client = globalWithMongo._mongoClient;
} else {
  client = new MongoClient(uri, options);
}

export default client;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;thats just as it is from the official docs of authjs &lt;a href="https://authjs.dev/getting-started/adapters/mongodb" rel="noopener noreferrer"&gt;Read here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;route handler&lt;/strong&gt;, I tried using Mongoose to create a new document, while also managing the connection with MongoClient:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Space from '@/models/space.model';
import client from '@/lib/db'; // MongoClient connection

export async function POST(req: Request) {
  const session = await auth(); // Authentication middleware

  if (!session || !session.user) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  try {
    const { spaceName, title, message, questions } = await req.json();

    if (!spaceName || !title || !message || !questions || !questions.length) {
      return NextResponse.json({ message: 'All fields are required' }, { status: 400 });
    }

    await client.connect(); // MongoClient connection

    const space = await Space.create({
      spaceName,
      spaceOwner: session.user.id,
      title,
      message,
      questions,
    });

    return NextResponse.json({ message: 'Space created successfully', spaceId: space._id }, { status: 201 });
  } catch (error) {
    return NextResponse.json({ message: 'Failed to create space' }, { status: 500 });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  This is when I hit the following error⚠️:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MongooseError: Operation `spaces.insertOne()` buffering timed out after 10000ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Root Cause
&lt;/h3&gt;

&lt;p&gt;After some digging, I realized that I was mixing up two different database management systems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MongoClient: This is the native MongoDB driver that works directly with MongoDB by establishing a raw connection to the database.&lt;/li&gt;
&lt;li&gt;Mongoose: An ODM that sits on top of MongoClient and provides schema-based models to interact with MongoDB.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MongoClient and Mongoose are not interchangeable. In my code, I was using client.connect() (MongoClient) to establish the connection but trying to interact with Mongoose models (Space.create()).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mongoose manages its own connection pooling and lifecycle. So, when I used client.connect() from MongoClient, Mongoose didn’t know about this connection, causing it to wait (or "buffer") until its own connection was established. This led to the buffering timeout error: Operation 'spaces.insertOne()' buffering timed out after 10000ms.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why It Worked with MongoClient but Not Mongoose
&lt;/h3&gt;

&lt;p&gt;When I switched to the following code, it worked without issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const db = (await client.connect()).db();

const space = await db.collection("spaces").insertOne({
  spaceName,
  spaceOwner: session.user.id,
  title,
  message,
  questions,
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Here, I was using MongoClient's native API directly, which correctly handled the connection because I used client.connect() to establish the connection and then interacted with the MongoDB collections.&lt;/li&gt;
&lt;li&gt;MongoClient doesn't depend on Mongoose's connection pool, so it worked as expected.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Mongoose Failed
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await client.connect(); // MongoClient connection

const space = await Space.create({
  spaceName,
  spaceOwner: session.user.id,
  title,
  message,
  questions,
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Mongoose was still in a buffering state because I hadn't initialized a Mongoose connection. Mongoose waits for its own connection before performing any operations on the model, which led to the timeout error.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fixing the Issue: Properly Managing Mongoose Connections
&lt;/h3&gt;

&lt;p&gt;To fix the issue, I had to properly establish a Mongoose connection and let Mongoose handle the database connection itself instead of using MongoClient. Here’s what I did:&lt;/p&gt;

&lt;h4&gt;
  
  
  Correct Mongoose Connection Setup (db.ts):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose from 'mongoose';

const MONGODB_URI = process.env.MONGODB_URI;

if (!MONGODB_URI) {
  throw new Error('Please define the MONGODB_URI environment variable');
}

let cached = global.mongoose;

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

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

  if (!cached.promise) {
    cached.promise = mongoose.connect(MONGODB_URI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    }).then((mongoose) =&amp;gt; {
      return mongoose;
    });
  }
  cached.conn = await cached.promise;
  return cached.conn;
}

export default connectToDatabase;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Updated Route Handler Using Mongoose:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Space from '@/models/space.model';
import connectToDatabase from '@/lib/db'; // Mongoose connection

export async function POST(req: Request) {
  const session = await auth(); // Authentication middleware

  if (!session || !session.user) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  try {
    const { spaceName, title, message, questions } = await req.json();

    if (!spaceName || !title || !message || !questions || !questions.length) {
      return NextResponse.json({ message: 'All fields are required' }, { status: 400 });
    }

    await connectToDatabase(); // Use Mongoose connection

    const space = await Space.create({
      spaceName,
      spaceOwner: session.user.id,
      title,
      message,
      questions,
    });

    return NextResponse.json({ message: 'Space created successfully', spaceId: space._id }, { status: 201 });
  } catch (error) {
    return NextResponse.json({ message: 'Failed to create space' }, { status: 500 });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Mongoose and MongoClient are not interchangeable:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;MongoClient: Best for low-level, direct interaction with MongoDB.&lt;/li&gt;
&lt;li&gt;Mongoose: Provides schema-based modeling and is more suitable for structured data interactions, but you need to establish its own connection using mongoose.connect().&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Use Mongoose with Mongoose models:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;If you're using Mongoose models like Space.create(), make sure you initialize the connection with Mongoose, not MongoClient.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Connection pooling:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Mongoose manages its own connection pooling. If you manually manage connections with MongoClient, Mongoose will not automatically know about this connection, leading to issues like buffering or timeouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Global connection caching:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;In Next.js, using global variables to cache your MongoDB connection (whether through MongoClient or Mongoose) is important in development mode to prevent creating multiple connections during hot module reloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Through this experience, I learned a lot about the internal workings of Mongoose and MongoClient. Understanding their differences and when to use each is crucial to avoiding connection-related errors. If you're using Mongoose, make sure to properly initialize the connection with Mongoose itself, rather than trying to use MongoClient alongside it.&lt;/p&gt;

&lt;p&gt;I hope this blog helps anyone who might be facing similar issues when dealing with Mongoose and MongoClient in a Next.js application. Understanding the differences between these tools can save a lot of time.&lt;/p&gt;

&lt;p&gt;Let me know if you have any questions or thoughts on this.🙌&lt;/p&gt;

&lt;p&gt;Btw I wrote this blog as part of sharing the learnings and challenges I'm facing while building my project and learning Next.js. If you're interested in what I'm working on or want to follow my journey, check out my &lt;a href="https://x.com/lonka_pardhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more updates and to see where it takes me .&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Before you can reach anything you have to believe it&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>mongoose</category>
      <category>mongoclient</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Next.js Client and Server Components: Your Guide to Clarity.</title>
      <dc:creator>lonka pardhu</dc:creator>
      <pubDate>Tue, 24 Sep 2024 11:02:29 +0000</pubDate>
      <link>https://dev.to/pardhu_99/nextjs-client-and-server-components-your-guide-to-clarity-3m64</link>
      <guid>https://dev.to/pardhu_99/nextjs-client-and-server-components-your-guide-to-clarity-3m64</guid>
      <description>&lt;p&gt;In this blog, you'll gain clarity on the often-confusing topic of client and server components in Next.js. We'll break down the differences, explain what each can and can't do, and show you where and how to use them in your projects. Whether you're just starting out or feeling stuck, this guide will help you confidently move forward with your Next.js development, ensuring you're equipped to build both the front and back ends of your applications efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client Components:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Rendered in the browser (Client-Side Rendering, or CSR).&lt;/li&gt;
&lt;li&gt;They can be interactive, handle user input (e.g., forms, buttons), and use browser APIs (like localStorage, window, document).&lt;/li&gt;
&lt;li&gt;They are hydrated (downloaded) to the client and run in the user’s browser after the initial page load.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Server components:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Rendered on the server (Server-Side Rendering, or SSR).&lt;/li&gt;
&lt;li&gt;They are faster for initial page loads since the HTML is generated on the server and sent to the browser.&lt;/li&gt;
&lt;li&gt;They cannot handle interactions, browser-specific APIs (e.g., window, document), or use client-side hooks like useState, useEffect.&lt;/li&gt;
&lt;li&gt;They are more suitable for static or pre-rendered content and data fetching.‎&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;‎ &lt;/p&gt;

&lt;h2&gt;
  
  
  What Can Be Done in Client and Server Components
&lt;/h2&gt;

&lt;p&gt;‎&lt;br&gt;
&lt;strong&gt;Client Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can manage state using hooks like useState, useEffect, useReducer.&lt;/li&gt;
&lt;li&gt;Can handle user interaction: forms, buttons, event listeners.&lt;/li&gt;
&lt;li&gt;Can access browser APIs: window, document, localStorage, etc.&lt;/li&gt;
&lt;li&gt;Can interact with external APIs from the client-side (e.g., using fetch or axios to call an API).&lt;/li&gt;
&lt;li&gt;Can trigger re-renders based on user actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Server component&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can perform server-side data fetching before sending the HTML to the browser.&lt;/li&gt;
&lt;li&gt;Can fetch data from databases or external APIs on the server.&lt;/li&gt;
&lt;li&gt;Can handle complex pre-rendering tasks (SSR, SSG).&lt;/li&gt;
&lt;li&gt;Cannot manage state or handle browser-based interactivity.&lt;/li&gt;
&lt;li&gt;Cannot directly access browser APIs like window or document.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;‎ &lt;/p&gt;
&lt;h2&gt;
  
  
  Client and Server Component Example.
&lt;/h2&gt;

&lt;p&gt;‎ &lt;br&gt;
&lt;strong&gt;Client component&lt;/strong&gt;&lt;br&gt;
To make a component run on the client, you must use the "use client" directive at the top of the component file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ClientComponent.js

"use client"; // This makes the component a Client Component

import { useState } from 'react';

export default function ClientComponent() {
  const [count, setCount] = useState(0);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;Increment&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;‎ &lt;br&gt;
&lt;strong&gt;Server component&lt;/strong&gt;&lt;br&gt;
Server components do not need the "use client" directive. By default, they are server-side components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// components/ServerComponent.js

export default async function ServerComponent() {
  const data = await fetch('https://api.example.com/data');
  const result = await data.json();

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Server-rendered Data:&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;{result.someValue}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;‎ &lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Use Client and Server Components
&lt;/h2&gt;

&lt;p&gt;‎ &lt;br&gt;
&lt;strong&gt;Client Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interactive elements: If your component requires user interaction (like buttons, forms, modals, etc.), it must be a client component.&lt;/li&gt;
&lt;li&gt;State management: If the component needs to track local state (useState, useEffect), such as handling form input, toggling UI elements, or fetching data on user action, it should be a client component.&lt;/li&gt;
&lt;li&gt;Browser APIs: Any use of browser-specific functionality (like window, localStorage, or document) must be in a client component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Server Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static or data-driven content: If a component fetches data and renders it without needing interaction (e.g., fetching product details from an API or database), it can be a server component.&lt;/li&gt;
&lt;li&gt;Content pre-rendering: For content that should be delivered already rendered to the browser to improve performance (such as blog posts, product pages, etc.).&lt;/li&gt;
&lt;li&gt;Avoiding large JavaScript bundles: Since server components don’t need hydration on the client, using them can reduce the amount of JavaScript that gets sent to the browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;‎ &lt;/p&gt;

&lt;h2&gt;
  
  
  Where to avoid using:
&lt;/h2&gt;

&lt;p&gt;‎ &lt;br&gt;
&lt;strong&gt;Client Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid putting unnecessary logic or data-fetching in client components that could be done on the server. This will reduce the bundle size and improve page load speed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Server Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid using server components for interactive content (e.g., buttons, form inputs, modals) or anything that requires state management, as server components can’t manage local state or handle client-side interaction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;‎ &lt;/p&gt;

&lt;p&gt;‎ For more detailed insights and a deeper understanding, visit these links&lt;br&gt;
 &lt;a href="https://nextjs.org/docs/app/building-your-application/rendering/server-components" rel="noopener noreferrer"&gt;server compoents&lt;/a&gt;&lt;br&gt;
&lt;a href="https://nextjs.org/docs/app/building-your-application/rendering/client-components" rel="noopener noreferrer"&gt;client components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;‎ &lt;/p&gt;

&lt;p&gt;‎ &lt;br&gt;
&lt;a href="https://x.com/lonka_pardhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>servercomponent</category>
      <category>clientcomponent</category>
      <category>fullstackdevelopment</category>
    </item>
  </channel>
</rss>
