========================= Part IV - CRUD ========================= In this part we will learn how to create, update and delete a user. 1 - User Setup ==================== Firstly we will create the UserList component: ``ng generate component user/component/user-list`` Add this new component to app-routing.module.ts: .. highlight:: ts .. code-block:: :linenos: :caption: app-routing.module.ts :emphasize-lines: 5,10 import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { LoginComponent } from './login/login.component'; import { DroneListComponent } from './drone/components/drone-list/drone-list.component'; import { UserListComponent } from './user/component/user-list/user-list.component'; const routes: Routes = [ { path: '', component: LoginComponent }, { path: 'drones', component: DroneListComponent }, { path: 'users', component: UserListComponent }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } | Secondly we will create the User service: ``ng generate service user/services/user`` And thirdly we will add the models folder and the actual models: .. code-block:: :linenos: :caption: organization.ts export class Organization { id?: string; name = ''; description = ''; } | This model represents the entity that is responsible for the users like: Beyond-vision, Enterprise-X and so on. .. code-block:: :linenos: :caption: role.ts import { Organization } from "./organization"; export class Role { id: string; name: string; organization: Organization; constructor() { this.id = ''; this.name = ''; this.organization = new Organization(); } } | This model is used to the access control on features of our application, for instance the role drone-pilot is allowed to list drones but is forbidden from deleting them, only the organization admin role is able to delete them. Final model, user.ts: .. code-block:: :linenos: :caption: user.ts import { Organization } from "./organization"; import { Role } from "./role"; export class User { id: string; username: string; email: string; profileImage: string; password: string; hash: string; description: string; createdDate: Date; token: string; roles: Role[]; organization: Organization; constructor() { this.id = ''; this.username = ''; this.email = ''; this.profileImage = ''; this.password = ''; this.hash = ''; this.description = ''; this.createdDate = new Date(); this.token = ''; this.roles = []; this.organization = new Organization(); } } | | 2 - Features Implementation ============================ 1 - User services ----------------- Next we will add the services to list, create, edit and delete users: .. code-block:: :linenos: :caption: user.service.ts import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { PaginatorDto } from 'src/app/lib/models/paginator.dto'; import { User } from '../models/user'; @Injectable({ providedIn: 'root' }) export class UserService { backendUserUrl = 'https://bexstream-preprod.beyond-vision.com/api/v1/user'; constructor(private http: HttpClient) { } public getAllUsers(paginator: PaginatorDto): Observable { const params = new HttpParams() .set('filter', paginator.filter) .set('limit', paginator.limit.toString()) .set('offset', paginator.offset.toString()) .set('sort', paginator.sort) .set('order', paginator.order); return this.http.get(this.backendUserUrl, {params}); } public register(user: User): Observable { return this.http.put(this.backendUserUrl, user); } public update(user: User): Observable { return this.http.post(`${this.backendUserUrl}/${user.id}`, user); } public delete(user: User): Observable { return this.http.delete(`${this.backendUserUrl}/${user.id}`); } } | | 2 - List users ----------------- .. code-block:: :linenos: :caption: user-list.component.ts import { Component, OnInit } from '@angular/core'; import { PaginatorDto } from 'src/app/lib/models/paginator.dto'; import { UserService } from '../../services/user.service'; import { FormBuilder } from '@angular/forms'; import { User } from '../../models/user'; @Component({ selector: 'app-user-list', templateUrl: './user-list.component.html', styleUrls: ['./user-list.component.less'] }) export class UserListComponent implements OnInit { users: User[] = []; paginator: PaginatorDto = new PaginatorDto(); constructor(private formBuilder: FormBuilder, private userService: UserService) { } ngOnInit(): void { this.paginator.limit = 0; this.listUsers(); } private listUsers() { this.userService .getAllUsers(this.paginator) .subscribe((users) => { this.users = users; }) } } | | On user-list.component.html let’s add a table with the list of users: .. code-block:: html+ng2 :linenos: :caption: user-list.component.html

