DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • OWASP TOP 10 API Security Part 2 (Broken Object Level Authorization)
  • Stretching Async/Await With Lambdas
  • Develop a Secure CRUD Application Using Angular and Spring Boot
  • Rails 6: Multiple DB Support

Trending

  • FIPS 140-3: The Security Standard That Protects Our Federal Data
  • Optimizing Integration Workflows With Spark Structured Streaming and Cloud Services
  • Revolutionizing Financial Monitoring: Building a Team Dashboard With OpenObserve
  • Mastering Advanced Traffic Management in Multi-Cloud Kubernetes: Scaling With Multiple Istio Ingress Gateways
  1. DZone
  2. Data Engineering
  3. Databases
  4. Step-by-Step Guide: Application Using NestJs and Angular

Step-by-Step Guide: Application Using NestJs and Angular

NestJs is, in my opinion, a great solution for Angular developers (like me) to start coding in a NodeJs environment as it is heavily based on Angular.

By 
ag dev user avatar
ag dev
·
Jan. 20, 21 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
12.6K Views

Join the DZone community and get the full member experience.

Join For Free

Just a few days before Christmas, I came along the NestJs framework. I always wanted to give NodeJs development a try, but the idea of a JavaScript backend seemed to keep me away.

NestJs is a framework for building Node.js server side applications and supports Typescript. Since almost all my experience is with Angular and NestJs provides an out-of-the box application architecture heavily inspired by Angular, it seemed like all the boxes were checked and I had to give it a try. For more information, please visit NestJs Official Documentation.

In this post, I will show you how to create a simple application with Angular frontend, NestJs backend, and Postgres database. To integrate with the database, Nest uses TypeORM and we will need to specify Postgres when installing TypeORM.

Application Description

I will create a demo application that will manage the user budget. The user can create, update, view, and delete expenses and incomes. For each expense, there will be an expense category. I will set up first the expense category for this article.

Server-Side Application With NestJs

The first step is to set up and create the application using the following commands:

  1. npm i -g @nestjs/cli
  2. nest new budget-be
  3. npm install — save @nestjs/typeoprm typeorm postgres

At this point, we are ready to start working with the server-side application. When creating the server-side application by default, it is created App Module, App Controller, and App Service.

Connecting to the Database

I have created the budget management database in Postgres. In App Module, we will need to set up the connection to the database by specifying it inside TypeOrmModule in the import.

Java
 




x
10


 
1
TypeOrmModule.forRoot({
2
       type: "postgres",
3
       host: "localhost",
4
       port: 5432,
5
       username: "postgres",
6
       password: "root",
7
       database: "budget-management",
8
       entities: [ExpenseCategory],
9
       synchronize: true
10
})


Inside the TypeOrmModule import, I have specified the host, username, database name, and password according to my definitions. At this point, we are ready to start implementing the Expense Category Module.

Set Up Expense Category Module

Here, will show you steps to create Expense Category Module that will be responsible for all the requests coming to expense-category from the front end.

1. Expense Category Dto

First, I will create the Expense Category DTO (Data Transfer Object), which determines how the data will be sent over the network. We will use it inside the controller later. For this example, it will be a very simple object containing only an id and a category. The implementation is done as follows:

JavaScript
 




xxxxxxxxxx
1


 
1
export class ExpenseCategoryDto {
2
       readonly id: number;
3
       readonly category: string;
4
}


2. Expense Category Entity

The Entity class marked with the @Entity decorator corresponds to an entity in the database. The expense category entity will be:

JavaScript
 




xxxxxxxxxx
1


 
1
@Entity()
2
export class ExpenseCategory {
3
       @PrimaryGeneratedColumn()
4
       id: number;
5
 
          
6
       @Column()
7
       category: string;
8
} 


In order to use the Entity, we should specify it inside the TypeOrmModule.

3. Expense Category Controller

Controllers are responsible for receiving requests and return a response to the client. It is the routing mechanism that decides which controller should handle the incoming request. My application will display a list of expense categories that the user can update, delete, or create a new one. So, I will need to manage in my Controller all these types of requests. Here is the Controller I implemented:

JavaScript
 




