Make Angular 13, MongoDB example with Node.js Express

The tutorial is an Angular 13 + MongoDB example with Node.js Express: CRUD. You can follow the introduction to create CRUD apps that use Angular 13 and Node js express rest API and MongoDB.

Following  the below steps to create Angular 13 + Node JS MongoDB crud application:

  • Step 1 – Create New Angular App
  • Step 2 – Create Components in Angular
  • Step 3 – Import Modules in app.module.ts
  • Step 4 – Create CRUD Routes
  • Step 5 – Build RESTful API using Node + Express js + MongoDB
  • Step 6 – Create Angular Service for REST API Consumption
  • Step 7 – Add code In app.component.html
  • Step 8 – Create Operation

Step 1 – Create New Angular App

First of all, open your terminal and execute the following command on it to install an Angular app:

Firstly, open your terminal and execute the  command to install an Angular app:

ng new my-new-app

Next, you need to execute the following command on the terminal to install angular material:

ng add @angular/material

Step 2 – Create Components in Angular

In this step, execute the following commands on the terminal to generate components in the angular application. Then, open your terminal and execute the below command:

ng g c components/add-book
ng g c components/book-detail
ng g c components/books-list

Step 3 – Import Modules in app.module.ts

In this step, visit the directory src/app and then open the file app.module.ts. After that you need to add the below code into the file:

...
...
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
  declarations: [],
  imports: [
    FormsModule,
    HttpClientModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: []
})
export class AppModule { }

Step 4 – Create CRUD Routes

In the step, you need to create routes with the help of Angular routes. You will make a consensus with components to enable the navigation in the CRUD application, then you need to add the following code in the app-routing.module.ts file.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { BooksListComponent } from './components/books-list/books-list.component';
import { AddBookComponent } from './components/add-book/add-book.component';
import { BookDetailComponent } from './components/book-detail/book-detail.component';
const routes: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'add-book' },
  { path: 'books-list', component: BooksListComponent },
  { path: 'add-book', component: AddBookComponent },
  { path: 'edit-book/:id', component: BookDetailComponent }
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Step 5 – Build RESTful API using Node + Express js + MongoDB

In the step, we will introduce how to create RESTful API with Node and Express.js. We will learn to use MongoDB and how to handle data.

You need to execute the following command to invoke the REST API development with Node and Express.js:

mkdir node-rest-api && cd node-rest-api

Then you need to execute the command:

npm init -y

Next, you execute the below commands to install imperative npm packages that will help you to create REST APIs for your Angular CRUD system:

npm install express cors body-parser mongoose
npm install nodemon --save-dev

In order to store the data flawlessly, you can use a reliable database of what else could be a better choice than MongoDB. So, execute the command to create a node-backend/database directory, and generate the db.js file where all the logic will be piled up for invoking the MongoDB connection.

mkdir database && cd database && touch db.js

Next, you need to add the following code in node-backend/database/db.js file.

module.exports = {
    db: 'mongodb://localhost:27017/db'
};

Now, you have to create the Book model or schema, and create node-backend/model folder. Also, you need to create a Book.js file and add the below code into the file:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Book = new Schema({
  name: {
    type: String
  },
  price: {
    type: String
  },
  description: {
    type: String
  }
}, {
  collection: 'books'
})
module.exports = mongoose.model('Book', Book)

Then, you need to define the REST API routes using Express js in the node project. Then you can create node-backend/routes folder, and create book.routes.js file. You need to add the below code into it:

const express = require('express');
const app = express();
const bookRoute = express.Router();
let Book = require('../model/Book');
// Add Book
bookRoute.route('/add-book').post((req, res, next) => {
    Book.create(req.body, (error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data)
    }
  })
});
// Get all Book
bookRoute.route('/').get((req, res) => {
    Book.find((error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data)
    }
  })
})
// Get Book
bookRoute.route('/read-book/:id').get((req, res) => {
    Book.findById(req.params.id, (error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data)
    }
  })
})
// Update Book
bookRoute.route('/update-book/:id').put((req, res, next) => {
    Book.findByIdAndUpdate(req.params.id, {
    $set: req.body
  }, (error, data) => {
    if (error) {
      return next(error);
      console.log(error)
    } else {
      res.json(data)
      console.log('Book updated successfully!')
    }
  })
})
// Delete Book
bookRoute.route('/delete-book/:id').delete((req, res, next) => {
    Book.findByIdAndRemove(req.params.id, (error, data) => {
    if (error) {
      return next(error);
    } else {
      res.status(200).json({
        msg: data
      })
    }
  })
})
module.exports = bookRoute;

