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:
1import { NgModule } from '@angular/core';
2import { Routes, RouterModule } from '@angular/router';
3import { LoginComponent } from './login/login.component';
4import { DroneListComponent } from './drone/components/drone-list/drone-list.component';
5import { UserListComponent } from './user/component/user-list/user-list.component';
6
7const routes: Routes = [
8 { path: '', component: LoginComponent },
9 { path: 'drones', component: DroneListComponent },
10 { path: 'users', component: UserListComponent },
11];
12
13@NgModule({
14 imports: [RouterModule.forRoot(routes)],
15 exports: [RouterModule]
16})
17export 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:
1export class Organization {
2 id?: string;
3 name = '';
4 description = '';
5}
This model represents the entity that is responsible for the users like: Beyond-vision, Enterprise-X and so on.
1import { Organization } from "./organization";
2
3export class Role {
4 id: string;
5 name: string;
6 organization: Organization;
7 constructor() {
8 this.id = '';
9 this.name = '';
10 this.organization = new Organization();
11 }
12}
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:
1import { Organization } from "./organization";
2import { Role } from "./role";
3
4export class User {
5 id: string;
6 username: string;
7 email: string;
8 profileImage: string;
9 password: string;
10 hash: string;
11 description: string;
12 createdDate: Date;
13 token: string;
14 roles: Role[];
15 organization: Organization;
16
17 constructor() {
18 this.id = '';
19 this.username = '';
20 this.email = '';
21 this.profileImage = '';
22 this.password = '';
23 this.hash = '';
24 this.description = '';
25 this.createdDate = new Date();
26 this.token = '';
27 this.roles = [];
28 this.organization = new Organization();
29 }
30}
2 - Features Implementation¶
1 - User services¶
Next we will add the services to list, create, edit and delete users:
1import { HttpClient, HttpParams } from '@angular/common/http';
2import { Injectable } from '@angular/core';
3import { Observable } from 'rxjs';
4import { PaginatorDto } from 'src/app/lib/models/paginator.dto';
5import { User } from '../models/user';
6
7@Injectable({
8providedIn: 'root'
9})
10export class UserService {
11
12 backendUserUrl = 'https://bexstream-preprod.beyond-vision.com/api/v1/user';
13
14 constructor(private http: HttpClient) { }
15
16 public getAllUsers(paginator: PaginatorDto): Observable<User[]> {
17 const params = new HttpParams()
18 .set('filter', paginator.filter)
19 .set('limit', paginator.limit.toString())
20 .set('offset', paginator.offset.toString())
21 .set('sort', paginator.sort)
22 .set('order', paginator.order);
23
24 return this.http.get<User[]>(this.backendUserUrl, {params});
25 }
26
27 public register(user: User): Observable<User> {
28 return this.http.put<User>(this.backendUserUrl, user);
29 }
30
31 public update(user: User): Observable<User> {
32 return this.http.post<User>(`${this.backendUserUrl}/${user.id}`, user);
33 }
34
35 public delete(user: User): Observable<User> {
36 return this.http.delete<User>(`${this.backendUserUrl}/${user.id}`);
37 }
38}
2 - List users¶
1import { Component, OnInit } from '@angular/core';
2import { PaginatorDto } from 'src/app/lib/models/paginator.dto';
3import { UserService } from '../../services/user.service';
4import { FormBuilder } from '@angular/forms';
5import { User } from '../../models/user';
6
7
8@Component({
9 selector: 'app-user-list',
10 templateUrl: './user-list.component.html',
11 styleUrls: ['./user-list.component.less']
12})
13export class UserListComponent implements OnInit {
14
15 users: User[] = [];
16
17 paginator: PaginatorDto = new PaginatorDto();
18
19 constructor(private formBuilder: FormBuilder,
20 private userService: UserService) { }
21
22 ngOnInit(): void {
23 this.paginator.limit = 0;
24 this.listUsers();
25 }
26
27 private listUsers() {
28 this.userService
29 .getAllUsers(this.paginator)
30 .subscribe((users) => {
31 this.users = users;
32 })
33 }
34}
On user-list.component.html let’s add a table with the list of users:
1<h3>Users List</h3>
2<table border="1">
3 <thead>
4 <th>Name</th>
5 <th>Description</th>
6 <th>Role</th>
7 <th>Actions</th>
8 </thead>
9 <tbody>
10 <tr *ngFor="let user of users">
11 <td>{{ user.username }}</td>
12 <td>{{ user.description }}</td>
13 <td>{{ user.roles[0].name }}</td>
14 <td>
15 <button (click)="editUser(user)">Edit</button>
16 <button (click)="deleteUser(user)">Delete</button>
17 </td>
18 </tr>
19 </tbody>
20</table>
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:
1import { Component, OnInit } from '@angular/core';
2import { PaginatorDto } from 'src/app/lib/models/paginator.dto';
3import { UserService } from '../../services/user.service';
4import { FormBuilder } from '@angular/forms';
5import { Role } from '../../models/role';
6import { User } from '../../models/user';
7import { RoleService } from '../../services/role.service';
8
9@Component({
10 selector: 'app-user-list',
11 templateUrl: './user-list.component.html',
12 styleUrls: ['./user-list.component.less']
13})
14export class UserListComponent implements OnInit {
15
16 users: User[] = [];
17
18 paginator: PaginatorDto = new PaginatorDto();
19
20 updateUserForm = this.formBuilder.group({
21 username: '',
22 description: '',
23 password: ''
24 });
25
26
27 editingUser: User = null;
28
29 constructor(private formBuilder: FormBuilder,
30 private userService: UserService) { }
31
32 ngOnInit(): void {
33 this.paginator.limit = 0;
34 this.listUsers();
35 }
36
37
38 private listUsers() {
39 this.userService
40 .getAllUsers(this.paginator)
41 .subscribe((users) => {
42 this.users = users;
43 });
44 }
45
46 editUser(user: User) {
47 this.editingUser = user;
48
49 this.updateUserForm.patchValue({
50 username: user.username,
51 description: user.description,
52 });
53 }
54
55 updateUser() {
56 const updateUserFormValues = this.updateUserForm.value;
57 this.editingUser.username = updateUserFormValues.username;
58 this.editingUser.description = updateUserFormValues.description;
59 this.editingUser.password = updateUserFormValues.password;
60
61 this.userService
62 .update(this.editingUser)
63 .subscribe((user) => {
64 alert(`${user.username} has benn successfully updated!`);
65 this.listUsers();
66 });
67 }
68}
On user-list.component.ts add the user edition form:
1<h3>Users List</h3>
2<table border="1">
3 <thead>
4 <th>Name</th>
5 <th>Description</th>
6 <th>Role</th>
7 <th>Actions</th>
8 </thead>
9<tbody>
10 <tr *ngFor="let user of users">
11 <td>{{ user.username }}</td>
12 <td>{{ user.description }}</td>
13 <td>{{ user.roles[0].name }}</td>
14 <td>
15 <button (click)="editUser(user)">Edit</button>
16 <button (click)="deleteUser(user)">Delete</button>
17 </td>
18 </tr>
19</tbody>
20</table>
21
22<hr>
23<hr>
24
25<h3>Edit User</h3>
26<form [formGroup]="updateUserForm" (ngSubmit)="updateUser()">
27 <div>
28 <label for="username">
29 Username
30 </label>
31 <input id="username" type="text" formControlName="username">
32 </div>
33
34 <div>
35 <label for="description">
36 Description
37 </label>
38 <input id="description" type="text" formControlName="description">
39 </div>
40
41 <div>
42 <label for="password">
43 Password
44 </label>
45 <input id="password" type="password" formControlName="password">
46 </div>
47
48 <button class="button" type="submit">Update</button>
49
50</form>
4 - Delete users¶
On user-list.component.ts add the following:
1import { Component, OnInit } from '@angular/core';
2import { PaginatorDto } from 'src/app/lib/models/paginator.dto';
3import { UserService } from '../../services/user.service';
4import { FormBuilder } from '@angular/forms';
5import { Role } from '../../models/role';
6import { User } from '../../models/user';
7
8@Component({
9 selector: 'app-user-list',
10 templateUrl: './user-list.component.html',
11 styleUrls: ['./user-list.component.less']
12})
13export class UserListComponent implements OnInit {
14
15 users: User[] = [];
16
17 paginator: PaginatorDto = new PaginatorDto();
18
19 updateUserForm = this.formBuilder.group({
20 username: '',
21 description: '',
22 password: ''
23 });
24
25
26 editingUser: User = null;
27
28 constructor(private formBuilder: FormBuilder,
29 private userService: UserService) { }
30
31 ngOnInit(): void {
32 this.paginator.limit = 0;
33 this.listUsers();
34 }
35
36
37 private listUsers() {
38 this.userService
39 .getAllUsers(this.paginator)
40 .subscribe((users) => {
41
42 this.users = users;
43 });
44 }
45
46 editUser(user: User) {
47 this.editingUser = user;
48
49 this.updateUserForm.patchValue({
50 username: user.username,
51 description: user.description,
52 });
53 }
54
55 updateUser() {
56 const updateUserFormValues = this.updateUserForm.value;
57 this.editingUser.username = updateUserFormValues.username;
58 this.editingUser.description = updateUserFormValues.description;
59 this.editingUser.password = updateUserFormValues.password;
60
61 this.userService
62 .update(this.editingUser)
63 .subscribe((user) => {
64 alert(`${user.username} has benn successfully updated!`);
65 this.listUsers();
66 });
67 }
68
69 deleteUser(user: User) {
70 this.userService
71 .delete(user)
72 .subscribe(result => {
73 alert(`${user.username} has benn successfully deleted!`);
74 });
75 }
76}
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:
1import { HttpClient, HttpParams } from '@angular/common/http';
2import { Injectable } from '@angular/core';
3import { Observable } from 'rxjs';
4import { Role } from '../models/role';
5
6@Injectable({
7 providedIn: 'root'
8})
9export class RoleService {
10
11 backendUrl = 'https://bexstream-preprod.beyond-vision.com/api/v1';
12
13 getAllUrl = this.backendUrl + '/role/all/filtered';
14
15 constructor(private http: HttpClient) { }
16
17 public getAll(): Observable<Role[]> {
18 const params = new HttpParams()
19 .set('filter', '')
20 .set('limit', '0')
21 .set('offset', '')
22 .set('sort', '')
23 .set('order', '');
24
25 return this.http.get<Role[]>(this.getAllUrl, {params});
26 }
27}
Now let’s use it on the user-list.component.ts:
1import { Component, OnInit } from '@angular/core';
2import { PaginatorDto } from 'src/app/lib/models/paginator.dto';
3import { UserService } from '../../services/user.service';
4import { FormBuilder } from '@angular/forms';
5import { Role } from '../../models/role';
6import { User } from '../../models/user';
7import { RoleService } from '../../services/role.service';
8
9@Component({
10 selector: 'app-user-list',
11 templateUrl: './user-list.component.html',
12 styleUrls: ['./user-list.component.less']
13})
14export class UserListComponent implements OnInit {
15
16 users: User[] = [];
17 roles: Role[] = [];
18 paginator: PaginatorDto = new PaginatorDto();
19
20 updateUserForm = this.formBuilder.group({
21 username: '',
22 description: '',
23 password: ''
24 });
25
26 createUserForm = this.formBuilder.group({
27 username: '',
28 description: '',
29 password: '',
30 email: ''
31 });
32
33
34 editingUser: User = null;
35
36 constructor(private formBuilder: FormBuilder,
37 private userService: UserService,
38 private roleService: RoleService) { }
39
40 ngOnInit(): void {
41 this.paginator.limit = 0;
42 this.listUsers();
43 this.getAllRoles();
44 }
45
46
47 private listUsers() {
48 this.userService
49 .getAllUsers(this.paginator)
50 .subscribe((users) => {
51
52 this.users = users;
53 });
54 }
55
56 private getAllRoles() {
57 this.roleService
58 .getAll()
59 .subscribe((roles) => {
60 this.roles = roles;
61 });
62 }
63
64 editUser(user: User) {
65 this.editingUser = user;
66
67 this.updateUserForm.patchValue({
68 username: user.username,
69 description: user.description,
70 });
71 }
72
73 updateUser() {
74 const updateUserFormValues = this.updateUserForm.value;
75 this.editingUser.username = updateUserFormValues.username;
76 this.editingUser.description = updateUserFormValues.description;
77 this.editingUser.password = updateUserFormValues.password;
78
79 this.userService
80 .update(this.editingUser)
81 .subscribe((user) => {
82 alert(`${user.username} has benn successfully updated!`);
83 this.listUsers();
84 });
85 }
86
87 deleteUser(user: User) {
88 this.userService
89 .delete(user)
90 .subscribe(result => {
91 alert(`${user.username} has benn successfully deleted!`);
92 });
93 }
94
95 createUser() {
96 const createUserFormValues = this.createUserForm.value;
97
98 const newUser = new User();
99
100 newUser.username = createUserFormValues.username;
101 newUser.description = createUserFormValues.description;
102 newUser.hash = createUserFormValues.password;
103 newUser.email = createUserFormValues.email;
104 newUser.roles = [this.roles[0]];
105
106
107 this.userService
108 .register(newUser)
109 .subscribe((user) => {
110 this.listUsers();
111 });
112 }
113}
Add the user creation form to user-list.component.ts:
1<h3>Users List</h3>
2<table border="1">
3 <thead>
4 <th>Name</th>
5 <th>Description</th>
6 <th>Role</th>
7 <th>Actions</th>
8 </thead>
9<tbody>
10 <tr *ngFor="let user of users">
11 <td>{{ user.username }}</td>
12 <td>{{ user.description }}</td>
13 <td>{{ user.roles[0].name }}</td>
14 <td>
15 <button (click)="editUser(user)">Edit</button>
16 <button (click)="deleteUser(user)">Delete</button>
17 </td>
18 </tr>
19</tbody>
20</table>
21
22<hr>
23<hr>
24
25<h3>Edit User</h3>
26<form [formGroup]="updateUserForm" (ngSubmit)="updateUser()">
27 <div>
28 <label for="username">
29 Username
30 </label>
31 <input id="username" type="text" formControlName="username">
32 </div>
33
34 <div>
35 <label for="description">
36 Description
37 </label>
38 <input id="description" type="text" formControlName="description">
39 </div>
40
41 <div>
42 <label for="password">
43 Password
44 </label>
45 <input id="password" type="password" formControlName="password">
46 </div>
47
48 <button class="button" type="submit">Update</button>
49
50</form>
51
52<hr>
53<hr>
54
55<h3>Create User</h3>
56<form [formGroup]="createUserForm" (ngSubmit)="createUser()">
57
58 <div>
59 <label for="username">
60 Username
61 </label>
62 <input id="username" type="text" formControlName="username">
63 </div>
64
65 <div>
66 <label for="description">
67 Description
68 </label>
69 <input id="description" type="text" formControlName="description">
70 </div>
71
72 <div>
73 <label for="email">
74 E-mail
75 </label>
76 <input id="e-mail" type="text" formControlName="email">
77 </div>
78
79 <div>
80 <label for="password">
81 Password
82 </label>
83 <input id="password" type="password" formControlName="password">
84 </div>
85
86 <button class="button" type="submit">Create</button>
87
88</form>
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