Part I - First Component

First Step – Adding login

The first step on this tutorial will be to add a login component to learn how to interact with the Bexstream backend API.

1 – Creating the login component

ng generate component login

This command creates 3 files:

login.component.ts login.component.html login.component.less

2 – Adding the login form

Firstly the User model must be added to our application. Create a folder called “models” under “src/app/login” and add a new file called “user.ts”. Add the following code:

Listing 1 user.ts
 1export class User {
 2    id: string;
 3    username: string;
 4    email: string;
 5    profileImage: string;
 6    password: string;
 7    hash: string;
 8    description: string;
 9    createdDate: Date;
10    token: string;
11    roles: any[];
12    organization: any;
13    constructor() {
14        this.id = '';
15        this.username = '';
16        this.email = '';
17        this.profileImage = '';
18        this.password = '';
19        this.hash = '';
20        this.description = '';
21        this.createdDate = new Date();
22        this.token = '';
23        this.roles = [];
24    }
25}

Secondly add to the login.component.ts file the following code:

Listing 2 login.component.ts
 1import { Component, OnInit } from '@angular/core';
 2import { FormBuilder } from '@angular/forms';
 3import { User } from './models/user';
 4
 5@Component({
 6    selector: 'app-login',
 7    templateUrl: './login.component.html',
 8    styleUrls: ['./login.component.less']
 9})
10export class LoginComponent implements OnInit {
11
12    user: User = new User();
13
14    loginForm = this.formBuilder.group({
15        username: '',
16        password: ''
17    });
18
19    constructor(private formBuilder: FormBuilder) { }
20
21    ngOnInit(): void {
22    }
23
24    /**
25    * User authentication method
26    */
27    public authenticate(): void {
28    }
29
30
31}

Since we will be using ReactiveForms we need to add this module to our app module, located in app.module.ts.

Listing 3 app.module.ts
 1import { BrowserModule } from '@angular/platform-browser';
 2import { NgModule } from '@angular/core';
 3import { ReactiveFormsModule } from '@angular/forms';
 4
 5import { AppRoutingModule } from './app-routing.module';
 6import { AppComponent } from './app.component';
 7import { LoginComponent } from './login/login.component';
 8
 9@NgModule({
10    declarations: [
11        AppComponent,
12        LoginComponent
13    ],
14    imports: [
15        BrowserModule,
16        AppRoutingModule,
17        ReactiveFormsModule,
18    ],
19    providers: [],
20    bootstrap: [AppComponent]
21})
22export class AppModule { }

Attention

After adding a new module, we must restart our angular app. Stop the running ng serve and run it again.

Edit login.component.html with the following code:

Listing 4 login.component.html
 1<h3>Login Form</h3>
 2
 3<form [formGroup]="loginForm" (ngSubmit)="authenticate()">
 4
 5<div>
 6    <label for="username">
 7        Username
 8    </label>
 9    <input id="username" type="text" formControlName="username">
10</div>
11
12<div>
13    <label for="password">
14        Password
15    </label>
16    <input id="password" type="password" formControlName="password">
17</div>
18
19<button class="button" type="submit">Login</button>
20
21</form>

3 – Adding the component to the app

First, clear app.component.html file and add the following line:

Listing 5 app.component.html
1<router-outlet id="parent-router-outlet"></router-outlet>

The router-outlet turns our application into a single page application where to a certain route (ex. http://localhost:4200/drones) matches with a Component (ex. DroneListComponent).

Second, lets add a route and the corresponding component to the “routes” variable:

Listing 6 app-routing.module.ts
 1import { NgModule } from '@angular/core';
 2import { Routes, RouterModule } from '@angular/router';
 3import { LoginComponent } from './login/login.component';
 4
 5const routes: Routes = [
 6    { path: '', component: LoginComponent },
 7];
 8
 9@NgModule({
10    imports: [RouterModule.forRoot(routes)],
11    exports: [RouterModule]
12})
13export class AppRoutingModule { }

In our case the root url (“/”) will show our LoginComponent.

4 – Invoking bexstream backend API

We will use HTTP, to communicate with the bexstream API. So the first step is to import it to our App module in app.module.ts:

Listing 7 app.module.ts
 1import { BrowserModule } from '@angular/platform-browser';
 2import { NgModule } from '@angular/core';
 3import { ReactiveFormsModule } from '@angular/forms';
 4import { HttpClientModule } from '@angular/common/http';
 5
 6import { AppRoutingModule } from './app-routing.module';
 7import { AppComponent } from './app.component';
 8import { LoginComponent } from './login/login.component';
 9
10@NgModule({
11    declarations: [
12        AppComponent,
13        LoginComponent
14    ],
15    imports: [
16        BrowserModule,
17        AppRoutingModule,
18        ReactiveFormsModule,
19        HttpClientModule
20    ],
21    providers: [],
22    bootstrap: [AppComponent]
23})
24export class AppModule { }

Restart your angular app.

Afterwards, we will add the communication code to the authenticate method on login.component.ts:

Listing 8 login.component.ts
 1import { Component, OnInit } from '@angular/core';
 2import { FormBuilder } from '@angular/forms';
 3import { HttpClient } from '@angular/common/http';
 4import { User } from './models/user';
 5
 6@Component({
 7    selector: 'app-login',
 8    templateUrl: './login.component.html',
 9    styleUrls: ['./login.component.less']
10})
11export class LoginComponent implements OnInit {
12
13    user: User = new User();
14
15    loginForm = this.formBuilder.group({
16        username: '',
17        password: ''
18    });
19
20    constructor(private formBuilder: FormBuilder,
21                private http: HttpClient) { }
22
23    ngOnInit(): void {
24    }
25
26    /**
27    * User authentication method
28    */
29    public authenticate(): void {
30        const loginFormValues = this.loginForm.value
31        this.user.username = loginFormValues.username;
32        this.user.password = loginFormValues.password;
33
34        this.http.post<any>('https://bexstream.beyond-vision.pt/api/v1/auth/user', this.user)
35          .subscribe((result) => {
36            if (result.user) {
37                alert(`${result.user.username} has been successfully logged in!`)
38            }
39        });
40    }
41
42}

Finally, to test that you’ve complete the PART I, try to login with:

user: drone-pilot-tutorial

pass: drone-pilot-tutorial

If everything was done correctly, you should have an alert pop-up with the login result.

../../_images/login.webp