Open In App

How to Communicate with Backend Services using HTTP in Angular?

Last Updated : 08 Jan, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

To communicate with backend services using HTTP in Angular, you typically use the HttpClient module, which is part of the @angular/common/http package. This module allows you to interact with RESTful APIs, fetch data, submit forms, perform CRUD operations, and more.

Prerequisites

Steps To Communicate with Backend Services

Step 1: Create a new project directory.

mkdir noteapp
cd noteapp

Step 2: Create a server directory for your backend.

mkdir server
cd server

Step 3: Initialize a new Node.js project.

npm init -y

Step 4: Install the necessary backend dependencies.

npm install express mongoose cors

Project Structure (Backend)

backend_project_structure
Folder Structure

Updated Dependencies

"dependencies": {    
"cors": "^2.8.5",
"express": "^4.19.2",
"mongoose": "^8.4.0"
}

Step 5: Create a basic server to do the CRUD operation.

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");

// 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 start the backend server run the following command.

node server.js

Step 6: Navigate to the root directory and create an Angular Application.

npm install -g @angular/cli
cd client
ng new note-maker-app

Project Structure(Frontend)

frontend_folder_structure
Folder Structure

Updated Dependencies(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"
}

Step 7: Creating a bssic note application to store and modify notes.

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 HttpClientModule
import { HttpClient, HttpClientModule } from '@angular/common/http';
// Import FormsModule for ngModel
import { FormsModule } from '@angular/forms';
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);
            }
        );
    }
}

To start the application, run the following command

ng serve

Output


Next Article
Article Tags :

Similar Reads