Now, sum up all the code and conjugate it in one place so that you can run your backend and propel the CRUD app development forward.

Next, you create and add the following code in the index.js file:

let express = require('express'),
  path = require('path'),
  mongoose = require('mongoose'),
  cors = require('cors'),
  bodyParser = require('body-parser'),
  mongoDb = require('./database/db');
mongoose.Promise = global.Promise;
mongoose.connect(mongoDb.db, {
  useNewUrlParser: true,
  useFindAndModify: false,
  useUnifiedTopology: true
}).then(() => {
    console.log('Database sucessfully connected ')
  },
  error => {
    console.log('Database error: ' + error)
  }
)
const bookRoute = require('./routes/book.routes')
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: false
}));
app.use(cors());
// Static directory path
app.use(express.static(path.join(__dirname, 'dist/angular-mean-crud-tutorial')));
// API root
app.use('/api', bookRoute)
// PORT
const port = process.env.PORT || 8000;
app.listen(port, () => {
  console.log('Listening on port ' + port)
})
// 404 Handler
app.use((req, res, next) => {
  next(createError(404));
});
// Base Route
app.get('/', (req, res) => {
  res.send('invaild endpoint');
});
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/angular-mean-crud-tutorial/index.html'));
});
// error handler
app.use(function (err, req, res, next) {
  console.error(err.message);
  if (!err.statusCode) err.statusCode = 500;
  res.status(err.statusCode).send(err.message);
});

Step 6 – Create Angular Service for REST API Consumption

In the step, you need to visit app/service directory in Angular project and create Book.ts class within.

Then, you add the following code in app/service/Book.ts file:

export class Book {
    _id!: String;
    name!: String;
    price!: String;
    description!: String;
}

Then, you need to execute the command to create a crud service file:

ng g s service/crud

Then, you need to add the below code in app/service/crud.service.ts file:

