Notes Maker App using MEAN Stack
Last Updated :
04 Jun, 2024
The Notes Maker project is a helpful web application designed to help users effectively create, manage, and organize their notes. In this article we are utilizing the MEAN (MongoDB, Express, Angular, Node) Stack, to build a notes maker application that provides a seamless user experience for note-taking.
Final OutputPrerequisites:
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, Angular.js is employed to create an interactive user interface. The functionalities include:
- Adding new notes with titles and content.
- Displaying a list of existing notes.
- Update/Delete Notes.
Steps to Create the Project
Step 1: Create a new directory for your project and navigate to it using the terminal.
mkdir NOTEAPP
cd NOTEAPP
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
Project Structure (Backend):
Backed StructureDependencies (Backend):
"dependencies": {
"cors": "^2.8.5",
"express": "^4.19.2",
"mongoose": "^8.4.0"
}
Step 5: Create a server.js file inside the server directory and add the following code:
JavaScript
// server.js
const express = require("express");
const mongoose = require("mongoose");
const noteRoutes = require("./routes/noteRoutes");
const cors = require("cors");
const app = express();
const port = 5000;
// Connect to MongoDB
mongoose
.connect("mongodb://localhost:27017/note-app")
.then(() => {
console.log("Connected successfully to MongoDB");
})
.catch((err) => {
console.error("Error occurred while connecting to MongoDB:", err);
});
// Middleware
app.use(express.json());
app.use(cors());
app.use(express.urlencoded({ extended: true }));
app.use("/notes", noteRoutes);
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
JavaScript
// model/note.js
const mongoose = require("mongoose");
const noteSchema = new mongoose.Schema({
title: { type: String, },
description: { type: String, },
});
module.exports = mongoose.model("Note", noteSchema);
JavaScript
// routes/noteRoutes.js
const express = require("express");
const router = express.Router();
const Note = require("../model/note");
const note = require("../model/note");
// Get all notes
router.get("/", async (req, res) => {
try {
const notes = await Note.find();
res.json(notes);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// Create a note
router.post("/", async (req, res) => {
console.log(req.body);
const note = new Note({
title: req.body.title,
description: req.body.description,
});
try {
const newNote = await note.save();
res.status(201).json(newNote);
} catch (err) {
res.status(400).json({ message: err.message });
}
});
// Update a note
router.put("/:id", async (req, res) => {
console.log(req.params.id);
try {
const note = await Note.findById(req.params.id);
if (note == null) {
return res.status(404).json({ message: "Note not found" });
}
if (req.body.title != null) {
note.title = req.body.title;
}
if (req.body.description != null) {
note.description = req.body.description;
}
const updatedNote = await note.save();
res.json(updatedNote);
} catch (err) {
res.status(400).json({ message: err.message });
}
});
// Delete a note
router.delete("/:id", async (req, res) => {
try {
const deletedNote = await Note.findByIdAndDelete(req.params.id);
const notes = await Note.find();
res.json(notes);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
module.exports = router;
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 Angular app:
npm install -g @angular/cli
cd client
ng new note-maker-app
Folder Structure(Frontend):
Front End StructureDependencies(Frontend):
"dependencies": {
"@angular/animations": "^17.3.0",
"@angular/common": "^17.3.0",
"@angular/compiler": "^17.3.0",
"@angular/core": "^17.3.0",
"@angular/forms": "^17.3.0",
"@angular/platform-browser": "^17.3.0",
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
}
Example: Add the given code in the respective files.
HTML
<!-- /src/app/app.component.html -->
<div class="note-form">
<h2>Note Maker App</h2>
<form (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="title">Title:</label>
<input
type="text"
id="title"
placeholder="Enter Note Title..."
[(ngModel)]="title"
name="title"
required
/>
</div>
<div class="form-group">
<label for="location">Description:</label>
<input
type="text"
id="location"
placeholder="Enter Description..."
[(ngModel)]="description"
name="description"
required
/>
</div>
<button type="submit">Submit</button>
</form>
<div class="existing-notes">
<h2>Existing Notes</h2>
<ul>
<li *ngFor="let note of notes">
<div class="notes-details">
<strong>Title:</strong> {{ note.title }},
<strong>Description</strong> {{ note.description }},
</div>
<div class="notes-actions">
<button class="editbtn" (click)="editNote(note)">Edit</button>
<button class="deletebtn" (click)="deleteNote(note._id)">Delete</button>
</div>
</li>
</ul>
</div>
</div>
CSS
/* app.component.css */
body {
font-family: 'Roboto', sans-serif;
background: linear-gradient(to right, #ff6e7f, #bfe9ff);
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-attachment: fixed;
}
/* Container */
.note-form {
background-color: #ffffff;
margin: 0 auto;
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
width: 500px;
text-align: left;
border-top: 5px solid #d9534f;
position: relative;
overflow: hidden;
background-image: url('https://example.com/disaster-background.jpg');
background-size: cover;
background-position: center;
background-blend-mode: overlay;
}
.emergency-form::before {
content: '';
background: rgba(255, 255, 255, 0.8);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
}
.emergency-form > * {
position: relative;
z-index: 1;
}
/* Headings */
h2 {
color: green;
margin-top: 0;
border-bottom: 2px solid green;
padding-bottom: 10px;
font-size: 24px;
}
/* Paragraph */
p {
color: #555;
margin: 10px 0;
font-size: 16px;
}
/* Form Styles */
form {
margin-top: 20px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
color: #333;
font-weight: bold;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box;
font-size: 16px;
}
/* Button Styles */
button {
width: 100%;
padding: 15px;
background-color:green;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 18px;
font-weight: bold;
margin-top: 20px;
transition: background-color 0.3s, transform 0.3s;
}
button:hover {
transform: scale(1.05);
}
.editbtn{
width: 50%;
margin: 1px;
background-color:green;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 18px;
font-weight: bold;
margin-top: 20px;
transition: background-color 0.3s, transform 0.3s;
}
.deletebtn{
width: 50%;
margin: 1px;
background-color:red;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 18px;
font-weight: bold;
margin-top: 20px;
transition: background-color 0.3s, transform 0.3s;
}
/* Existing Emergencies Section */
.existing-notes {
margin-top: 40px;
}
.existing-notes h2 {
color: #d9534f;
}
.existing-notes ul {
list-style: none;
padding: 0;
}
.existing-notes li {
background-color: #f9f9f9;
border: 1px solid #ddd;
padding: 15px;
margin-bottom: 15px;
border-radius: 5px;
position: relative;
display: flex;
justify-content: space-between; /* Aligns content and actions side by side */
align-items: center;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: transform 0.3s, box-shadow 0.3s;
}
.existing-notes li:hover {
transform: translateY(-5px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}
.existing-notes li::before {
content: '?';
position: absolute;
left: 10px;
top: 10px;
font-size: 24px;
color: #0e4b07;
}
.existing-notes li strong {
color: #333;
display: block;
}
/* Media Queries for Responsive Design */
@media (max-width: 600px) {
.emergency-form {
width: 100%;
padding: 20px;
}
.form-group input,
button {
padding: 10px;
}
button {
font-size: 16px;
}
}
JavaScript
// /src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpClientModule } from '@angular/common/http'; // Import HttpClientModule
import { FormsModule } from '@angular/forms'; // Import FormsModule for ngModel
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
imports: [
CommonModule,
FormsModule, // Add FormsModule here
HttpClientModule // Add HttpClientModule here
],
standalone: true
})
export class AppComponent implements OnInit {
// Form inputs
title = '';
description = '';
notes: any[] = [];
constructor(private http: HttpClient) { }
ngOnInit(): void {
this.fetchNotes();
}
fetchNotes(): void {
this.http.get<any[]>('http://localhost:5000/notes').subscribe(
(data) => {
this.notes = data;
},
(error) => {
console.error('Error fetching notes:', error);
}
);
}
// Handle form submission
onSubmit(): void {
if (this.title.trim() === '' || this.description.trim() === '') {
alert('Please fill in all fields!');
return;
}
const newNote = {
title: this.title,
description: this.description,
};
this.http.post('http://localhost:5000/notes', newNote).subscribe(
(data) => {
console.log('Data submitted:', data);
// Reset form inputs
this.title = '';
this.description = '';
this.fetchNotes();
},
(error) => {
console.error('Error submitting data:', error);
}
);
}
editNote(note: any): void {
console.log(note)
const newTitle = prompt('Enter new title:', note.title);
const newDescription = prompt('Enter new description:', note.description);
if (newTitle !== null && newDescription !== null) {
const updatedNotes = { ...note, title: newTitle, description: newDescription };
this.http.put(`http://localhost:5000/notes/${note._id}`, updatedNotes).subscribe(
(data) => {
console.log('Updated note:', data);
this.fetchNotes(); // Refresh the list
},
(error) => {
console.error('Error updating notes:', error);
}
);
}
}
deleteNote(id: number): void {
this.http.delete<any[]>('http://localhost:5000/notes/' + id).subscribe(
(updatedNotes) => {
this.notes = updatedNotes;
},
(error) => {
console.error('Error deleting notes:', error);
}
);
}
}
JavaScript
//main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
To run the application, type the following command:
ng serve
Output:
Notes Maker app using MEAN stack
Similar Reads
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-t
6 min read
Stock Market Portfolio App using MEAN Stack In this guide, we'll walk through the process of building a stock market application using Angular, a powerful front-end framework. Building a stock market application allows users to monitor stock prices, add stocks to their watchlist, and stay informed about market trends. Project Preview: Prerequ
6 min read
Task Manager App using MERN Stack Task Manager is very crucial to manage your tasks. In this article, we are going to develop a task manager application using the MERN stack. This application helps users to manage their tasks efficiently, offering essential features like creating new tasks, editing existing ones, and deleting tasks
10 min read
Quiz App using MERN Stack In this article, weâll walk through the step-by-step process of creating a complete quiz application with MongoDB, ReactJS, ExpressJS, and NodeJS. This application will provide users with a user-friendly interface for taking and submitting quizzes and a scoreboard to check their standing among other
15+ min read
Twenty-one Game using MEAN Stack Twenty-one Game is a popular card game played in casinos worldwide. In this article, we'll explore how to create a Twenty-one game also known as the BlackJack game using the MEAN stack (MongoDB, Express.js, Angular, and Node.js). By building a Twenty-one game, we'll see the various aspects of web de
8 min read
Note-taking App using Django In this article, we will explore a note-making app. In this article, we will create a note-making app using Django. We will also use the Django authentication system. Users need to create an account on the web to access the note-making app. After that, users will have access to the note-making app.
8 min read
Social Fitness App using MERN Stack Creating a Social Fitness App is a great opportunity for anyone who wants to understand full-stack development. In this article, we'll make a Social Fitness App from scratch using the MERN(MongoDB, Express.js, React, Node.js) stack. This project will help navigate backend development, and teach you
9 min read
Blackjack Game using MEAN Stack This is a project to get a thorough understanding of MEAN Stack technologies (MongoDB, Express, Node JS, Angular). This will give you a step-by-step process to create a blackjack game from scratch. This article will discuss Starting a new game, the logic to play it and store it in the database. It w
15+ min read
Note-Taking App with Status Tracker using MERN Stack In this article, we will be creating a simple note-taking application with functionalities to create a note, delete a note, edit a note, and view the note. The project uses NodeJS as a backend server with Postman API to post and get the notes from the HTTP request. It uses ExpressJS as a framework i
15 min read
Workout Planner using MERN Stack With a busy schedule, it is very important to prioritize our health and fitness. In this article, a walkthrough to creating a Workout Planner using MERN (Mongodb, Express, ReactJS, NodeJS) stack is explained. How to create own customized APIs using Mongoose for performing CRUD (Create, Read, Update
15+ min read