Open In App

Notes Maker App using MERN Stack

The “Notes Maker” project is an helpful web application designed to help users effectively create, manage, and organize their notes. In this article we are utilizing the MERN (MongoDB, Express, React, Node) Stack, to build a notes maker application that provides a seamless user experience for note-taking.

Preview of final output: Let us have a look at how the final application will look like.



Project preview

Prerequisites

Approach to create Notes Maker App:

Functionalities of Notes Maker App:

The project employs a backend built with Node.js and Express.js, utilizing MongoDB as the database for note storage. On the front end, React.js is employed to create an interactive user interface. The functionalities include:

Steps to Create the Project:

Step 1: Create a new directory for your project and navigate to it using the terminal.



mkdir notes-maker
cd notes-maker

Step 2: Create a server directory for your backend and navigate into it.

mkdir server
cd server

Step 3: Initialize a new Node.js project for the backend.

npm init -y

Step 4: Install the necessary backend dependencies.

npm install express mongoose cors body-parser

Project Structure (Backend):

Dependencies (Backend):

"dependencies": {
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"mongoose": "^8.0.3"
}

Step 5: Create a server.js file inside the server directory and add the following code:




//server.js
 
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const bodyParser = require("body-parser");
 
const app = express();
const PORT = process.env.PORT || 5000;
 
// Middleware
app.use(cors());
app.use(bodyParser.json());
 
// Connect to MongoDB Atlas
const dbURI = "your mongodb connection string";
mongoose.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true });
 
// Define Note model
const Note = mongoose.model("Note", {
    title: String,
    content: String,
});
 
// Listen for successful MongoDB connection
mongoose.connection.on("connected", () => {
    console.log("Connected to MongoDB Atlas");
});
 
// Listen for MongoDB connection errors
mongoose.connection.on("error", (err) => {
    console.error("MongoDB connection error:", err);
});
 
// Routes
app.get("/", (req, res) => {
    res.send("Hello, this is the root!");
});
 
