Logo

dev-resources.site

for different kinds of informations.

Getting Started with Mongoose

Published at
6/28/2024
Categories
mongoose
node
mongodb
backenddevelopment
Author
mbugua70
Author
8 person written this
mbugua70
open
Getting Started with Mongoose

PAGE CONTENT

Introduction to Mongoose

Mongoose is an ODM (Object Data Modeling) library designed to streamline the interaction between your MongoDB database and Node.js applications.It is designed to work with asynchronous environments and offers a powerful set of features that simplify data manipulation and validation.

Connecting to the database

Before diving into Mongoose, you need to establish a connection to your MongoDB database. Here’s a step-by-step guide to get you started:

1.Installing Mongoose

npm install mongoose

2. Importing Mongoose and creating a connection file

Create a file called connect.js and place the connection logic there. This function returns a promise, which allows you to handle the connection success or failure in your main file.:

//connect.js
const mongoose = require('mongoose')

const connectDB = (url) => {
  return mongoose.connect(url)
}

module.exports = connectDB

Enter fullscreen mode Exit fullscreen mode

3. Use the Connection in Your Main File:

In your main application file for example app.js, import and use the connection logic:

//app.js
require('dotenv').config();
const express = require('express');
const app = express();

// connectdb
const connectDB = require("./db/connect"); //Add the path to the connection logic file.

// Get the MongoDB connection string from environment variables
const MONGODB_STRING = process.env.MONGODB_STRING;

app.get("/", (req, res) => {
  res.send("Hello Heroku app");
});


const port = process.env.PORT || 4040;

// Function to start the server
const start = async () => {
  try {
    // Connect to the database. Pass the MongoDB String as an arguement of the connectDB function.
    await connectDB(MONGODB_STRING)
    app.listen(port, () =>
      console.log(`Connected to the database and listening on port ${port}...`)
    );
  } catch (error) {
    console.log(error);
  }
};

start();

Enter fullscreen mode Exit fullscreen mode

Explanation

  • Environment Variables: Use dotenv to load MONGODB_STRING and PORT.
  • Database Connection: connectDB in db/connect.js in my case returns a promise for the database connection.
  • Async/Await: Use async/await in app.js to ensure the server starts only after a successful database connection.
  • Error Handling: Handle connection errors with a try/catch block.

Creating Models and Schemas

In Mongoose, models and schemas are fundamental for defining and interacting with data in MongoDB.

  • Schema: Defines the structure of your data. It specifies the shape that each document (instance) will have in the database. Think of it as a blueprint.
  • Model: Once you have a schema, you compile it into a model. A model is a JavaScript class that represents a collection in MongoDB. It is responsible for creating and reading documents from the database.
  • Document: An instance of a model is called a document. Each document is a record in your MongoDB collection, based on the schema you defined.

Create a file called job.js and place to place your logic there.

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const JobSchema = new Schema(
  {
    company: {
      type: String,
      required: [true, "Please the field can't be empty"],
    },
    position: {
      type: String,
      required: [true, "Please the field can't be empty"],
    },
    status: {
      type: String,
      required: [true, "Please the field can't be empty"],
      enum: ["interview", "declined", "pending", "accepted"],
      default: "pending",
    },

  },
  { timestamps: true }
);

const JobModel = mongoose.model("Job", JobSchema);

module.exports = JobModel;

Enter fullscreen mode Exit fullscreen mode

Explanation

  • Schema Definition: *JobSchema * defines fields company, position, status _ and their types. It includes validations (required, enum) and a default value _default.

Model Creation: *JobModel * is created using mongoose.model(), linking Job as the collection name in MongoDB.

Using Your Model in Controller Functions

In an Express application using Mongoose, it's common to separate your model definitions from your controller logic. This promotes modularity and improves code organization. So you can create a file and place your logic there for controller functions.

  • Controller Functions: These functions getAllJobs, createJob, getJob, updateJob, deleteJob handle CRUD operations for jobs. They interact with the imported (JobModel) to perform database operations based on HTTP requests.
  • You will export this controller function and map them to the routes.
const JobModel = require("../models/Job");
const { StatusCodes } = require("http-status-codes");
const { BadRequestError, NotFoundError } = require("../errors/bad-request");

const getAllJobs = async (req, res) => {

  const jobs = await JobModel.find({ createdBy: req.user.userId });
  res.status(StatusCodes.CREATED).json({ jobs });
};

const createJobs = async (req, res) => {
  req.body.createdBy = req.user.userId;
  const jobs = await JobModel.create(req.body);

  res.status(StatusCodes.CREATED).json({ jobs });
};

const getJob = async (req, res) => {
  const {
    user: { userId },
    params: { id: job_id },
  } = req;

  const job = await JobModel.findOne({ _id: job_id, createdBy: userId });
  if (!job) {
    throw new NotFoundError(`No job with id: ${job_id}`);
  }

  res.status(StatusCodes.OK).json({ job });
};

