,

Becoming an Expert in MERN Stack Development: Create a Note App from the Ground Up!

Posted by


The MERN (MongoDB, Express, React, Node.js) stack is a popular full stack framework for building web applications. In this tutorial, we will walk you through building a simple note-taking app from scratch using the MERN stack. By the end of this tutorial, you will have a fully functional note app that allows users to create, read, update, and delete notes.

Prerequisites:

  • Basic knowledge of HTML, CSS, and JavaScript
  • Familiarity with Node.js and npm
  • MongoDB installed on your machine
  • A text editor (such as Visual Studio Code) and a terminal

Let’s get started!

  1. Setting up the backend (Node.js and Express):
    First, create a new directory for your project and navigate into it:

    mkdir mern-note-app
    cd mern-note-app

Initialize a new Node.js project using npm:

npm init -y

Install Express, Mongoose, and dotenv as dependencies:

npm install express mongoose dotenv

Create an app.js file and set up a basic Express server:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello, world!');
});

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

Create a .env file in the root of your project and add the following environment variables:

PORT=5000
MONGODB_URI=your-mongodb-uri
  1. Setting up MongoDB:
    Create a models directory and a Note.js file inside it:

    
    const mongoose = require('mongoose');

const noteSchema = new mongoose.Schema({
title: { type: String, required: true },
content: { type: String, required: true },
}, { timestamps: true });

const Note = mongoose.model(‘Note’, noteSchema);

module.exports = Note;


Connect to MongoDB in your `app.js` file:
```javascript
const mongoose = require('mongoose');

mongoose.connect(process.env.MONGODB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
})
  .then(() => console.log('Connected to MongoDB'))
  .catch(err => console.error(err));
  1. Implementing CRUD operations:
    Create routes for handling CRUD operations in your app.js file:

    
    const Note = require('./models/Note');

// Create a note
app.post(‘/notes’, async (req, res) => {
const { title, content } = req.body;
const note = new Note({ title, content });

try {
await note.save();
res.status(201).json(note);
} catch (err) {
res.status(400).json({ error: err.message });
}
});

// Read all notes
app.get(‘/notes’, async (req, res) => {
const notes = await Note.find();
res.json(notes);
});

// Update a note
app.put(‘/notes/:id’, async (req, res) => {
const { title, content } = req.body;

try {
const note = await Note.findByIdAndUpdate(req.params.id, { title, content }, { new: true });
res.json(note);
} catch (err) {
res.status(400).json({ error: err.message });
}
});

// Delete a note
app.delete(‘/notes/:id’, async (req, res) => {
try {
await Note.findByIdAndDelete(req.params.id);
res.send(‘Note deleted successfully’);
} catch (err) {
res.status(400).json({ error: err.message });
}
});


4. Setting up the frontend (React):
Create a new directory for the frontend and navigate into it:

mkdir client
cd client


Initialize a new React project using Create React App:

npx create-react-app .


Install Axios for making HTTP requests to the backend:

npm install axios


5. Building the frontend:
Replace the contents of `src/App.js` with the following code:
```javascript
import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [notes, setNotes] = useState([]);
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');

  useEffect(() => {
    axios.get('/notes')
      .then(res => setNotes(res.data))
      .catch(err => console.error(err));
  }, []);

  const handleSubmit = async () => {
    try {
      await axios.post('/notes', { title, content });
      setNotes([...notes, { title, content }]);
      setTitle('');
      setContent('');
    } catch (err) {
      console.error(err);
    }
  };

  const handleDelete = async id => {
    try {
      await axios.delete(`/notes/${id}`);
      setNotes(notes.filter(note => note._id !== id));
    } catch (err) {
      console.error(err);
    }
  };

  return (
    <div>
      <h1>Notes</h1>
      <div>
        <input
          type="text"
          placeholder="Title"
          value={title}
          onChange={e => setTitle(e.target.value)}
        />
        <input
          type="text"
          placeholder="Content"
          value={content}
          onChange={e => setContent(e.target.value)}
        />
        <button onClick={handleSubmit}>Add Note</button>
      </div>
      <ul>
        {notes.map(note => (
          <li key={note._id}>
            <h3>{note.title}</h3>
            <p>{note.content}</p>
            <button onClick={() => handleDelete(note._id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;
  1. Connecting the frontend to the backend:
    Update the package.json file in the client directory to proxy requests to the backend:

    "proxy": "http://localhost:5000"
  2. Running the app:
    Start the backend server by running:

    node app.js

Start the frontend server by running:

npm start

Congratulations! You have successfully built a note-taking app using the MERN stack. You can now create, read, update, and delete notes. Feel free to customize and expand upon this project to further develop your skills with the MERN stack. Happy coding!

0 0 votes
Article Rating
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
@WebDevWarriors
1 month ago
@Salah-YT
1 month ago

Amazing project, bro. I'll complete it and do it as soon as I can. Thank you so much for your hard work.