import { Injectable } from '@angular/core';
import { Book } from './Book';
import { catchError, map } from 'rxjs/operators';
import { Observable, throwError } from 'rxjs';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
@Injectable({
  providedIn: 'root'
})
export class CrudService {
  // Node/Express API
  REST_API: string = 'http://localhost:8000/api';
  // Http Header
  httpHeaders = new HttpHeaders().set('Content-Type', 'application/json');
  constructor(private httpClient: HttpClient) { }
  // Add
  AddBook(data: Book): Observable<any> {
    let API_URL = `${this.REST_API}/add-book`;
    return this.httpClient.post(API_URL, data)
      .pipe(
        catchError(this.handleError)
      )
  }
  // Get all objects
  GetBooks() {
    return this.httpClient.get(`${this.REST_API}`);
  }
  // Get single object
  GetBook(id:any): Observable<any> {
    let API_URL = `${this.REST_API}/read-book/${id}`;
    return this.httpClient.get(API_URL, { headers: this.httpHeaders })
      .pipe(map((res: any) => {
          return res || {}
        }),
        catchError(this.handleError)
      )
  }
  // Update
  updateBook(id:any, data:any): Observable<any> {
    let API_URL = `${this.REST_API}/update-book/${id}`;
    return this.httpClient.put(API_URL, data, { headers: this.httpHeaders })
      .pipe(
        catchError(this.handleError)
      )
  }
  // Delete
  deleteBook(id:any): Observable<any> {
    let API_URL = `${this.REST_API}/delete-book/${id}`;
    return this.httpClient.delete(API_URL, { headers: this.httpHeaders}).pipe(
        catchError(this.handleError)
      )
  }
  // Error
  handleError(error: HttpErrorResponse) {
    let errorMessage = '';
    if (error.error instanceof ErrorEvent) {
      // Handle client error
      errorMessage = error.error.message;
    } else {
      // Handle server error
      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
    console.log(errorMessage);
    return throwError(errorMessage);
  }
}

Step 7 – Add code In app.component.html

In the step, you need to create HTML and for crud app in Angular. You need to visit src/app/app.component.html and update the below code into the HTML file:

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand">Angular 13 CRUD Operations Demo</a>
  <div id="navbarNav" class="collapse navbar-collapse">
    <ul class="navbar-nav ml-auto ">
      <li class="nav-item">
        <a class="nav-link" routerLinkActive="active" routerLink="/books-list">Show Books</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLinkActive="active" routerLink="/add-book">Add Books</a>
      </li>
    </ul>
  </div>
</nav>
<router-outlet></router-outlet>

Step 8 – Create Operation

After that, you can add the code in the add-book.component.ts file:

import { Component, OnInit, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { CrudService } from './../../service/crud.service';
import { FormGroup, FormBuilder } from "@angular/forms";
@Component({
  selector: 'app-add-book',
  templateUrl: './add-book.component.html',
  styleUrls: ['./add-book.component.scss']
})
export class AddBookComponent implements OnInit {
  bookForm: FormGroup;
  
  constructor(
    public formBuilder: FormBuilder,
    private router: Router,
    private ngZone: NgZone,
    private crudService: CrudService
  ) {
    this.bookForm = this.formBuilder.group({
      name: [''],
      price: [''],
      description: ['']
    })
  }
  ngOnInit() { }
  onSubmit(): any {
    this.crudService.AddBook(this.bookForm.value)
    .subscribe(() => {
        console.log('Data added successfully!')
        this.ngZone.run(() => this.router.navigateByUrl('/books-list'))
      }, (err) => {
        console.log(err);
    });
  }
}

Then, you need to add the following code in the add-book.component.html file:

<div class="row justify-content-center mt-5">
    <div class="col-md-4">
        <form [formGroup]="bookForm" (ngSubmit)="onSubmit()">
          <div class="form-group">
            <label>Name</label>
            <input class="form-control" type="text" formControlName="name" required>
          </div>
  
          <div class="form-group">
            <label>Price</label>
            <input class="form-control" type="text" formControlName="price" required>
          </div>
  
          <div class="form-group">
            <label>Description</label>
            <input class="form-control" type="text" formControlName="description" required>
          </div>
  
          <div class="form-group">
            <button class="btn btn-primary btn-block" type="submit">Add Book</button>
          </div>
        </form>
    </div>
  </div>

Next, you add the below code in the books-list.component.ts file:

import { Component, OnInit } from '@angular/core';
import { CrudService } from './../../service/crud.service';
@Component({
  selector: 'app-books-list',
  templateUrl: './books-list.component.html',
  styleUrls: ['./books-list.component.scss']
})
export class BooksListComponent implements OnInit {
  
  Books:any = [];
  constructor(private crudService: CrudService) { }
  ngOnInit(): void {
    this.crudService.GetBooks().subscribe(res => {
      console.log(res)
      this.Books =res;
    });   
  }
  delete(id:any, i:any) {
    console.log(id);
    if(window.confirm('Do you want to go ahead?')) {
      this.crudService.deleteBook(id).subscribe((res) => {
        this.Books.splice(i, 1);
      })
    }
  }
}

Next, you add the below code in the books-list.component.html file:

<div class="container">
  <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
    <h2 class="h2">Books List</h2>
  </div>
  <div class="table-responsive">
    <table class="table table-bordered">
      <thead>
        <tr>
          <th scope="col">Id</th>
          <th scope="col">Name</th>
          <th scope="col">Price</th>
          <th scope="col">Description</th>
          <th class="text-center" scope="col">Action</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let book of Books; let i = index">
          <th scope="row">{{book._id}}</th>
          <td>{{book.name}}</td>
          <td>{{book.price}}</td>
          <td>{{book.description}}</td>
          <td class="text-center">
            <button class="btn btn-sm btn-primary" routerLink="/edit-book/{{book._id}}">Edit</button>
            <button class="btn btn-sm btn-danger" (click)="delete(book._id, i)">Delete</button>
        </tr>
      </tbody>
    </table>
  </div>
</div>

Next, add the below code in the book-detail.component.ts file:

import { Component, OnInit, NgZone } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { CrudService } from './../../service/crud.service';
import { FormGroup, FormBuilder } from "@angular/forms";
@Component({
  selector: 'app-book-detail',
  templateUrl: './book-detail.component.html',
  styleUrls: ['./book-detail.component.scss']
})
export class BookDetailComponent implements OnInit {
  getId: any;
  updateForm: FormGroup;
  
  constructor(
    public formBuilder: FormBuilder,
    private router: Router,
    private ngZone: NgZone,
    private activatedRoute: ActivatedRoute,
    private crudService: CrudService
  ) {
    this.getId = this.activatedRoute.snapshot.paramMap.get('id');
    this.crudService.GetBook(this.getId).subscribe(res => {
      this.updateForm.setValue({
        name: res['name'],
        price: res['price'],
        description: res['description']
      });
    });
    this.updateForm = this.formBuilder.group({
      name: [''],
      price: [''],
      description: ['']
    })
  }
  ngOnInit() { }
  onUpdate(): any {
    this.crudService.updateBook(this.getId, this.updateForm.value)
    .subscribe(() => {
        console.log('Data updated successfully!')
        this.ngZone.run(() => this.router.navigateByUrl('/books-list'))
      }, (err) => {
        console.log(err);
    });
  }
}

Next, add the below code in the book-detail.component.html file:

<div class="row justify-content-center mt-5">
  <div class="col-md-4">
    <form [formGroup]="updateForm" (ngSubmit)="onUpdate()">
      <div class="form-group">
        <label>Name</label>
        <input class="form-control" type="text" formControlName="name" required>
      </div>
      <div class="form-group">
        <label>Price</label>
        <input class="form-control" type="text" formControlName="price" required>
      </div>
      <div class="form-group">
        <label>Description</label>
        <input class="form-control" type="text" formControlName="description" required>
      </div>
      <div class="form-group">
        <button class="btn btn-primary btn-block" type="submit">Update</button>
      </div>
    </form>
  </div>
</div>

For the topic of Angular 13 CRUD application using Node.js, Express.js, and MongoDB. In the tutorial, we introduce how to create a crud app in Angular 13 using Node js and Mongo DB with built REST API.

Angular 13 Spring WebFlux MongoDB CRUD Operations

In this tutorial, we’re gonna build a full Reactive Application in which, Spring WebFlux, Spring Data Reactive MongoDB are used for backend, and Angular, RxJS, EventSource are on client side.

Related Posts:
How to use Angular Http Client to fetch Data from SpringBoot RestAPI – Angular 13
How to use Angular HttpClient to POST, PUT, DELETE data on SpringBoot Rest APIs – Angular 13
How to build SpringBoot MongoDb RestfulApi
How to use SpringData MongoRepository to interact with MongoDB
Angular 13 + Spring Boot + MongoDB CRUD example
Introduction to RxJS – Extensions for JavaScript Reactive Streams

Continue reading “Angular 13 Spring WebFlux MongoDB CRUD Operations”

How to Integrate Angular 13 & SpringBoot 2.0 RestAPI – SpringToolSuite

In the tutorial, we show you how to integrate Angular 13 with SpringBoot RestAPI for development using SpringToolSuite IDE.

Related posts:
Angular 13 Component – How to create & integrate New Angular 13 Component
Angular 13 Service – with Observable Data for Asynchronous Operation

Spring Boot + Angular 13 example | Spring Data JPA + REST + PostgreSQL CRUD example
Spring Boot + Angular 13 example | Spring Data JPA + REST + MySQL CRUD example
Angular 13 HttpClient + Spring Boot + MariaDB example | Spring Data JPA + RestAPIs CRUD example
Spring Boot + Angular 13 example | Spring Data + REST + MongoDb CRUD example
Spring Boot + Angular 13 example | Spring Data + REST + Cassandra CRUD example

Continue reading “How to Integrate Angular 13 & SpringBoot 2.0 RestAPI – SpringToolSuite”

Angular 13 SpringBoot CRUD Mariadb Example

In this tutorial, we show you Angular 13 Http Client & Spring Boot Server example that uses Spring JPA to do CRUD with MariaDB and Angular 13 as a front-end technology to make request and receive response.

Related Posts:
Spring Boot + Angular 13 example | Spring Data JPA + REST + MySQL CRUD example
Spring Boot + Angular 13 example | Spring Data JPA + REST + PostgreSQL CRUD example
Spring Boot + Angular 13 example | Spring Data + REST + Cassandra CRUD example
How to use Spring JPA with PostgreSQL | Spring Boot

Related Pages:

Continue reading “Angular 13 SpringBoot CRUD Mariadb Example”

Kotlin SpringBoot Angular 13 PostgreSQL CRUD Example

In this tutorial, we show you Angular 13 Http Client & Spring Boot Server example that uses Spring JPA to do CRUD with PostgreSQL and Angular 13 as a front-end technology to make request and receive response.

Related Posts:
How to use Spring JPA with PostgreSQL | Spring Boot
Spring JPA + PostgreSQL + AngularJS example | Spring Boot
Kotlin Spring JPA + Postgresql | Spring Boot Example
Kotlin RequestMapping RESTful APIs with @GetMapping, @PostMapping, @PutMapping, @DeleteMapping
Kotlin SpringJPA Hibernate One-To-Many relationship

Related Pages:

Continue reading “Kotlin SpringBoot Angular 13 PostgreSQL CRUD Example”