const updateJob = async (req, res) => {
  const {
    body: { company, position },
    params: { id: job_id },
    user: { userId },
  } = req;

  if (company === "" || position === "") {
    throw new BadRequestError("company and position cannot be found");
  }

  const job = await JobModel.findByIdAndUpdate(
    { _id: job_id, createdBy: userId },
    req.body,
    { new: true, runValidators: true }
  );

  res.status(StatusCodes.OK).json({ job });
};

const deleteJob = async (req, res) => {
  const {
    params: { id: job_id },
    user: { userId },
  } = req;

  const job = await JobModel.findByIdAndDelete({
    _id: job_id,
    createdBy: userId,
  });

  if (!job) {
    throw new NotFoundError(`No user with id: ${job_id}`);
  }

  res.status(StatusCodes.OK).json({ msg: "Job deleted successfully" });
};

module.exports = {
  getAllJobs,
  createJobs,
  getJob,
  updateJob,
  deleteJob,
};

Enter fullscreen mode Exit fullscreen mode

Import Controller Functions:

Import controller functions getAllJobs, createJob, getJob, updateJob, deleteJob from the path your controller function login is located.

  • Mapping Routes: Each HTTP method GET, POST, PUT, DELETE is mapped to its corresponding controller function getAllJobs, createJob, getJob, updateJob, deleteJob.
const express = require('express');
const router = express.Router();
const auth = require("../middleware/authentication");

const {
  getAllJobs,
  getJob,
  createJobs,
  updateJob,
  deleteJob,
} = require("../controllers/jobs");

router.use(auth);
router.route('/').get(getAllJobs).post(createJobs);
router.route('/:id').get(getJob).patch(updateJob).delete(deleteJob);


module.exports = router;
Enter fullscreen mode Exit fullscreen mode

Importing your router in your main file.

In an Express application, routers are used to organize and handle different sets of routes. Here is how you integrate a router into your main application file.

Import the router in your main file (app.js)

const jobRoutes = require("./routes/jobs");

Applying Router Middleware in your main file (app.js)

//app.js
require('dotenv').config();
const express = require('express');
const app = express();

//imported router
const jobRoutes = require("./routes/jobs");
// connectdb
const connectDB = require("./db/connect"); //Add the path to the connection logic file.

// Get the MongoDB connection string from environment variables
const MONGODB_STRING = process.env.MONGODB_STRING;

app.get("/", (req, res) => {
  res.send("Hello Heroku app");
});


const port = process.env.PORT || 4040;

// Function to start the server
const start = async () => {
  try {
    // Connect to the database. Pass the MongoDB String as an arguement of the connectDB function.
    await connectDB(MONGODB_STRING)
    app.listen(port, () =>
      console.log(`Connected to the database and listening on port ${port}...`)
    );
  } catch (error) {
    console.log(error);
  }
};

start();
Enter fullscreen mode Exit fullscreen mode

Conclusion

Integrating Mongoose in Node.js simplifies MongoDB interactions through schema based modeling, enhancing data structure and validation. Explore more in the mongoosejs.com official documentation.

Happy coding

mongoose Article's
30 articles in total
Favicon
Crudify: Automate Your Mongoose CRUD Operations in NestJS
Favicon
6 Steps to Set Up MongoDB Atlas for Node.js Applications
Favicon
Mysql 101 for Mongoose developer.
Favicon
Tutorial de Instalação: Express com MongoDB e Mongoose
Favicon
Today’s new knowledge #6(Mongoose)
Favicon
Today’s new knowledge #10 (Building a Flexible Query Builder for MongoDB with Mongoose)
Favicon
mongoose connect to express
Favicon
I Fumbled on a Next.js MongoDB Error and Learned the Key Differences Between Mongoose and MongoClient
Favicon
Setup Eslint Prettier in a TypeScript project with mongoose ODM
Favicon
Bootcamping 01: An Unexpected Behavior of Mongoose
Favicon
Common Myths About Mongoose
Favicon
5 Quick And Easy MongoDB Optimizations (part 1)
Favicon
Mongoose Interview Questions
Favicon
MongoDB vs. Mongoose: Understanding Their Roles and Differences
Favicon
We finally have a fullstack framework for MongoDB
Favicon
Mongoose
Favicon
💬 Building a Real-time Chat Feature for Virtual Gift Store Using Socket.IO with MERN Stack 🚀
Favicon
The Power of exec() in Mongoose: Unlocking Better Query Execution
Favicon
Enhancing Mongoose Reference Handling in Node.js
Favicon
Mongoose Documentation
Favicon
How to Connect MongoDB with Node.js: A Comprehensive Guide
Favicon
Updating Non-Primitive Data in an Array Using Transactions and Rollbacks
Favicon
Method Chaining in Mongoose: A Brief Overview
Favicon
Understanding Transactions and Rollbacks in MongoDB
Favicon
Understanding Populating Referencing Fields in Mongoose
Favicon
How to Use Bcrypt for Password Hashing in Node.js
Favicon
Getting Started with Mongoose
Favicon
Running Unit Tests with MongoDB in a Node.js Express Application using Jest
Favicon
Setting up MongoDB using Mongoose in Node.js
Favicon
I built an open-source schema visualisation tool for mongoose

Featured ones: