MEAN Stack tutorial with examples

 The MEAN stack is a popular web development stack that includes MongoDB, Express, Angular, and Node.js. It's a full-stack JavaScript framework for building dynamic, scalable web applications. In this tutorial, we will create a simple MEAN stack application that allows users to add, view, update, and delete tasks (CRUD operations) from a database.

Prerequisites:

  1. Node.js and npm installed.
  2. Angular CLI installed (for setting up Angular).
  3. Basic understanding of JavaScript, TypeScript, and web development.

Overview of the MEAN Stack:

  1. MongoDB: NoSQL database for storing data in a JSON-like format.
  2. Express: Web application framework for Node.js.
  3. Angular: Frontend framework for building Single Page Applications (SPA).
  4. Node.js: JavaScript runtime environment for the backend.

Step 1: Setting Up the Backend (Node.js + Express + MongoDB)

1.1. Create a new directory for the project.

mkdir mean-stack-tutorial cd mean-stack-tutorial

1.2. Initialize Node.js Project.

npm init -y

1.3. Install Dependencies.

You'll need the following dependencies:

  • express: For creating the server.
  • mongoose: For MongoDB object modeling.
  • cors: For handling cross-origin requests.
  • body-parser: For parsing JSON requests.
npm install express mongoose cors body-parser

1.4. Create the Server (app.js)

Create an app.js file to set up the Express server and connect to MongoDB.

// app.js const express = require('express'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const cors = require('cors'); const Task = require('./models/task'); // Import Task model const app = express(); const port = 3000; // Middleware app.use(cors()); app.use(bodyParser.json()); // MongoDB connection mongoose.connect('mongodb://localhost:27017/mean-stack', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log("Connected to MongoDB")) .catch(err => console.log("Error connecting to MongoDB:", err)); // Define Routes app.get('/tasks', async (req, res) => { try { const tasks = await Task.find(); res.json(tasks); } catch (error) { res.status(500).json({ message: error.message }); } }); app.post('/tasks', async (req, res) => { const task = new Task({ name: req.body.name, completed: req.body.completed }); try { const newTask = await task.save(); res.status(201).json(newTask); } catch (error) { res.status(400).json({ message: error.message }); } }); app.put('/tasks/:id', async (req, res) => { try { const task = await Task.findById(req.params.id); if (task) { task.name = req.body.name || task.name; task.completed = req.body.completed || task.completed; const updatedTask = await task.save(); res.json(updatedTask); } else { res.status(404).json({ message: 'Task not found' }); } } catch (error) { res.status(500).json({ message: error.message }); } }); app.delete('/tasks/:id', async (req, res) => { try { const task = await Task.findById(req.params.id); if (task) { await task.remove(); res.json({ message: 'Task deleted' }); } else { res.status(404).json({ message: 'Task not found' }); } } catch (error) { res.status(500).json({ message: error.message }); } }); // Start server app.listen(port, () => { console.log(`Server running on http://localhost:${port}`); });

1.5. Create the MongoDB Model (models/task.js)

In the models/ directory, create a task.js file to define the task schema using Mongoose.

// models/task.js const mongoose = require('mongoose'); const taskSchema = new mongoose.Schema({ name: { type: String, required: true }, completed: { type: Boolean, default: false } }); module.exports = mongoose.model('Task', taskSchema);

1.6. Run the Backend Server

To run the server, use the following command:

node app.js

Now your backend is running on http://localhost:3000.


Step 2: Setting Up the Frontend (Angular)

2.1. Install Angular CLI

If you don't have the Angular CLI installed globally, you can install it with:

npm install -g @angular/cli

2.2. Create a New Angular Project

Navigate back to your root directory and create a new Angular project.

cd .. ng new client --routing --style=scss cd client

2.3. Install Angular HTTP Client Module

You need the Angular HttpClientModule to make HTTP requests.

npm install @angular/common

2.4. Create a Service to Communicate with the Backend

In Angular, we’ll create a service to communicate with the backend API.

ng generate service task

In src/app/task.service.ts, add the following code:

