Building a Contact Form with Node.js, Express, and MongoDB
Tags: webdev, javascript, beginners, programming
Published: 2024-02-05 06:15:00

In the world of web development, contact forms play a crucial role in facilitating communication between users and website owners. Creating a robust and secure contact form requires a combination of frontend and backend technologies. In this blog post, we'll explore how to build a simple contact form backend using Node.js, Express, and MongoDB.

## Setting Up the Project

Before diving into the code, make sure you have Node.js and MongoDB installed on your machine. If not, you can download them from their official websites.

**Initializing the Project:**

   Open your terminal and create a new project folder. Navigate to the folder and run the following commands:

   ```bash
   npm init -y
   ```

   This initializes a new Node.js project with default settings.

**Installing Dependencies:**

   Install the required npm packages: Express, Mongoose, and Cors.

   ```bash
   npm install express mongoose cors
   ```

   These packages will help us set up the server, interact with the MongoDB database, and handle cross-origin resource sharing (CORS).

## Building the Backend

Now, let's create the necessary files and code for the backend.

**Database Model (models/contact.js):**

   ```javascript
   const mongoose = require('mongoose');

   const ContactSchema = mongoose.Schema({
       name: { type: String },
       email: { type: String },
       message: { type: String }
   });

   const Contact = mongoose.model('contacts', ContactSchema);

   module.exports = Contact;
   ```

   This file defines the structure of our contact model using Mongoose, allowing us to interact with MongoDB.

**Controller (controllers/contacts.js):**

   ```javascript
   const Contact = require('../models/contact.js');

   exports.submitForm = async (req, res, next) => {
       try {
           const { name, email, message } = req.body;

           // Basic validations
           if (!name || !email || !message) {
               return res.status(400).json({ message: 'Name, email, and message are required fields' });
           }

           // Create a new contact instance
           const newContact = new Contact({
               name: name,
               email: email,
               message: message,
           });

           // Save the contact to the database
           await newContact.save();

           res.status(201).json({ message: 'Contact form submitted successfully' });
       } catch (error) {
           console.error(error);
           res.status(500).json({ message: 'Internal server error' });
       }
   };
   ```

   The controller handles the submission of the contact form, performs basic validations, and saves the data to the MongoDB database.

**Routes (routes/contacts.js):**

   ```javascript
   const express = require('express');
   const router = express.Router();
   const contactsController = require('../controllers/contacts');

   router.post('/contact', contactsController.submitForm);

   module.exports = router;
   ```

   The routes file defines the API endpoint for submitting the contact form and delegates the handling to the controller.

**Server Setup (index.js):**

   ```javascript
   const express = require('express');
   const mongoose = require('mongoose');
   const cors = require('cors');
   const bodyParser = require('body-parser');

   require('dotenv').config();

   const app = express();
   const PORT = process.env.PORT || 3000;

   const dbUser = process.env.MONGODB_USER;
   const dbPassword = process.env.MONGODB_PASSWORD;

   mongoose
       .connect(`mongodb+srv://${dbUser}:${dbPassword}@cluster0.re3ha3x.mongodb.net/backend`, { useNewUrlParser: true, useUnifiedTopology: true })
       .then(() => {
           console.log('Connected to MongoDB database!');
       })
       .catch(() => {
           console.log('Connection failed!');
       });

   app.use(cors({ origin: '*' }));
   app.use(bodyParser.json());
   app.use(express.static('public'));
   app.use(express.json());

   app.use('/api', require('./routes/contacts'));

   app.use(function (err, req, res, next) {
       res.status(422).send({ error: err.message });
   });

   app.listen(PORT, () => {
       console.log(`Server started on port ${PORT}`);
   });
   ```

   The main server file sets up the Express application, connects to the MongoDB database, and defines middleware for handling CORS, parsing JSON data, and serving static files. It also includes the route for handling contact form submissions.

## Setting up MongoDB

Ensure you have a MongoDB cluster set up. The connection string is stored in the `.env` file, following the format:

```env
MONGODB_USER=your_username
MONGODB_PASSWORD=your_password
```

## Conclusion

With this setup, you now have a basic but functional backend for a contact form using Node.js, Express, and MongoDB. You can expand upon this foundation by adding frontend components, implementing additional validation, and enhancing the user experience. As your project evolves, consider implementing features such as email notifications, more robust error handling, and user authentication to create a complete and secure contact form solution.