Create a list of employees with Angular.
Tags: angular, angularnation, beginners, webdev
Published: 2022-04-25 08:55:11

Hello reader! In this post I'll be sharing with you what I have learned so far with angular. 

We're building a list of employees that fetches employees Data over HTTP and display an employee's detailed information via a modal after a list item is clicked by using Angular, Angular Material, and Tailwind CSS.


![Demo list of employees](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hi94soabz5yjc6ehisjb.gif)


## What we'll learn:
* Identify what components are involved.
* Use Angular Material to create a list and a modal to show a detailed information of an employee. 
* Use Tailwind CSS to style almost everything!
* Create a pipe to combine `First Name` and `Last Name` to `Full Name`.
* Fetch employees data with `HttpClient` and display it using `RXJS`.


## What we need:
* Angular Essentials by John Papa. For a better dev experience in angular development.
* An Angular ~ 13.3.0 app. `ng new ngEmployeeListDemo`
* Installed Angular Material. `ng add @angular/material`
* Installed [Tailwind CSS](https://tailwindcss.com/docs/guides/angular).
* Employees Data [API](https://hub.dummyapis.com/employee).
* Basic knowledge of generating angular components. `ng generate`

## Angular Settings Considerations
For this demo we'll keep the files minimal as possible so we'll be combining Typescript, HTML, and CSS in a single file(we won't make much CSS anyways since Tailwind will do the heavy lifting) and remove additional files when generating a component but this is optional and you can have your preferred settings. 

`angular.json`
![angular.json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5egv0ai3r5j5n7fydaxs.jpg)
 
## Our Project Structure
![Project Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pp3tybocltsdycdti6hj.jpg)

## Tailwind Configuration
![Tailwind](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/so6w97a2p7ytll0x0ouh.png)
 
 
## Let's begin!

First and foremost, I assume you already have and Angular app with Angular Material and Tailwind CSS installed as mentioned above. If you haven't, please check that out.

## The EmployeeModule

To keep our employee-related stuff in place, we simply generate a module named `EmployeeModule` and import it in the `AppModule`.
```
ng generate module employees/employee --flat
```

In `employee.module.ts` we need to define our interface that describes an `Employee`. Next, we need to import some of the material components and the HttpClientModule:
* `MatListModule`
* `MatDialogModule`
* `MatButtonModule`
* `MatCardModule`
* `HttpClientModule`

Now, your `employee.module.ts` should look like this:

![Employee Module](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmhzbsmv5nb1orvvrzqy.png)
 
 

Next, we define our api url from the `environment.ts`
![env](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzosastomvx83ygy7wya.png)
 
 

## The EmployeeListComponent

This component will be responsible in fetching our array of employees and then display each employee represented by a component called `EmployeeListItem` which we will define later.
```
ng g c employees/employee-list
```
After generating this component, switch back to `EmployeeModule` to ensure that the `EmployeeListComponent` is present in the `declarations` and `exports` array, otherwise you need to put it manually. 
Now, switch back to `employee-list.component.ts` and copy the following:

![employee-list.component.ts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzw3v9qz7szucxknp1ly.png)
 

Let's understand what we have done here:

* We defined a property `employees` as an Observable of Employee[] and initialized with an Observable of empty array that will hold our employees after fetching from the API.
* We injected `HttpClient` to enable us from fetching the employees API.
* We defined `getEmployees()`, a function that will do the fetching of our employees API.
* In `ngOnInit`, we instructed angular that after our component is initialized, we immediately fetch our employees via `getEmployees` and save the results to our `employees` property.

Why does `employees` property have to be an Observable<Employee[]> and not just a plain Employee[]? 
By declaring this as an observable, we can take advantage of the `async` pipe in the template that will automatically handle the subscription and the unsubscription of the http call which saves lines of code in manual subscription and unsubscription. We can also benefit from an automatic cancellation of a pending http call when the component is destroyed(such as when you navigate to other page).
 
To display this component, we put it in `app-component.html`

![app component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8i0mscncghhnohme47j2.png)
 
Let's take a look! type `ng serve -o` in the terminal and you should be seeing something like this:

![empty list](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l95und4frz2mniloraey.png)
 
## The EmployeeListItemComponent
This component represents an employee and will be responsible in displaying our modal called `EmployeeDetailsDialogComponent` which we will define later. Here, we only need to display the employee's profile picture and the last name.
```
ng g c employees/employee-list-item
```
![Employee List Item](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/431084h0vnlqj35m6vjb.png)
 
Switch back to `employee-list.component.ts` and uncomment this template:

![employee-list.component.ts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56mrdlwi3i315iiro10q.png)
 
Save your changes and let the app refresh. Your app should look like this:
![List with name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l4dabarra3t62cs0bikn.png)
 
## The EmployeeFullNamePipe
As you can see in the `EmployeeListItemComponent` we are only displaying the `firstName` but our requirement is to display the employee's full name. To achieve this, we create `EmployeeFullNamePipe`.
```
ng g p employees/employee-full-name --skipTests=true 
```
![FullName](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5t6jesg9xrpuj2d1t4yb.png)
 
Then update `employee-list-item.component.ts` to this:
![Employee with Full Name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djnj3jcpnkcsespjf3nf.png)
 
So far, so good!
![employee-list-item.component.ts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8j7xr6z6jbf46drilcf3.png)
 
## The EmployeeDetailsDialogComponent
We are almost there! This is the last component we need to implement to complete our app. This component will be responsible in displaying a detailed information of an employee.
```
ng g c employees/employee-details-dialog
```
After generating the component, we need to go back to `employee-list-item.component.ts` and we will implement the `showDetails`.

![employee-list-item.component.ts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tb5yz1vsxt3v1le9biwe.png)
 
`employee-details-dialog.component.ts`

![Employee Details Dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dodp74zapt34tvskedmf.png)
 
And that's it! Reload your app and see the salaries of your employees!

![Demo list of employees](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hi94soabz5yjc6ehisjb.gif)

If you're wondering why I used CodeSnaps instead of markdown, I actually wanted to keep the beginners from copy-pasting the code and for them to appreciate the IntelliSense and the type system that typescript offers. Before, I used to declare properties in `any` type thinking that it is faster to write and I could care less about these objects until I ran into problems where I had `undefined` errors because `firstName` was declared as `firstNaem`. By developing in a strict mode setting, it helps reduce the headaches we get from the runtime errors due to misspellings and invalid accesses of an object since this will be detected during the compilation process and we get better IntelliSense support as we type `.` after the object or `ctrl + space` which is more faster and is care-free.

I hope that I may have helped you in some way and learned something even a little from this blog. For the seniors, please let me know what are some of the areas I need to improve. Thank you!


[Source Code](https://github.com/suicodave/EmployeeListBlogDemo)

Credits to Rob Ramirez(and the people of Angular Nation) for the idea and the motivation to create this blog.