Part 6. Clock-in/out System: Basic frontend - Angular
Tags: javascript, typescript, node, nestjs
Published: 2019-03-18 20:41:13

---
title: Part 6. Clock-in/out System: Basic frontend - Angular
published: true
tags: javascript, typescript, nodejs, nestjs
description: This is the first post about the frontend for our clock-in/out system, which already has a basic, functional backend working. The frontend will be developed using the JS framework [Angular ](https://www.angular.io/) due to it being the best framework, in the sense of software architecture, (my intent isn’t to unleash a war about which is the best/worst JavaScript framework). This is a post about my system, I’m sure that there are better solutions for developing this layer of my software :-).
series: clock-in/out system
canonical_url: https://carloscaballero.io/part-6-clock-in-out-system-basic-frontend/
cover_image: https://cdn-images-1.medium.com/max/1000/1*KhCkmbtORw2Ux3n5WCrtzA.png 
---

This post is part of a Series of post which I’m describing a clock-in/out system
if you want to read more you can read the following posts:


* [Part 1. Clock-in/out System: Diagram.](https://dev.to/carlillo/part-1-clock-inout-system---diagram-4kgj)
* [Part 2. Clock-in/out System: Basic backend — AuthModule.](https://dev.to/carlillo/part-2-clock-inout-system-basic-backend-i--authmodule-d2l)
* [Part 3. Clock-in/out System: Basic backend — UsersModule.](https://dev.to/carlillo/part-3-clock-inout-system---basic-backend-ii---usersmodule-5hf5)
* [Part 4. Clock-in/out System: Basic backend- AppModule.](https://dev.to/carlillo/part-4-clock-inout-system---basic-backend-iii---appmodule-5anb)
* [Part 5. Clock-in/out System: Seed Database and migration data](https://dev.to/carlillo/part-5-clock-inout-system-seed-database-and-migration-data-320m)
* [Part 6. Clock-in/out System: Basic frontend.](https://dev.to/carlillo/part-6-clock-inout-system-basic-frontend---angular-28pg)
* [Part 7. Clock-in/out System: Deploy backend (nestJS) using docker/docker-compose.](https://dev.to/carlillo/part-7-deploy-backend-nestjs-dockerdocker-compose-3cmb)
* [Part 8. Clock-in/out System: Deploy frontend (Angular 2+) using environments.](https://dev.to/carlillo/part-8-clock-in-out-system-deploy-frontend-angular-6-using-environments-nog)
* [Part 9. Testing: Backend Testing — Unit Testing - Services](https://dev.to/carlillo/part-9-clock-in-out-system-testing-backend-testing-3imk)
* [Part 10. Testing: Backend Testing — Unit Testing - Controllers](https://dev.to/carlillo/part-10-testing-backend-testing-unit-testing-controllers-573a)
* Part 11. Testing: Backend Testing — E2E Testing
* Part 12. Testing: Frontend Testing — Unit Testing
* Part 13. Testing: Frontend Testing — Integration Testing


This is the first post about the frontend for our clock-in/out system, which
already has a basic, functional backend working. The frontend will be developed
using the JS framework [Angular ](https://www.angular.io/) due to it being the
best framework, in the sense of software architecture, (my intent isn’t to
unleash a war about which is the best/worst JavaScript framework). This is a
post about my system, I’m sure that there are better solutions for developing
this layer of my software :-).

**The result is shown below**

![](https://cdn-images-1.medium.com/max/1000/0*bYID6EW0MszXitX4.gif)

### Well…. Let’s go!

The first step is creating a new project using [angular-cli](https://cli.angular.io/):

![](https://cdn-images-1.medium.com/max/1000/1*gBL-sUzQ0-tSXo2xSUPYDA.png)

In our context, a routing is not required, because our frontend is not an [SPA](https://en.wikipedia.org/wiki/Single-page_application) (OMG! So why are you using Angular then? Because this is a simple tutorial to show how to integrate [NestJS](https://nestjs.com/) + [Angular](https://www.angular.io/)).

The next step is to install several libraries that are dependencies in our code ([Angular Material](https://material.angular.io/)):


Our project has three important points:

1.  **AppModule**: This is the main module, which is responsible for launching the
other modules.
2.  **UserComponent**: This component is used to add new users and their keys (it’s only for admin purposes, although there isn’t any security).
3.  **TicketingComponent**: This is the most important component, since this is the one which refreshes the screen with the information about the users who should be working in the building.

Now, I’m going to show and explain each of the modules.

### AppModule

This is the module which is used to launch the other modules. In the following code I’m loading the modules:

1.  **Angular Material**:
  1.  **MatTableModule**: The table that will show the list of users which are in the building.
  2.  **MatInputModule**: Form’s input that will be used to add the users-keys pair.
2.  **RouterModule**: This module will be used to load the clock-in/out and admin
pages.
3.  **FormsModule**: This module is required to use template-driven forms in our
project.
4.  **BrowserModule** and **BrowserAnimationsModule**: These are the modules
required to use Angular in the browser (and the animations).
5.  **HttpClientModule**: This module will be used to communicate the frontend and the backend using the HTTP protocol.

The `Route[]` are the routes to load our components. In our case it's very easy,
because the default path will load `TicketingComponent` and the path `/user`
will load our admin page (`UserComponent`).

Lastly, we must declare our components in the `AppModule`: `AppComponent`,
`UserComponent` and `TicketingComponent`

![](https://cdn-images-1.medium.com/max/1000/1*TlKbBS3AaldYZhX9BcaPSg.png)

The `AppComponent` is the bootstrap of our app. This component only runs the
`router-outlet`.

![](https://cdn-images-1.medium.com/max/1000/1*xCXDW11BLAG1R6gIbT0vlw.png)

### Constants and environment

In any software we develop, we need different constants and environment variables, i.e, [http://localhost:4200](http://localhost:4200/) is the traditional URI to develop an Angular app, although you need to change the domain or the port when you deploy your app. For this purpose, Angular provides us with configuration to change between different environments.

So, the file `AppSettings` can define every our constants. The most important
constant is the APIENDPOINT which is provide from the file `environment`.

![](https://cdn-images-1.medium.com/max/1000/1*sE-LerIthjLeph633v8mmQ.png)

The `environment` file is loaded by default when you're developing an Angular
app:

![](https://cdn-images-1.medium.com/max/1000/1*6ySFg0s64E9RCm6TljD1wQ.png)

The only difference in the `environment.production.ts` file is the `APIENDPOINT_BACKEND` constant, which contains the name of the machine on which our app is deployed (In our case, a docker container).

![](https://cdn-images-1.medium.com/max/1000/1*SGtW7sr7hmhHAZOKX0kDNQ.png)

### Ticketing Component

The ticketing component is the most interesting piece of code in this project,
due to it having been developing using [RxJS](https://rxjs-dev.firebaseapp.com/)to make the system in near-realtime. This example doesn’t use redux, so the double data-binding is used to refresh the template, from the logic part. This component’s template is the following.

![](https://cdn-images-1.medium.com/max/1000/1*hOglaVPJSlisE-cC6km0eg.png)

You may note that the template has several `Observable$`, which are rendered using the pipe `async`. For example, in the following code, the `span` tag redered the result of the subscription of the observable `timestamp$`. This pipe is a syntactic sugar for the traditional `subscribe` method. You can read more about this pipe in the [official documentation.](https://angular.io/api/common/AsyncPipe)


Other interesting point of the template is the use of the component `Material Datatable` which can received a set of data to be rendering in a table or an observable using the input `[source]` but in our case the `Datatable` will receive a set of data (after that the pipe `async` will do its job). Futhermore, the data are show in two different tables, so the data are separated in two sets using the method `middle`.

The CSS is quite simple and is shown in the following code:

![](https://cdn-images-1.medium.com/max/1000/1*ZTCSM2Ghf2FOSyZ7cMuNag.png)

Although this post isn’t about CSS, you must know NEVER to use `id`'s in styling your web (you can read more about this fact in [dev.to](https://dev.to/claireparker/reasons-not-to-use-ids-in-css-4ni4), [CSSWizard](https://csswizardry.com/2011/09/when-using-ids-can-be-a-pain-in-the-class/)
and [developingdesigns](https://www.developingdesigns.com/stop-using-ids-in-your-css/)).

Our CSS file is simple, since it’s only styling our table (which must have a `width` of 49.50% and different typography size adjustments).

I will now reveal the most interesting piece of code in this post, the `TicketingComponent`, which has the subsequent attributes:

![](https://cdn-images-1.medium.com/max/1000/1*Rqzp4ihwKATBfUsZ_tz-DA.png)

The description of each of our attributes is:

* `usersAbsent$`: This is the observable which contains the list of `User` which
are not in the building.
* `usersPresent$`: This is the observable which contains the list of `User` which
are in the building.
* `timestamp$`: This is the observable which contains the timestamp from the server.
* `displayedColumns`: The array of columns which will be shown in the table.

It is very important to remember that we’re using observables in our code to provide us with the power of stream’s manipulation by using the [RxJS](https://rxjs-dev.firebaseapp.com/) operators. These observables are subscribed using the pipe `async` in the template.

Our next step is the component constructor, where the real magic appears! You
must understand the streams in [RxJS](https://rxjs-dev.firebaseapp.com/) to be
able to understand the following code:

![](https://cdn-images-1.medium.com/max/1000/1*DQjwroGQrG_ciP2YAv7yMg.png)

This code does the following:

The observable `interval$` is created using the `timer` operator, which in turn
will trigger a call each 3000 ms. In the subsequent line of the code you can see
how the observable `data$` is created from the observable `interval$` which runs
a http request using the `httpClient` service.

The `get` request then return an object comprising a list of users and a timestamp (from the server). Two sections of this code fragment are particularly
relevant:

1.  The operator `switchMap` is used to cancel an unfinished request when a new
request is made (to avoid several request being made at the same time).
2.  The operator `retryWhen` is used to handle the server errors. For example, if the connection is lost in the client or server you will need to retry again the request. So, when the code has an error, the request will be retried in 3000 ms.

Ok, now the observable `data$` has a stream containing information about the list of users and timestamp. The observable `users$` is created from the observable `data$` which does a destructuration in each stream of data (this is the reason for the `map`operator being there). If you have understood the previous code, you can imagine how the observable `timestamp$` is created. This timestamp is in unix format, we need to transform it to the DATE_FORMAT (DD/MM/YYYY).

Perhaps you can now imagine how the `usersPresent$` and `usersAbsent$` observables are created from the `users$` observable. For these observables you must use the [RxJS](https://rxjs-dev.firebaseapp.com/) `map` operator to create a new observable, using the Array.prototype `filter` method. The last step is creating the private `isPresent` and `isAbsent` methods, which are shown subsequently:

![](https://cdn-images-1.medium.com/max/1000/1*CHP7nzhXFbvYPmv2c6fH-g.png)

These methods basically check if the user has been authorized by the system, and whether the action is `INPUT` or `OUTPUT`.

So, the complete controller code is the following:

![](https://cdn-images-1.medium.com/max/1000/1*RkuV3mZfGSaqFZ0raQbsxw.png)

### User Component

The last component of our basic frontend is the `UserComponent`, which is a simple form to add users and keys to our database. The idea to build this component is the same as the one used in the `TicketingComponent`. Therefore, the template to do the operation `subscribe`s using the `async` pipe.

![](https://cdn-images-1.medium.com/max/1000/1*9C6F5I9TLcYyQogFRVc4gQ.png)

The template uses the if-else of the `ng-container` to show a message when nobody has a key.

The `UserComponent` code is the following:

![](https://cdn-images-1.medium.com/max/1000/1*CcbadFxtpTQecdv7ytDSTw.png)
<span class="figcaption_hack">Type caption for image (optional)</span>

In this case, we’ve defined four relevant attributes:

1.  Observable `users$` which contains the list of users' UID.
2.  The string `userID` which contains the userID selected from the template.
3.  The string `key` which is the key that will be assigned to the user.
4.  Observable/Subject `update$` which allows us to know that the action updated was done successful.

The constructor is very similar to the constructor in the `TicketingComponent`, due to it recovering the list of users' UID from the backend, by using the `switchMap` and `map` operators.

Finally the `save` method makes a request `POST` to the backend with the object that the backend requires to save the information.

### Conclusion

‌In this post I’ve explained my **basic frontend**, developed with Angular and RxJS to ensure a near real-time system (using polling as the technique to connect with the server).

![](https://cdn-images-1.medium.com/max/1000/0*9qxZNnXW2nfISGI2.gif)

The GitHub project is [https://github.com/Caballerog/clock-in-out](https://github.com/Caballerog/clock-in-out).<br>
The GitHub branch of this post is [https://github.com/Caballerog/clock-in-out/tree/part6-basic-frontend](https://github.com/Caballerog/clock-in-out/tree/part6-basic-frontend).

*****

Originally published at [www.carloscaballero.io](https://carloscaballero.io/part-6-clock-in-out-system-basic-frontend/) on January 18, 2019.