In todays's tutorial, we are going to build a full-stack web application using Nest.js and Angular. In here, we'll be building a simple contacts management web application in an Angular and Material Design interface retrieved from a Nest.js RESTful backend.
To proceed with this tutorial you need to Angular installed in your local pc. to check, if Angular is installed or not run below command in your terminal:
1
ng version
To install Angular in your local pc, run below coomand in your terminal:
To install Nest.js on your local pc, run below command in your terminal:
1
npm install -g @nestjs/cli
Setup Working Directory
Now we need to setup our working directory. To setup directory, Head back to your terminal and navigate to your working directory then create a folder your project:
1 2
cd ~/codingtricks mkdir nest-angular-app
Now we need to navigate to our created project and generate the backend and frontend projects using the following commands:
1 2 3
cd nest-angular-app ng new frontend nest new backend
Note:
Then the Angular CLI will prompt you if you Would you like to add Angular routing? (y/N) Enter y and Which stylesheet format would you like to use? Choose CSS and hit Enter.
The Nest CLI will ask you for a bunch of information about your project and CLI will create the necessary files and then prompt you for which package manager to use to install the dependencies. Choose npm.
Next, navigate to your frontend project and serve it using a live-reload development server using the following commands:
1 2
cd frontend ng serve
Open a new terminal and navigate to the backend project then run the development server using the following commands:
1 2
cd backend npm run start:dev
Set up Database and TypeORM
ext, we nned to create a Databse for our project. To create Database access to your php my admin and create database with your prefered name. In my case my Database name is nestng.
Previously I mentioned that we are going to use of TypeORM which is the most mature Object Relational Mapper (ORM) available in TypeScript.
Navigate to your backend project and run the following commands to install the required dependencies:
1
npm install --save @nestjs/typeorm typeorm mysql
Next, you need to open the src/app.module.ts file and import the TypeOrmModule in ApplicationModule:
Make sure to replace YOUR_DATABASE_PASSWORD with your own MySQL database password.
In the configuration object we specify the following options:
mysql database as the type which tells TypeORM to connect to a MySQL database,
nestng database we previously created
entities files contain our ORM entities that will be mapped to SQL tables by TypeORM.
synchronize option (which takes true or false). If true, It tells TypeORM to automatically sync the database tables with the entities each time you run the app. This is helpful in development but not recommended in production.
Now, we have configured TypeORM in our project, we’ll be able to inject the Connection and EntityManager services in your Nest.js services and controllers to work with the database
Creating a Contact Entity
Next, we need to create a Contact entity that will be mapped to a contact table in the MySQL database that will hold information about contacts in our application.
Create a src/entities/contact.entity.ts file and add the following code:
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Contact {
@PrimaryGeneratedColumn() id: number;
@Column() name: string;
@Column() title: string;
@Column() email: string;
@Column() phone: string;
@Column() address: string;
@Column() city: string; }
Next, we need to import that Contact entity and include it in the imports array of the root module using the forFeature() method. Open the src/app.module.ts file and add the following changes:
1 2 3 4 5 6 7 8 9 10 11 12 13
// ... import { Contact } from 'entities/contact.entity';
Now we need to create the REST endpoints that our Angular frontend will be calling to retrieve and create data on the server. Head back to your terminal and run the following command to generate a controller:
1
nest generate controller contacts
Next, open the src/contacts/contacts.controller.ts file and import then inject ContactService
1 2 3 4 5 6 7 8 9
import { Controller } from '@nestjs/common'; import { ContactService } from 'contact.service';
@Controller('contacts') export class ContactsController {
Since we'll be communicating with our REST API from an Angular frontend running on another domain we need to enable CORS. Open the src/main.ts file and call the enableCors() method:
1 2 3 4 5 6 7 8 9
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module';
We'll be using HttpClient and a template-based form in our application so we need to import their modules. Open the src/app/app.module.ts file and update it accordingly:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// [...] import { HttpClientModule } from '@angular/common/http'; import { FormsModule } from '@angular/forms';
Next, let's create a service that contains the code for interfacing with the REST API. In your terminal, run the following command:
1
ng generate service api
Next, open the src/app/api.service.ts file and start by importing and injecting HttpClient:
1 2 3 4 5 6 7 8 9 10 11
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Contact } from './contact';
@Injectable({ providedIn: 'root' }) export class ApiService {
constructor(private httpClient: HttpClient) { } }
We also imported the Contact model.
Next, define the API_SERVER variable that contains the address of the API server:
1 2 3 4
export class ApiService {
API_SERVER = "http://localhost:3000";
Next, add the CRUD operations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public readContacts(){ return this.httpClient.get<Contact[]>(`${this.API_SERVER}/contacts`); }
public createContact(contact: Contact){ return this.httpClient.post<Contact>(`${this.API_SERVER}/contacts/create`, contact); }
public updateContact(contact: Contact){ return this.httpClient.put<Contact>(`${this.API_SERVER}/contacts/${contact.id}/update`, contact); }
public deleteContact(id: number){ return this.httpClient.delete(`${this.API_SERVER}/contacts/${id}/delete`); }
We use the get(), post(), put() and delete() methods of HttpClient to send the GET, POST, PUT and DELETE requests to the corresponding endpoints of the API backend
Creating the Contacts Component
Now, let's create the component where we can display our table of contacts and a form to create contacts.
In your terminal, run the following command:
1
ng generate component contact
Next, open the src/app/app-routing.module.ts file and add a route for accessing the component:
1 2 3 4 5 6 7 8 9 10
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { ContactComponent } from './contact/contact.component';
The displayedComumns variable holds the name of the columns that will be displayed in the Angular Material Table we’ll be adding later. The dataSource variable will contain the data of the table and the contact variable will contain the selected contact from the table.
Next, retrieve the contacts from the server when the component is initialized:
We simply call the readContacts() method of ApiService in the ngOnInit() method of the component and we subscribe to the returned RxJS Observable then we assign the result to the dataSource variable.
Next, add the selectContact() and newContact() methods:
1 2 3 4 5 6 7
selectContact(contact){ this.contact = contact; }
newContact(){ this.contact = {}; }
The selectContact() method assigns the selected contact to the contact variable and the newContact() method assigns an empty object to the contact variable. These two methods will be bound to a select and new buttons that will be adding later in our UI.
Finally, add the other CRUD methods to create, update and delete contacts:
In this tutorial, we obtain how can we create built a full-stack web application with Angular and Nest.js. You can obtain complete source code for this tutorial from this GitHub repository.