Users List

Name Description Role Actions
{{ user.username }} {{ user.description }} {{ user.roles[0].name }}
| | 3 - Edit users ----------------- To edit a user we will firstly select the user using the “edit” button on the actions column. Then we will fill a form with the existing user data and allow for its edition. Finally the user will be able to submit the changed data. On user-list.component.ts add: .. code-block:: :linenos: :caption: user-list.component.ts :emphasize-lines: 46-67 import { Component, OnInit } from '@angular/core'; import { PaginatorDto } from 'src/app/lib/models/paginator.dto'; import { UserService } from '../../services/user.service'; import { FormBuilder } from '@angular/forms'; import { Role } from '../../models/role'; import { User } from '../../models/user'; import { RoleService } from '../../services/role.service'; @Component({ selector: 'app-user-list', templateUrl: './user-list.component.html', styleUrls: ['./user-list.component.less'] }) export class UserListComponent implements OnInit { users: User[] = []; paginator: PaginatorDto = new PaginatorDto(); updateUserForm = this.formBuilder.group({ username: '', description: '', password: '' }); editingUser: User = null; constructor(private formBuilder: FormBuilder, private userService: UserService) { } ngOnInit(): void { this.paginator.limit = 0; this.listUsers(); } private listUsers() { this.userService .getAllUsers(this.paginator) .subscribe((users) => { this.users = users; }); } editUser(user: User) { this.editingUser = user; this.updateUserForm.patchValue({ username: user.username, description: user.description, }); } updateUser() { const updateUserFormValues = this.updateUserForm.value; this.editingUser.username = updateUserFormValues.username; this.editingUser.description = updateUserFormValues.description; this.editingUser.password = updateUserFormValues.password; this.userService .update(this.editingUser) .subscribe((user) => { alert(`${user.username} has benn successfully updated!`); this.listUsers(); }); } } | | On user-list.component.ts add the user edition form: .. code-block:: html+ng2 :linenos: :caption: user-list.component.html :emphasize-lines: 22-

Users List

Name Description Role Actions
{{ user.username }} {{ user.description }} {{ user.roles[0].name }}


Edit User