// task.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; interface Task { _id?: string; name: string; completed: boolean; } @Injectable({ providedIn: 'root' }) export class TaskService { private apiUrl = 'http://localhost:3000/tasks'; // Backend URL constructor(private http: HttpClient) {} getTasks(): Observable<Task[]> { return this.http.get<Task[]>(this.apiUrl); } addTask(task: Task): Observable<Task> { return this.http.post<Task>(this.apiUrl, task); } updateTask(task: Task): Observable<Task> { return this.http.put<Task>(`${this.apiUrl}/${task._id}`, task); } deleteTask(id: string): Observable<any> { return this.http.delete(`${this.apiUrl}/${id}`); } }

2.5. Create a Task Component

Now, create a component to manage and display tasks.

ng generate component task-list

In src/app/task-list/task-list.component.ts, modify it as follows:

// task-list.component.ts import { Component, OnInit } from '@angular/core'; import { TaskService } from '../task.service'; @Component({ selector: 'app-task-list', templateUrl: './task-list.component.html', styleUrls: ['./task-list.component.scss'] }) export class TaskListComponent implements OnInit { tasks: any[] = []; newTaskName: string = ''; constructor(private taskService: TaskService) {} ngOnInit(): void { this.loadTasks(); } loadTasks(): void { this.taskService.getTasks().subscribe(tasks => { this.tasks = tasks; }); } addTask(): void { if (this.newTaskName.trim()) { const newTask = { name: this.newTaskName, completed: false }; this.taskService.addTask(newTask).subscribe(task => { this.tasks.push(task); this.newTaskName = ''; // Clear input field }); } } deleteTask(id: string): void { this.taskService.deleteTask(id).subscribe(() => { this.tasks = this.tasks.filter(task => task._id !== id); }); } toggleCompletion(task: any): void { task.completed = !task.completed; this.taskService.updateTask(task).subscribe(); } }

2.6. Create Task List Template

In src/app/task-list/task-list.component.html, add the HTML for the task list:

<div class="container"> <h2>Task List</h2> <input [(ngModel)]="newTaskName" placeholder="Add a new task" /> <button (click)="addTask()">Add</button> <ul> <li *ngFor="let task of tasks"> <span [class.completed]="task.completed" (click)="toggleCompletion(task)"> {{ task.name }} </span> <button (click)="deleteTask(task._id)">Delete</button> </li> </ul> </div>

In src/app/styles.scss, add the following CSS to style the tasks:

.completed { text-decoration: line-through; color: grey; } .container { width: 80%; margin: 0 auto; padding-top: 50px; } button { margin-left: 10px; }

2.7. Add HttpClientModule and FormsModule

Finally, ensure that HttpClientModule and FormsModule are imported in your app.module.ts:

// app.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from '@angular/common/http'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { TaskListComponent } from './task-list/task-list.component'; import { TaskService } from './task.service'; @NgModule({ declarations: [ AppComponent, TaskListComponent ], imports: [ BrowserModule, HttpClientModule, FormsModule ], providers: [TaskService], bootstrap: [AppComponent] }) export class AppModule { }

2.8. Run the Angular App

To run the Angular application, use the following command:

ng serve

Your Angular frontend will now be running on http://localhost:4200.


Step 3: Testing the MEAN Application

  • Backend is running on http://localhost:3000 (Node.js + Express).
  • Frontend is running on http://localhost:4200 (Angular).

Test the full CRUD operations:

  1. Add tasks from the Angular app.
  2. View tasks on the frontend.
  3. Update tasks by toggling completion status.
  4. Delete tasks by clicking the delete button.

Conclusion

In this tutorial, you've learned how to create a simple MEAN stack application that allows you to add, view, update, and delete tasks using MongoDB, Express, Angular, and Node.js. The full stack allows you to handle both the frontend and backend of a web application, all with JavaScript and TypeScript.

You can expand this application by adding features like user authentication, validation, and more complex data models.

Comments

Popular posts from this blog

PrimeNG tutorial with examples using frequently used classes

Docker and Kubernetes Tutorials and QnA

Building strong foundational knowledge in frontend development topics