=========================
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
--------------------------
.. highlight:: ts
Add to the *login.component.ts* file the following code:
.. code-block::
:linenos:
:caption: login.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit {
user = { username: '', password: '' }; // see body on OpenAPI definition for POST /api/v1/auth/user
loginForm = this.formBuilder.group({
username: '',
password: ''
});
constructor(private formBuilder: FormBuilder) { }
ngOnInit(): void {
this.user = { username: '', password: '' };
}
/**
* User authentication method
*/
public authenticate(): void {
}
}
Since we will be using ReactiveForms we need to add this module to our app module, located in *app.module.ts*.
.. code-block::
:linenos:
:caption: app.module.ts
:emphasize-lines: 3, 17
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
@NgModule({
declarations: [
AppComponent,
LoginComponent
],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
],
providers: [],
bootstrap: [AppComponent]
})
export 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:
.. code-block:: html+ng2
:linenos:
:caption: login.component.html
Login Form
3 – Adding the component to the app
-----------------------------------
First, clear *app.component.html* file and add the following line:
.. code-block:: html
:linenos:
:caption: app.component.html
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:
.. code-block:: TS
:linenos:
:caption: app-routing.module.ts
:emphasize-lines: 3, 6
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login/login.component';
const routes: Routes = [
{ path: '', component: LoginComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export 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*:
.. code-block::
:linenos:
:caption: app.module.ts
:emphasize-lines: 4, 18, 19
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
@NgModule({
declarations: [
AppComponent,
LoginComponent
],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Restart your angular app.
Afterwards, we will add the communication code to the authenticate method on *login.component.ts*:
.. code-block::
:linenos:
:caption: login.component.ts
:emphasize-lines: 3, 30-48
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { User } from './models/user';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit {
user = { username: '', password: '' }; // see body on OpenAPI definition for POST /api/v1/auth/user
loginForm = this.formBuilder.group({
username: '',
password: ''
});
constructor(private formBuilder: FormBuilder,
private http: HttpClient) { }
ngOnInit(): void {
this.user = { username: '', password: '' };
}
/**
* User authentication method
*/
public authenticate(): void {
const loginFormValues = this.loginForm.value
this.user.username = loginFormValues.username;
this.user.password = loginFormValues.password;
this.http.post('https://bexstream-preprod.beyond-vision.com/api/v1/auth/user', this.user)
.subscribe({
next: (result) => {
if (result.token) {
alert(`${this.user.username} has been successfully logged in!`);
} else {
alert(`Unexpected response from the server for /api/v1/auth/user. Check the network request/response for details!`);
}
},
error: (err) => {
alert(`Error on login. Please check the username and the password!.`);
}
});
}
}
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.
.. image:: ../../_static/images/bexstream/tutorial/login.webp
:align: center