xxxxxxxxxx
1
31


 
1
@Controller('expense-category')
2
export class ExpenseCategoryController {
3
 
          
4
  constructor(private expenseCategoryService: ExpenseCategoryService){}
5
 
          
6
  @Get()
7
  getExpenseCategories() {
8
    return this.expenseCategoryService.find();
9
  }
10
 
          
11
  @Post()
12
  create(@Body() expenseCategory: ExpenseCategoryDto) {
13
    return this.expenseCategoryService.create(expenseCategory);
14
  }
15
 
          
16
  @Get(':id')
17
  findOne(@Param('id') id: string) {
18
     return this.expenseCategoryService.findOne(id);
19
 }
20
 
          
21
  @Put()
22
  @ApiBody({ type: ExpenseCategoryDto })
23
   update(@Body() expenseCategory: ExpenseCategoryDto) {
24
     return this.expenseCategoryService.update(expenseCategory);
25
  }
26
 
          
27
  @Delete(':id')
28
  remove(@Param('id') id: number) {
29
     this.expenseCategoryService.remove(id);
30
 }
31
}


4. Expense Category Repository

TypeORM supports the Repository design pattern. For this reason, the Expense Category Entity will have its own repository. To implement a custom repository, we need to extend Repository from typeorm. It is marked with the @EntityRepository decorator. The implementation is as below. I have implemented this just to try it, but even the default repository is fine for this case.

JavaScript
 




xxxxxxxxxx
1


 
1
@EntityRepository(ExpenseCategory)
2
export class ExpenseCategoryRepository extends  Repository<ExpenseCategory> {
3
createExpenseCategory = async (expenseCategoryDto: ExpenseCategoryDto) => {
4
     return await this.save(expenseCategoryDto);
5
     };
6
}


5. Expense Category Service

Dependency Injection works the same as in Angular. I will define a service using the @Injectable decorator and will declare it under Providers in the Expense Category Module. Here, I will implement all the methods to create, get, find, update, and delete what I have used inside the Controller.

JavaScript
 




xxxxxxxxxx
1
26


 
1
@Injectable()
2
export class ExpenseCategoryService {
3
 
          
4
constructor(
5
        @InjectRepository(ExpenseCategoryRepository) private    readonly expenseCategoryRepository: ExpenseCategoryRepository){}
6
 
          
7
find() {
8
    return this.expenseCategoryRepository.find();
9
}
10
 
          
11
create(expenseCategory: ExpenseCategoryDto) {
12
    return this.expenseCategoryRepository.insert(expenseCategory);
13
}
14
 
          
15
findOne(id: string) {
16
    return this.expenseCategoryRepository.findOne(id);
17
}
18
 
          
19
update(expenseCategory: ExpenseCategoryDto) {
20
    return this.expenseCategoryRepository.save(expenseCategory);
21
}
22
 
          
23
remove(id: number) {
24
    this.expenseCategoryRepository.delete(id);
25
 }
26
}


6. Expense Category Module

At this point, we have set up the expense category entity, controller, service, repository, and dto. We will include this in the Expense Category Module which later will be imported in the App Module and we can consider the server-side implementation finished.

JavaScript
 




xxxxxxxxxx
1


 
1
@Module({
2
   imports: [
3
     TypeOrmModule.forFeature(
4
       [ExpenseCategory, ExpenseCategoryRepository]
5
)],
6
controllers: [ExpenseCategoryController],
7
providers: [ExpenseCategoryService]
8
})
9
export class ExpenseCategoryModule {}


Front End Application With Angular

After setting up the server-side application, I will create a new Angular application that will connect to NestJs Application to display and modify expense categories. I will not get in deep details regarding the Angular implementation, but rather give you a general implementation.

By executing:

  1. ng new budget-fe
  2. ng g c expense-category

...we will create the budget management application and the expense category component. In order to connect to the server side, I will configure proxy.conf.json as below:

JSON
 




xxxxxxxxxx
1
11


 
1
{
2
  "/api/*": {
3
       "target": "http://localhost:3000",
4
       "secure": false,
5
       "logLevel": "debug",
6
       "changeOrigin": true,
7
       "pathRewrite": {
8
             "^/api": ""
9
        }
10
    }
11
}


