How To Set Up Mongoose With Typescript In NextJS ?
Last Updated :
30 Jun, 2024
Integrating Mongoose with TypeScript in a Next.js application allows you to harness the power of MongoDB while maintaining strong typing and modern JavaScript features. This guide will walk you through the process of setting up Mongoose with TypeScript in a Next.js project, ensuring your application is robust, scalable, and easy to maintain.
Prerequisites:
Steps to Create a NextJS App and Installing Module
Step 1: Initialize Next app and move to the project directory.
npx create-next-app my-next-app
cd my-next-app
Step 2: Install the required dependencies:
npm install tailwindcss react-hook-form mongoose mongodb
Project Structure
Project StructureStep 3: Setting Up MongoDB Connection inside .env file add:
MONGOB_URI = mongodb+srv://yourMongodbnab:[email protected]/DatabaseName
The Updated dependencies of your package.json file will look like this:
"dependencies": {
"mongoose": "^8.4.0",
"next": "13.4",
"react": "^18",
"react-dom": "^18"
}
Example: Beow is an example of uploading an Image to MongoDB using only NextJS 13.4.
JavaScript
// utils/connectToDb.ts
import mongoose, { Connection } from "mongoose";
import { GridFSBucket } from "mongodb";
let client: Connection | null = null;
let bucket: GridFSBucket | null = null;
const MONGODB_URI = process.env.MONGODB_URI as string;
interface DbConnection {
client: Connection;
bucket: GridFSBucket;
}
async function connectToDb(): Promise<DbConnection> {
if (client) {
return { client, bucket: bucket as GridFSBucket };
}
await mongoose.connect(MONGODB_URI);
client = mongoose.connection;
bucket = new mongoose.mongo.GridFSBucket(client.db, {
bucketName: "images",
});
console.log("Connected to the Database");
return { client, bucket };
}
export default connectToDb;
JavaScript
// utils/posts.ts
import mongoose, { Schema, Document, Model } from "mongoose";
interface IPost extends Document {
name: string;
imageUrl: string;
}
const postsSchema: Schema<IPost> = new Schema({
name: { type: String, required: true },
imageUrl: { type: String, required: true },
});
const PostModel: Model<IPost> = mongoose.models.Posts || mongoose.model<IPost>("Posts", postsSchema);
export default PostModel;
JavaScript
// api/route.tsx
import { NextResponse } from "next/server";
import { Readable } from "stream";
import Posts from "../../utils/posts";
import connectToDb from "../../utils/connectToDb";
export const revalidate = 0;
export const POST = async (req: Request) => {
const { client, bucket } = await connectToDb();
let name: string | undefined;
let image: string | undefined;
const formData = await req.formData();
console.log(formData);
for (const entries of Array.from(formData.entries())) {
const [key, value] = entries;
if (key === "name") {
name = value as string;
}
if (typeof value === "object" && value instanceof File) {
image = Date.now() + value.name;
console.log("done");
const buffer = Buffer.from(await value.arrayBuffer());
const stream = Readable.from(buffer);
const uploadStream = bucket.openUploadStream(image, {});
stream.pipe(uploadStream);
await new Promise((resolve, reject) => {
uploadStream.on('finish', resolve);
uploadStream.on('error', reject);
});
}
}
if (name && image) {
const newItem = new Posts({
name,
imageUrl: image,
});
await newItem.save();
} else {
return NextResponse.json(
{ msg: "Invalid form data" },
{ status: 400 }
);
}
return NextResponse.json({ msg: "ok" });
};
export const GET = async () => {
await connectToDb();
const posts = await Posts.find({});
return NextResponse.json(posts);
};
JavaScript
// components/newPost.tsx
"use client";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { useState, ChangeEvent } from "react";
import {
useForm,
SubmitHandler,
} from "react-hook-form";
interface FormData {
name: string;
imageUrl: FileList;
}
const NewPost = () => {
const { register, handleSubmit, reset } =
useForm<FormData>();
const [previewImage, setPreviewImage] =
useState<string | null>(null);
const router = useRouter();
const handleFileChange = (
e: ChangeEvent<HTMLInputElement>
) => {
const file = e.target.files
? e.target.files[0]
: null;
if (file) {
const reader = new FileReader();
reader.onloadend = () => {
setPreviewImage(
reader.result as string
);
};
reader.readAsDataURL(file);
} else {
setPreviewImage(null);
}
};
const onSubmit: SubmitHandler<
FormData
> = async (data) => {
const formData = new FormData();
formData.append("name", data.name);
if (data.imageUrl) {
for (
let i = 0;
i < data.imageUrl.length;
i++
) {
formData.append(
"imageUrl",
data.imageUrl[i]
);
}
}
await fetch("/api", {
method: "POST",
body: formData,
});
// Clear form data and reset input fields
setPreviewImage(null);
reset();
router.refresh();
};
return (
<main className="flex flex-col items-center
justify-between ">
<div className="max-w-md mx-auto">
<form
className="bg-white shadow-md
rounded px-8 pt-6 pb-8 mb-4"
onSubmit={handleSubmit(
onSubmit
)}
>
<div className="mb-4">
<label
className="block text-gray-700
text-sm font-bold mb-2"
htmlFor="input1"
>
Text Input 1
</label>
<input
className="shadow appearance-none
border rounded w-full py-2 px-3
text-gray-700 leading-tight
focus:outline-none focus:shadow-outline"
id="input1"
type="text"
placeholder="Enter text input 1"
{...register("name")}
/>
</div>
<div className="mb-4">
<label
className="block text-gray-700
text-sm font-bold mb-2"
htmlFor="fileInput"
>
File Input
</label>
<input
type="file"
accept="image/*"
className="file-input
file-input-bordered w-full max-w-xs"
id="fileInput"
{...register(
"imageUrl"
)}
onChange={
handleFileChange
}
/>
{previewImage && (
<Image
width={200}
height={200}
src={previewImage}
alt="Preview"
className="mt-2 w-full h-32 object-cover"
/>
)}
</div>
<div className="flex items-center justify-between">
<button
className="bg-blue-500 hover:bg-blue-700
text-white font-bold py-2 px-4
rounded focus:outline-none focus:shadow-outline"
type="submit"
>
Submit
</button>
</div>
</form>
</div>
</main>
);
};
export default NewPost;
JavaScript
//page.tsx
import NewPost from "./components/newPost";
import React from "react";
const Home: React.FC = () => {
return (
<div className="">
<div className="my-20">
<NewPost />
</div>
</div>
);
};
export default Home;
Start your Next.js development server:
npm run dev
Visit http://localhost:3000 in your browser to see the application in action.
Output:
OutputWhen you enter the file name, upload a file, and then click on the submit button, your file is successfully uploaded to MongoDB.
Conclusion
Overall, using Mongoose in Next.js empowers developers to build feature-rich, data-driven web applications with a modern frontend and a robust backend database, enabling seamless integration, efficient data management, and scalable architecture.
Similar Reads
How to Use NextJS in Typescript?
TypeScript enhances Next.js applications by adding static type checking and improves developer experience through type safety. Integrating TypeScript into your Next.js project helps catch errors early and improves code maintainability. It offers even greater productivity and robustness to your web d
5 min read
How to Use MathJS with TypeScript?
Math.js library can be use with TypeScript to handle various mathematical tasks while getting the benefits of TypeScriptâs type safety and autocompletion. Integrating Math.js into your TypeScript project allows you to perform arithmetic, algebra, statistics, and more, with the added advantage of Typ
3 min read
How to add TypeScript in Next.js ?
In this article, we will learn how to add TypeScript in Next.js.Why should we use TypeScript in our project? The fundamental concept of TypeScript is that it is type-strict, which means that each entity, be it a variable, a function, or an object has a definite data type. It allows minimum bugs in t
5 min read
How to update record without objectID in mongoose?
Mongoose is an ODM(Object Data Library) for MongoDB in Node JS that helps to write schema, validation and business logic in a simple way without the hassle of native MongoDB boilerplate. PrerequisitesUnderstanding of Mongoose and MongoDBData Modeling and Schema DesignMongoose Query MethodsApproach t
3 min read
How to use Typescript with native ES6 Promises ?
What is TypeScript? TypeScript is a free as well as an open-source programming language which was developed and is maintained by Microsoft. It actually provides highly productive development tools for JavaScript IDEs and also for practices like static checking. It even makes code easier to read and
3 min read
How to Setup a TypeScript Project?
In the world of modern web development, TypeScript has emerged as a powerful superset of JavaScript, offering static typing and improved tooling. Its strong typing system helps developers catch errors early during development, leading to more maintainable and scalable code. Whether you're starting a
2 min read
How to use TypeScript to build Node.js API with Express ?
TypeScript is a powerful version of JavaScript that incorporates static typing and other features, making it easy to build and maintain large applications. Combined with Node.js and Express, TypeScript can enhance your development experience by providing better type safety and tools. This guide will
4 min read
How to Make Next.js getStaticProps Work With Typescript?
Next.js is a popular React framework that developers use to create efficient server-rendered and static applications. One of the key features is to fetch data at build time, using a function called getStaticProps. This function enables developers to make static pages that are served fast to users, t
5 min read
How to install TypeScript ?
TypeScript is a powerful language that enhances JavaScript by adding static type checking, enabling developers to catch errors during development rather than at runtime. As a strict superset of JavaScript, TypeScript allows you to write plain JavaScript with optional extra features. This guide will
3 min read
How to Use MongoDB and Mongoose with Node.js ?
MongoDB is a popular NoSQL database that offers flexibility and scalability, making it an excellent choice for modern applications. Mongoose, a powerful ODM (Object Data Modeling) library, simplifies the interaction between MongoDB and Node.js by providing a schema-based solution for data validation
6 min read