Getting Started | Building an Application with Angular
Angular 10 Front-end
In this tutorial We are going build an application Movies to display the movies we will use the query find by title, find by year, find by director and find by actor. we use mongodb database to develope this project. Front-end side is made with Angular 10, HTTPClient & Router.
Angular CLI version (10.1.1)
ng new
The Angular CLI makes it easy to create an application that already works, right out of the box. It already follows our best practices!
ng generate
Generate components, routes, services and pipes with a simple command. The CLI will also create simple test shells for all of these.
ng serve
Easily test your app locally while developing.
$ npm install -g @angular/cli
$ ng new gym-frontend
$ cd gym-frontend
$ ng serve
Technology
Angular 10
Angular HTTPClient
Angular Router
Project Structure
Angular Material Tutorial
The idea of this is article is to teach you how to use Angular Material through a hands-on exercise. First, you will check the dependencies that you need on your computer to use and develop with Angular Material, then you will learn how to configure and use different components.
Install Angular Material
Angular Material In addition to the install schematic, Angular Material comes with several schematics (like nav, table, address-form, etc.) that can be used to easily generate pre-built components in your application.
$ ng add @angular/material
MaterialModule
In earlier versions of Angular Material, we could import MaterialModule which imports all components from Angular Material and makes them available in our app. Most of the time we will need to import the most of material.
src/app/material-module.ts
import { NgModule } from '@angular/core';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatBadgeModule } from '@angular/material/badge';
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips';
import { MatStepperModule } from '@angular/material/stepper';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatRadioModule } from '@angular/material/radio';
import { MatSelectModule } from '@angular/material/select';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatSliderModule } from '@angular/material/slider';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatTreeModule } from '@angular/material/tree';
@NgModule({
exports: [
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
],
imports: [
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
]
})
export class MaterialModule { }
Style.css
First of all, we need to create the various entry point CSS files of course. You can just create further scss files at the level where the styles.scss is in your project.
src/style.css
html, body {
height: 100%;
}
body {
margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif;
}
.form-content {
max-width: 400px;
margin: auto;
background-color: #3f51b5;
padding: 15px;
border-radius: 5px;
}
.button,
.mat-form-field {
width: 100%;
}
Modals interfaces
The purpose of this class is to map the specified fields with the fields of Spring entity class.
src/app/Modal.ts
export interface Gym {
id: number,
name: string,
address: string,
city: string,
area: number,
logo: string
}
export interface Payment {
id: number,
cost: number,
date: any,
duration: string
}
export interface Arbitrate {
id: number,
name: string
}
export interface Sport {
id: number,
name: string,
description: string,
photo: string,
arbitrates: Arbitrate[],
trains: Train[]
}
export interface SportsMan {
id: number,
firstName: string,
lastName: string,
age: number,
sex: string,
avatar: string,
}
export interface Worktime {
id: any,
day: string,
timetable: any,
start: any,
end: any
}
export interface Train {
id: number,
name: string
}
export interface User {
id: number;
username: string;
password: string;
admin: boolean;
}
Create Data services
This service will use Angular HTTPClient to send HTTP requests. You can see that its functions includes CRUD operations and finder method
- ArbitrateService
- GymService
- PaymentService
- SportService
- SportsManService
- TrainService
- WorktimeService
$ ng generate service arbitrate
$ ng generate service payment
$ ng generate service sport
$ ng generate service sportsMan
$ ng generate service train
$ ng generate service Worktime
src/app/service/arbitrate.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Arbitrate } from '../model/Model';
@Injectable({
providedIn: 'root'
})
export class ArbitrateService {
private url = 'http://localhost:8080/api';
constructor(private http: HttpClient) { }
addArbitrateForGym(arbitrate: Arbitrate, idGym: number): Observable<Arbitrate> {
return this.http.post<any>(`${this.url}/addArbitrateForGym/${idGym}`, arbitrate);
}
addArbitrateForSport(arbitrate: Arbitrate, id: number): Observable<Arbitrate> {
return this.http.post<Arbitrate>(`${this.url}/addArbitrateForSport/${idArbitrate}/${idSport}`, null);
}
editArbitrate(arbitrate: Arbitrate, id: number): Observable<Arbitrate> {
return this.http.put<Arbitrate>(`${this.url}/editArbitrate/${id}`, arbitrate);
findArbitrateById(id: number): Observable<Arbitrate> {
return this.http.get<Arbitrate>(`${this.url}/findArbitrateById/${id}`);
}
deleteArbitrate(id: number): Observable<Arbitrate> {
return this.http.delete<Arbitrate>(`${this.url}/deleteArbitrate/${id}`);
}
findAllArbitrates(): Observable<Arbitrate[]> {
return this.http.get<Arbitrate[]>(`${this.url}/findAllArbitrates`);
}
findArbitratesForGym(idGym: number): Observable<Arbitrate[]> {
return this.http.get<Arbitrate[]>(`${this.url}/findArbitratesForGym/${idGym}`);
}
findArbitratesForSport(idSport: number): Observable<Arbitrate[]> {
return this.http.get<Arbitrate[]>(`${this.url}/findArbitratesForSport/${idSport}`);
}
}
src/app/service/gym.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Gym } from '../model/Model';
@Injectable({
providedIn: 'root'
})
export class GymService {
private url = 'http://localhost:8080/api';
constructor(private http: HttpClient) { }
addGym(gym: Gym): Observable<Gym> {
return this.http.post<Gym>(`${this.url}/addGym`, gym);
}
editGym(gym: Gym, id: number): Observable<Gym> {
return this.http.put<Gym>(`${this.url}/editGym/${id}`, gym);
}
findGymById(id: number): Observable<Gym> {
return this.http.get<Gym>(`${this.url}/findGymById/${id}`);
}
deleteGym(id: number): Observable<Gym> {
return this.http.delete<Gym>(`${this.url}/deleteGym/${id}`);
}
findAllGyms(): Observable<Gym[]> {
return this.http.get<Gym[]>(`${this.url}/findAllGyms`);
}
}
src/app/service/payment.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Payment } from '../model/Model';
@Injectable({
providedIn: 'root'
})
export class PaymentService {
private url = 'http://localhost:8080/api';
constructor(private http: HttpClient) { }
addPayment(payment: Payment, id: number): Observable<Payment> {
return this.http.post<Payment>(`${this.url}/addPayment/${id}`, payment);
}
editPayment(payment: Payment, id: number): Observable<Payment> {
return this.http.put<Payment>(`${this.url}/editPayment/${id}`, payment);
}
findPaymentById(id: number): Observable<Payment> {
return this.http.get<Payment>(`${this.url}/findPaymentById/${id}`);
}
deletePayment(id: number): Observable<Payment> {
return this.http.delete<Payment>(`${this.url}/deletePayment/${id}`);
}
findPaymentForSportsMan(id: number): Observable<Payment[]> {
return this.http.get<Payment[]>(`${this.url}/findPaymentForSportsMan/`${id});
}
}
We will use the sessionStorage are part of web API which are used to store ‘KEY’ — ‘VALUE’ pairs in Angular.
src/app/service/storage.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
const USERNAME_KEY = 'AuthUsername';
@Injectable({
providedIn: 'root'
})
export class StorageService {
private url = 'http://localhost:8080/api';
constructor(private http: HttpClient) { }
addUser(user: any): Observable<any> {
return this.http.post<any>(`${this.url}/addUser`, user);
}
editUser(user: any, id: number): Observable<any> {
return this.http.put<any>(`${this.url}/editUser/${id}`, user);
}
findUserById(id: number): Observable<any> {
return this.http.get<any>(`${this.url}/findUserById/${id}`);
}
findUserByUsername(username: string): Observable<any> {
return this.http.get<any>(`${this.url}/findUserByUsername/${username}`);
}
deleteUser(id: number): Observable<any> {
return this.http.delete<any>(`${this.url}/deleteUser/${id}`);
}
public saveUsername(username: string) {
window.sessionStorage.removeItem(USERNAME_KEY);
window.sessionStorage.setItem(USERNAME_KEY, username);
}
public getUsername(): string {
return sessionStorage.getItem(USERNAME_KEY);
}
public signOut() {
window.sessionStorage.clear();
}
}
src/app/service/sport.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Sport } from '../model/Model';
@Injectable({
providedIn: 'root'
})
export class SportService {
private url = 'http://localhost:8080/api';
constructor(private http: HttpClient) { }
addSportForSportsMan(idSport: number, idSportsMan: number): Observable<Sport> {
return this.http.post<Sport>(`${this.url}/addSportForSportsMan/${idSport}/${idSportsMan}`, null);
}
addSportForGym(sport: Sport, idGym: number): Observable<Sport> {
return this.http.post<Sport>(`${this.url}/addSportForGym/${idGym}`, sport);
}
editSport(sport: Sport, id: number): Observable<Sport> {
return this.http.put<Sport>(`${this.url}/editSport/${id}`, sport);
}
findSportById(id: number): Observable<Sport> {
return this.http.get<Sport>(`${this.url}/findSportById/${id}`);
}
deletePayment(id: number): Observable<Sport> {
return this.http.delete<Sport>(`${this.url}/deletePayment/${id}`);
}
deleteSportFromGym(id: number, idGym: number): Observable<Sport> {
return this.http.delete<Sport>(`${this.url}/deleteSportFromGym/${id}/${idGym}`);
}
findSportsForGym(idGym: number): Observable<Sport[]> {
return this.http.get<Sport[]>(`${this.url}/findSportsForGym/${idGym}`);
}
findSportsForSportsMan(id: number): Observable<Sport[]> {
return this.http.get<Sport[]>(`${this.url}/findSportsForSportsMan)/${id}`;
}
}
src/app/service/sportsMan.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { SportsMan } from '../model/Model';
@Injectable({
providedIn: 'root'
})
export class SportsManService {
private url = 'http://localhost:8080/api';
constructor(private http: HttpClient) { }
addSportsMan(sportsMan: SportsMan, id: number): Observable<SportsMan> {
return this.http.post<SportsMan>(`${this.url}/addSportsMan/${id}`, sportsMan);
}
editSportsMan(sportsMan: SportsMan, id: number): Observable<SportsMan> {
return this.http.put<SportsMan>(`${this.url}/editSportsMan/${id}`, sportsMan);
}
findSportsManById(id: number): Observable<SportsMan> {
return this.http.get<SportsMan>(`${this.url}/findSportsManById/${id}`);
}
deleteSportsMan(id: number): Observable<SportsMan> {
return this.http.delete<SportsMan>(`${this.url}/deleteSportsMan/${id}`);
}
findAllSportsMans(): Observable<SportsMan[]> {
return this.http.get<SportsMan[]>(`${this.url}/findAllSportsMans`);
}
}
src/app/service/train.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Train } from '../model/Model';
@Injectable({
providedIn: 'root'
})
export class TrainService {
private url = 'http://localhost:8080/api';
constructor(private http: HttpClient) { }
addTrainForGym(train: Train, idGym: number): Observable<Train> {
return this.http.post<Train>(`${this.url}/addTrainForGym/${idGym}`, train);
}
addTrainForSport(idTrain: number, idSport: number): Observable<Train> {
return this.http.post<Train>(`${this.url}/addTrainForSport/${idTrain}/${idSport}`, null);
}
editTrain(train: Train, id: number): Observable<Train> {
return this.http.put<Train>(`${this.url}/editTrain/${id}`, train);
}
findTrainById(id: number): Observable<Train> {
return this.http.get<Train>(`${this.url}/findTrainById/${id}`);
}
deleteTrain(id: number): Observable<Train> {
return this.http.delete<Train>(`${this.url}/deleteTrain/${id}`);
}
findAllTrains(): Observable<Train[]> {
return this.http.get<Train[]>(`${this.url}/findAllTrains`);
}
findTrainsForGym(idGym: number): Observable<Train[]> {
return this.http.get<Train[]>(`${this.url}/findTrainsForGym/${idGym}`);
}
findTrainsForSport(idSport: number): Observable<Train[]> {
return this.http.get<Train[]>(`${this.url}/findTrainsForSport/${idSport}`);
}
}
src/app/service/worktime.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Worktime } from '../model/Model';
@Injectable({
providedIn: 'root'
})
export class WorktimeService {
private url = 'http://localhost:8080/api';
constructor(private http: HttpClient) { }
addWorktimeForGym(worktime: Worktime, id: number): Observable<Worktime> {
return this.http.post<Worktime>(`${this.url}/addWorktimeForGym/${id}`, worktime);
}
addSportsManForWork(idSportsMan: number, idSport: number): Observable<Worktime> {
return this.http.post<Worktime>(`${this.url}/addSportsManForWork/${idSportsMan}/${idSport}`, null);
}
editWorktime(worktime: Worktime, id: number, idGym: number): Observable<Worktime> {
return this.http.put<Worktime>(`${this.url}/editWorktime/${id}/${idGym}`, worktime);
}
findWorktimeById(id: number): Observable<Worktime> {
return this.http.get<Worktime>(`${this.url}/findWorktimeById/${id}`);
}
deleteWorktime(id: number): Observable<Worktime> {
return this.http.delete<Worktime>(`${this.url}/deleteWorktime/${id}`);
}
findWorktimesForGym(idGym: number): Observable<Worktime[]> {
return this.http.get<Worktime[]>(`${this.url}/findWorktimesForGym/${idGym}`);
}
findSportsManForWorktime(id: number): Observable<Worktime[]> {
return this.http.get<Worktime[]>(`${this.url}/findSportsManForWorktime/${id}`);
}
}
Login form
In this form we need to login user because we want know the difference between Admin and User that is not really authentication but this is a storage data.
src/app/login/app-login-component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { User } from '../model/Model';
import { StorageService } from '../service/storage.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
user: User = {} as User;
constructor(private router: Router, private storageService: StorageService) {}
ngOnInit(): void { }
login() {
this.storageService.findUserByUsername(this.user.username).subscribe(user => {
if(user==null) {
if(this.user.username=='admin' && this.user.password == 'admin') {
if(this.user!==null) {
this.user.admin = true;
this.storageService.addUser(this.user).subscribe(addUser => {
this.user = addUser;
this.router.navigate(['/admin-dashboard/', this.user.username]);
this.storageService.saveUsername(this.user.username);
});
}
} else {
if(this.user!=null) {
this.user.admin = false;
this.storageService.addUser(this.user).subscribe(addUser => {
this.user = addUser;
this.storageService.saveUsername(this.user.username);
this.router.navigate(['/home/', this.user.username]);
});
}
}
} else {
this.storageService.findUserByUsername(this.user.username).subscribe((user) => {
if(this.user.username=='admin' && this.user.password == 'admin') {
if(this.user!=null) {
this.user.admin = true;
this.storageService.editUser(this.user, user.id).subscribe(addUser => {
this.user = addUser;
this.router.navigate(['/admin-dashboard/', this.user.username]);
this.storageService.saveUsername(this.user.username);
});
}
} else {
if(this.user!=null) {
this.user.admin = false;
this.storageService.editUser(this.user, user.id).subscribe(addUser => {
this.user = addUser;
this.storageService.saveUsername(this.user.username);
this.router.navigate(['/home/', this.user.username]);
});
}
}
});
}
});
}
}
src/app/login.component.html
<div class="content">
<mat-card>
<mat-card-header>
<div mat-card-avatar class="header-image"></div>
<mat-card-title>Please Login</mat-card-title>
</mat-card-header>
<mat-card-content>
<div><br>
<mat-form-field appearance="fill">
<mat-label>Username</mat-label>
<input matInput [(ngModel)]="user.username" name="username">
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Password</mat-label>
<input matInput [(ngModel)]="user.password" type="password" name="password">
</mat-form-field>
</div>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="accent" (click)="login()">Enter</button>
</mat-card-actions><br>
</mat-card>
</div>
src/app/login.css
.header-image {
background-image: url('https://designgyan.com/srp457/assets3/icons/loginLogo.png');
background-size: cover;
}
.content {
max-width: 400px;
margin: auto;
margin-top: 50px;
}
button,
mat-form-field {
width: 100%;
}
Admin Dashboard
We need admin dashboard to create a new gym and a new sportsman
src/app/admin-dashboard.component.ts
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Gym, User, SportsMan, Train } from '../model/Model';
import { StorageService} from '../service/storage.service';
import { GymService } from './../service/gym.service';
import { SportsManService} from './../service/sports-man.service';
@Component({
selector: 'app-admin-dashboard',
templateUrl: './admin-dashboard.component.html',
styleUrls: ['./admin-dashboard.component.css'],
encapsulation: ViewEncapsulation.None
})
export class AdminDashboardComponent implements OnInit {
gym: Gym = {} as Gym;
user: User = {} as User;
sportsMan: SportsMan = {} as SportsMan;
train: Train = {} as Train;
showProgressBar = false;
username: string;
gender: any = {};
constructor(private router: Router, private gymService: GymService,
private route: ActivatedRoute, private storageService: StorageService,
private sportsManService: SportsManService) { }
ngOnInit(): void {
this.username = this.route.snapshot.params.username;
this.storageService.findUserByUsername(this.username).subscribe(user => {
this.user = user;
});
}
setGender() {
this.sportsMan.sex = this.gender;
}
addSportsMan() {
this.showProgressBar = true;
this.sportsManService.addSportsMan(this.sportsMan, 1).subscribe(sportsMan => {
this.sportsMan = sportsMan;
window.location.reload();
});
}
addGym() {
this.showProgressBar = true;
this.gymService.addGym(this.gym).subscribe(gym => {
this.gym = gym;
window.location.reload();
})
}
home() {
window.location.replace(`/home/${this.username}`);
}
logout(id: number) {
this.storageService.signOut();
this.router.navigateByUrl('/login');
this.storageService.deleteUser(id).subscribe();
}
}
src/app/admin-dashboard.component.html
<mat-tab-group>
<mat-tab label="Add gym"> <br><br>
<div class="form-content">
<mat-card>
<mat-card-header>
<mat-card-title>Add gym information</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-progress-bar mode="indeterminate" *ngIf="showProgressBar"></mat-progress-bar>
<div> <br>
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter name</mat-label>
<input matInput type="text" [(ngModel)]="gym.name" name="name">
</mat-form-field><br>
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter Address</mat-label>
<input matInput type="text" [(ngModel)]="gym.address" name="address">
</mat-form-field>
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter city</mat-label>
<input matInput type="text" [(ngModel)]="gym.city" name="city">
</mat-form-field><br>
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter area</mat-label>
<input matInput type="number" [(ngModel)]="gym.area" name="area">
</mat-form-field><br>
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter logo</mat-label>
<input matInput type="text" [(ngModel)]="gym.logo" name="logo">
</mat-form-field>
</div>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary" (click)="addGym()" class="button">Save</button>
</mat-card-actions><br>
</mat-card>
</div>
</mat-tab>
<mat-tab label="Add sports man">
<br><br>
<div class="form-content">
<mat-card>
<mat-card-header>
<mat-card-title>Add sports man information</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-progress-bar mode="indeterminate" *ngIf="showProgressBar"></mat-progress-bar>
<div class="example-container">
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter firstName</mat-label>
<input matInput type="text" [(ngModel)]="sportsMan.firstName" name="firstName">
</mat-form-field><br>
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter lastName</mat-label>
<input matInput type="text" [(ngModel)]="sportsMan.lastName" name="lastName">
</mat-form-field>
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter age</mat-label>
<input matInput type="number" [(ngModel)]="sportsMan.age" name="age">
</mat-form-field><br>
<mat-form-field appearance="fill" class="mat-form-field">
<mat-label>Enter avatar</mat-label>
<input matInput type="text" [(ngModel)]="sportsMan.avatar" name="avatar">
</mat-form-field><br>
<mat-radio-group aria-label="Select an option" [(ngModel)]="gender" name="gender" (ngModelChange)="setGender()">
<mat-radio-button value="female">Female</mat-radio-button>
<mat-radio-button value="male" style="margin-left: 10px;">Male</mat-radio-button>
</mat-radio-group>
</div>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="warn" (click)="addSportsMan()" class="button">Save</button>
</mat-card-actions><br>
</mat-card>
</div>
</mat-tab>
</mat-tab-group>
<div class="footer">
<p>Welcome {{username}}</p>
<button mat-button color="warn" (click)="home()">Frontend</button>
<button mat-button color="accent" (click)="logout(user.id)">Logout</button>
</div>
src/app/admin-dashboard.component.css
.mat-tab-label {
min-width: 25px !important;
padding: 5px;
background-color: transparent;
color: red;
font-weight: 700;
}
/* Styles for the active tab label */
.mat-tab-label.mat-tab-label-active {
min-width: 25px !important;
padding: 5px;
background-color: transparent;
color: red;
font-weight: 700;
}
/* Styles for the ink bar */
.mat-ink-bar {
background-color: green;
}
.footer {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #ddd;
color: black;
text-align: center;
}
Home page
We are going to create a home page to display all gyms information for user access it
src/app/home-component.ts
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { User, Gym } from '../model/Model';
import { StorageService } from '../service/storage.service';
import { GymService } from '../service/gym.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
gyms: Gym[];
user: User = {} as User;
username: any;
constructor(private gymService: GymService, private router: Router,
private storageService: StorageService, private route: ActivatedRoute) {
this.route.params.subscribe(
params => {
this.username = this.storageService.getUsername();
this.storageService.findUserByUsername(this.username).subscribe(user => {
this.user = user;
});
}
)
}
ngOnInit(): void {
this.gymService.findAllGyms().subscribe(gyms => {
this.gyms = gyms;
});
}
logout(id: number) {
this.storageService.signOut();
this.router.navigateByUrl('/login');
this.storageService.deleteUser(id).subscribe();
}
}
src/app/home-component.html
<div class="topnav">
<a class="active" href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
<div class="login-container">
<button type="submit" (click)="logout(user.id)">Logout {{user.username}}</button>
</div>
</div>
<div id="maincontainer">
<div id="leftcolumn">
<mat-card style="height: 918px; background-color: #e9e9e9;">
<mat-card-header>
<mat-card-title>Gyms </mat-card-title>
<mat-card-subtitle>All Gyms Information</mat-card-subtitle>
</mat-card-header>
<hr>
<mat-selection-list #shoes [multiple]="false">
<mat-list-option *ngFor="let gym of gyms" [value]="gym" [routerLink]="['/home/' + username + '/find-all-gyms/', gym.id]">
{{gym.name}}
</mat-list-option>
</mat-selection-list>
</mat-card>
</div>
<div id="contentwrapper">
<router-outlet></router-outlet>
</div>
</div>
src/app/home-component.css
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
.topnav {
overflow: hidden;
background-color: #e9e9e9;
}
.topnav a {
float: left;
display: block;
color: black;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.topnav a.active {
background-color: #3f51b5;
color: white;
}
.topnav .login-container {
float: right;
}
.topnav input[type=text] {
padding: 6px;
margin-top: 8px;
font-size: 17px;
border: none;
width: 120px;
}
.topnav .login-container button {
float: right;
padding: 6px 10px;
margin-top: 8px;
margin-right: 16px;
background-color: #ff4081;
color: white;
font-size: 17px;
border: none;
cursor: pointer;
border-radius: 5px;
}
.topnav .login-container button:hover {
background-color: #3f51b5;
}
@media screen and (max-width: 600px) {
.topnav .login-container {
float: none;
}
.topnav a, .topnav input[type=text], .topnav .login-container button {
float: none;
display: block;
text-align: left;
width: 100%;
margin: 0;
padding: 14px;
}
.topnav input[type=text] {
border: 1px solid #ccc;
}
}
#maincontainer {
width:100%;
height: 100%;
}
#leftcolumn {
float: left;
display: inline-block;
width: 240px;
height: 100%;
}
#contentwrapper {
float: left;
display: inline-block;
width: -moz-calc(100% - 240px);
width: -webkit-calc(100% - 240px);
width: calc(100% - 240px);
height: 100%;
}
Conclusion
Now we have an overview of Angular 10 + Spring Boot CRUD example when building a CRUD App.
We also take a look at client-server architecture for REST API using Spring Web MVC & Spring Data JPA, as well as Angular 10 project structure for building a front-end app to make HTTP requests and consume responses.