app.get("/api/notes", async (req, res) => {
    try {
        const notes = await Note.find();
        res.json(notes);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
});
 
// Update Note by ID
// Update Note by ID
app.put("/api/notes/:id", async (req, res) => {
    const { title, content } = req.body;
    const noteId = req.params.id;
 
    try {
        const updatedNote = await Note.findByIdAndUpdate(
            noteId,
            { title, content },
            { new: true }
        );
        res.json(updatedNote);
    } catch (error) {
        res.status(404).json({ message: "Note not found" });
    }
});
 
// Delete Note by ID
app.delete("/api/notes/:id", async (req, res) => {
    const noteId = req.params.id;
 
    try {
        await Note.findByIdAndDelete(noteId);
        res.json({ message: "Note deleted successfully" });
    } catch (error) {
        res.status(404).json({ message: "Note not found" });
    }
});
 
app.post("/api/notes", async (req, res) => {
    const { title, content } = req.body;
 
    const note = new Note({ title, content });
 
    try {
        const newNote = await note.save();
        res.status(201).json(newNote);
    } catch (error) {
        res.status(400).json({ message: error.message });
    }
});
 
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

To run the backend server run the following command.

node server.js

Step 6: Navigate to the root directory. Run the following command to initialize a new React app:

npx create-react-app client
cd client

Step 7: Install the required dependencies.

npm i axios

Folder Structure(Frontend):

Dependencies(Frontend):

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

Example: Add the given code in the respective files.




//App.js
 
import React, { useState, useEffect } from "react";
import axios from "axios";
import "./App.css";
import NoteList from "./components/NoteList";
import AddNote from "./components/AddNote";
 
const App = () => {
    const [notes, setNotes] = useState([]);
    const [title, setTitle] = useState("");
    const [content, setContent] = useState("");
 
    useEffect(() => {
        // Fetch notes from the server
        axios
            .get("http://localhost:5000/api/notes")
            .then((response) => setNotes(response.data))
            .catch((error) => console.error("Error fetching notes:", error));
    }, []);
 
    const handleAddNote = () => {
        // Add a new note to the server
        axios
            .post("http://localhost:5000/api/notes", { title, content })
            .then((response) => {
                setNotes([...notes, response.data]);
                setTitle("");
                setContent("");
            })
            .catch((error) => console.error("Error adding note:", error));
    };
    const handleEditNote = (id, updatedTitle, updatedContent) => {
        // Update note by ID
        axios
            .put(`http://localhost:5000/api/notes/${id}`, {
                title: updatedTitle,
                content: updatedContent,
            })
            .then((response) => {
                const updatedNotes = notes.map((note) =>
                    note._id === id ? response.data : note
                );
                setNotes(updatedNotes);
            })
            .catch((error) => console.error("Error updating note:", error));
    };
 
    const handleDeleteNote = (id) => {
        // Delete note by ID
        axios
            .delete(`http://localhost:5000/api/notes/${id}`)
            .then((response) => {
                const updatedNotes = notes.filter((note) => note._id !== id);
                setNotes(updatedNotes);
            })
            .catch((error) => console.error("Error deleting note:", error));
    };
 
    return (
        <div className="app-container">
            <h1>Notes App</h1>
            <AddNote
                title={title}
                setTitle={setTitle}
                content={content}
                setContent={setContent}
                onAddNote={handleAddNote}
            />
            <NoteList
                notes={notes}
                onEditNote={handleEditNote}
                onDeleteNote={handleDeleteNote}
            />
        </div>
    );
};
 
export default App;




// components/NoteList.js
 
import React from "react";
 
const NoteList = ({ notes, onEditNote, onDeleteNote }) => {
    return (
        <ul>
            {notes.map((note) => (
                <li key={note._id}>
                    <strong>{note.title}</strong>
                    <p>{note.content}</p>
 
                    <button
                        className="button2"
                        style={{ marginRight: "15px" }}
                        onClick={() =>
                            onEditNote(
                                note._id,
                                prompt("Enter updated title:", note.title),
                                prompt("Enter updated content:", note.content)
                            )
                        }
                    >
                        Edit
                    </button>
                    <button
                        className="button2"
                        onClick={() => onDeleteNote(note._id)}
                    >
                        Delete
                    </button>
                </li>
            ))}
        </ul>
    );
};
 
export default NoteList;




//componenets/AddNode.js
 
import React from "react";
 
const AddNote = ({ title, setTitle, content, setContent, onAddNote }) => {
    return (
        <div>
            <h2>Add Note</h2>
            <input
                type="text"
                placeholder="Title"
                value={title}
                onChange={(e) => setTitle(e.target.value)}
            />
            <textarea
                placeholder="Content"
                value={content}
                onChange={(e) => setContent(e.target.value)}
            ></textarea>
            <button className="button1" onClick={onAddNote}>
                Add Note
            </button>
        </div>
    );
};
 
export default AddNote;




/* App.css */
 
body {
    font-family: 'Arial', sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}
 
.app-container {
    max-width: 800px;
    margin: 20px auto;
    padding: 20px;
    background-color: #fff;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    border-radius: 5px;
}
 
h1 {
    color: #333;
}
 
form {
    display: flex;
    flex-direction: column;
}
 
label {
    margin-bottom: 8px;
    font-size: 16px;
}
 
input {
    margin-bottom: 15px;
    padding: 10px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 5px;
    box-sizing: border-box;
    width: 100%;
}
 
.button1,
.button2 {
    margin-bottom: 15px;
    padding: 10px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 5px;
    box-sizing: border-box;
}
 
.button1 {
    width: 100%;
}
 
.button2 {
    width: 49%;
 
}
 
textarea {
    margin-bottom: 15px;
    padding: 10px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 5px;
    box-sizing: border-box;
    resize: vertical;
    height: 100px;
    width: 100%;
}
 
button {
    background-color: #4caf50;
    color: #fff;
    cursor: pointer;
}
 
button:hover {
    background-color: #45a049;
}
 
ul {
    list-style-type: none;
    padding: 0;
}
 
li {
    margin-bottom: 15px;
    padding: 10px;
    background-color: #eee;
    border-radius: 5px;
}
 
li strong {
    font-size: 18px;
    color: #333;
}
 
li p {
    font-size: 16px;
    color: #555;
}

To run the application,type the following command:

node server.js

Output:

Final Output


Article Tags :