Implementing CRUD in Angular for Expense Category

First, I will implement the service that will handle all the requests as below.

After implementing the service, we will update the expense-category-component to get the data and add some actions to the UI such as create, modify, and delete.

JavaScript
 




xxxxxxxxxx
1
23


 
1
@Injectable()
2
export class ExpenseCategoryService {
3
static URL = '/api/expense-category';
4
 
          
5
constructor(public http: HttpClient){}
6
 
          
7
getCategories(): Observable<ExpenseCategoryModel[]> {
8
       return this.http.get<ExpenseCategoryModel[]>
9
               ExpenseCategoryService.URL);
10
}
11
 
          
12
createCategory(category: ExpenseCategoryModel) {
13
    return this.http.post(ExpenseCategoryService.URL, category);
14
}
15
 
          
16
modifyCategory(category: ExpenseCategoryModel): Observable<ExpenseCategoryModel> { 
17
     return this.http.put<ExpenseCategoryModel>(ExpenseCategoryService.URL, category);
18
}
19
 
          
20
deleteCategory(id: number): Observable<any> {
21
  return this.http.delete(ExpenseCategoryService.URL + `/${id}`);
22
}
23
}


The template for this example will be a list of items displaying the id and name of the category.

JavaScript
 




xxxxxxxxxx
1
16


 
1
<button mat-mini-fab (click)="add()">
2
  <mat-icon>add</mat-icon>
3
</button>
4
<mat-list *ngIf="expenses$ | async as expenses">
5
     <mat-list-item *ngFor="let expense of expenses">
6
           <div mat-line>{{expense.id}}
7
             <button mat-mini-fab (click)="modify(expense.id)" >
8
                 <mat-icon>edit</mat-icon>
9
             </button>
10
            <button mat-mini-fab (click)="delete(expense.id)">
11
                <mat-icon>delete</mat-icon>
12
            </button>
13
         </div>
14
         <div mat-line>{{expense.category}} </div>
15
   </mat-list-item>
16
</mat-list>


Component definition will be:

JavaScript
 




xxxxxxxxxx
1
33


 
1
@Component({
2
    selector: 'app-expense-category',
3
    templateUrl: './expense-category.component.html',
4
    styleUrls: ['./expense-category.component.scss']
5
})
6
export class ExpenseCategoryComponent implements OnInit {
7
 
          
8
expenses$: Observable<any[]>;
9
 
          
10
constructor(private service: ExpenseCategoryService) { }
11
 
          
12
ngOnInit(): void {
13
     this.getCategories();
14
}
15
 
          
16
getCategories = () => {
17
    this.expenses$ = this.service.getCategories();
18
}
19
 
          
20
add(): void {
21
  const newCategory = {id: null, category: 'New Category'};
22
  this.service.createCategory(newCategory);
23
}
24
 
          
25
modify(id: number) {
26
   const updatedCategory  = {id, category: 'Modified Category'};
27
   this.service.modifyCategory(updatedCategory);
28
}
29
 
          
30
delete(id: number) {
31
   this.service.deleteCategory(id).subscribe(this.getCategories);
32
  }
33
}


In the component, I am injecting the service in order to get, update, and delete expense categories. As I mentioned before, the front-end is a simple implementation just to see that the applications are connecting with each other and I have correctly implemented the server side.

Conclusions

NestJs is, in my opinion, a great solution for Angular developers (like me) to start coding in a NodeJs environment as it is heavily based on Angular. Creating a simple application, both server side and front-end was easy and quite interesting for me. I will continue to work and experiment in NestJs and will give you more updates. I would highly recommend giving it a try because as they say, “The proof of the pudding is in the eating”

application AngularJS Database JavaScript app Repository (version control) Implementation Requests Dependency injection

Opinions expressed by DZone contributors are their own.

Related

  • OWASP TOP 10 API Security Part 2 (Broken Object Level Authorization)
  • Stretching Async/Await With Lambdas
  • Develop a Secure CRUD Application Using Angular and Spring Boot
  • Rails 6: Multiple DB Support

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!