| | 4 - Delete users ----------------- On user-list.component.ts add the following: .. code-block:: :linenos: :caption: user-list.component.ts :emphasize-lines: 69-75 import { Component, OnInit } from '@angular/core'; import { PaginatorDto } from 'src/app/lib/models/paginator.dto'; import { UserService } from '../../services/user.service'; import { FormBuilder } from '@angular/forms'; import { Role } from '../../models/role'; import { User } from '../../models/user'; @Component({ selector: 'app-user-list', templateUrl: './user-list.component.html', styleUrls: ['./user-list.component.less'] }) export class UserListComponent implements OnInit { users: User[] = []; paginator: PaginatorDto = new PaginatorDto(); updateUserForm = this.formBuilder.group({ username: '', description: '', password: '' }); editingUser: User = null; constructor(private formBuilder: FormBuilder, private userService: UserService) { } ngOnInit(): void { this.paginator.limit = 0; this.listUsers(); } private listUsers() { this.userService .getAllUsers(this.paginator) .subscribe((users) => { this.users = users; }); } editUser(user: User) { this.editingUser = user; this.updateUserForm.patchValue({ username: user.username, description: user.description, }); } updateUser() { const updateUserFormValues = this.updateUserForm.value; this.editingUser.username = updateUserFormValues.username; this.editingUser.description = updateUserFormValues.description; this.editingUser.password = updateUserFormValues.password; this.userService .update(this.editingUser) .subscribe((user) => { alert(`${user.username} has benn successfully updated!`); this.listUsers(); }); } deleteUser(user: User) { this.userService .delete(user) .subscribe(result => { alert(`${user.username} has benn successfully deleted!`); }); } } | | 5 – Creating a new user ----------------------- To create a new user we need to add new functionality, because when we create a user it has to have a role. This relationship is mandatory só we need to get a role from the backend first and then use it on the new user that we want to create. To achieve this we need to generate a Role service to get the roles and then just use one of the many, for simplicity sake. ``ng generate service user/services/role`` And add the following code: .. code-block:: :linenos: :caption: role.service.ts import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { Role } from '../models/role'; @Injectable({ providedIn: 'root' }) export class RoleService { backendUrl = 'https://bexstream-preprod.beyond-vision.com/api/v1'; getAllUrl = this.backendUrl + '/role/all/filtered'; constructor(private http: HttpClient) { } public getAll(): Observable { const params = new HttpParams() .set('filter', '') .set('limit', '0') .set('offset', '') .set('sort', '') .set('order', ''); return this.http.get(this.getAllUrl, {params}); } } | | Now let’s use it on the user-list.component.ts: .. code-block:: :linenos: :caption: user-list.component.ts :emphasize-lines: 7, 17, 26-31, 38, 43, 56-62, 95-112 import { Component, OnInit } from '@angular/core'; import { PaginatorDto } from 'src/app/lib/models/paginator.dto'; import { UserService } from '../../services/user.service'; import { FormBuilder } from '@angular/forms'; import { Role } from '../../models/role'; import { User } from '../../models/user'; import { RoleService } from '../../services/role.service'; @Component({ selector: 'app-user-list', templateUrl: './user-list.component.html', styleUrls: ['./user-list.component.less'] }) export class UserListComponent implements OnInit { users: User[] = []; roles: Role[] = []; paginator: PaginatorDto = new PaginatorDto(); updateUserForm = this.formBuilder.group({ username: '', description: '', password: '' }); createUserForm = this.formBuilder.group({ username: '', description: '', password: '', email: '' }); editingUser: User = null; constructor(private formBuilder: FormBuilder, private userService: UserService, private roleService: RoleService) { } ngOnInit(): void { this.paginator.limit = 0; this.listUsers(); this.getAllRoles(); } private listUsers() { this.userService .getAllUsers(this.paginator) .subscribe((users) => { this.users = users; }); } private getAllRoles() { this.roleService .getAll() .subscribe((roles) => { this.roles = roles; }); } editUser(user: User) { this.editingUser = user; this.updateUserForm.patchValue({ username: user.username, description: user.description, }); } updateUser() { const updateUserFormValues = this.updateUserForm.value; this.editingUser.username = updateUserFormValues.username; this.editingUser.description = updateUserFormValues.description; this.editingUser.password = updateUserFormValues.password; this.userService .update(this.editingUser) .subscribe((user) => { alert(`${user.username} has benn successfully updated!`); this.listUsers(); }); } deleteUser(user: User) { this.userService .delete(user) .subscribe(result => { alert(`${user.username} has benn successfully deleted!`); }); } createUser() { const createUserFormValues = this.createUserForm.value; const newUser = new User(); newUser.username = createUserFormValues.username; newUser.description = createUserFormValues.description; newUser.hash = createUserFormValues.password; newUser.email = createUserFormValues.email; newUser.roles = [this.roles[0]]; this.userService .register(newUser) .subscribe((user) => { this.listUsers(); }); } } | | Add the user creation form to user-list.component.ts: .. code-block:: html+ng2 :linenos: :caption: user-list.component.html :emphasize-lines: 51-

Users List

Name Description Role Actions
{{ user.username }} {{ user.description }} {{ user.roles[0].name }}


Edit User



Create User

Now go to http://localhost:4200, log in and then go to http://localhost:4200/users and edit or create new users. Congratulations,you've finished the first beXStream tutorial. Now you are capable of modifying users, and listing the drones inside the organization. Explore more APIs at https://docs.beyond-vision.com/bexstream/APIs.html .. image:: ../../_static/images/bexstream/tutorial/crud-users.webp :align: center