Getting Started | Building an Application with Angular
In this part We will continue to complete school project
Find Activity Components
In find Activity component we can display informarion of Activity with Update and Delete
src/app/find-activity-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Activity } from '../model/Model';
import { ActivityService } from '../service/activity.service';
import { AddActivityComponent } from '../add-activity/add-activity.component';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'find-activity',
templateUrl: './find-activity.component.html',
styleUrls: ['./find-activity.component.css']
})
export class FindActivityComponent implements OnInit {
activity: Activity = {} as Activity;
idActivity: number;
constructor (private route: ActivatedRoute, private activityService: ActivityService, private dialog: MatDialog,
private router: Router) {
this.route.params.subscribe (
params => {
this.idActivity = this.route.snapshot.params.idActivity;
this.activityService .findActivity (this.idActivity).subscribe (activity => {
this.activity = activity;
})
}
)
}
ngOnInit (): void {}
deleteActivity (idActivity: number) {
if(confirm( 'Are you sure' )) {
this.activityService .deleteActivity(idActivity ).subscribe (() => {
window.location .replace( `/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-activities` )
})
}
}
updateActivity(idActivity: number) {
this.dialog.open(AddActivityComponent, {
data : {idActivity},
height : '600px' ,
width : '400px' ,
});
}
}
src/app/find-activity-component.html
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>{{activity.type}}</mat-card-title>
<mat-card-subtitle>{{activity.createdAt|date}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content *ngIf="activity!=null">
<mat-list>
<mat-divider ></mat-divider >
<mat-list-item > <strong>{{activity.day}}</strong> </mat-list-item >
<mat-list-item >Date: {{activity.date|date: 'dd/MM/yyyy'}}</mat-list-item >
<mat-divider style="width: 180px !important;"></mat-divider >
<mat-list-item >Start: {{activity.startDate}}</mat-list-item >
<mat-divider style="width: 180px !important;"></mat-divider >
<mat-list-item >End: {{activity.endDate}}</mat-list-item >
<mat-divider style="width: 180px !important;"></mat-divider >
</mat-list>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{activity.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteActivity((activity.id)" >Delete activity</button>
<button mat-stroked-button color="primary" (click)="updateActivity(activity.id)">Update activity</button>
</mat-card-actions>
</mat-card>
Find Subject Components
In find Subject component we can display informarion of Subject with Update and Delete, We can also add a new Program
find-subject.component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Subject } from '../model/Model';
import { SubjectService } from '../service/subject.service';
import { AddSubjectComponent } from '../add-subject/add-subject.component';
import { ActivatedRoute, Router } from '@angular/router';
import { AddProgramComponent } from '../add-program/add-program.component';
import { AddCoefficientComponent} from '../add-coefficient/add-coefficient.component';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class FindSubjectComponent implements OnInit {
subject : Subject = {} as Subject;
idSubject : number;
constructor (private route: ActivatedRoute, private subjectService: SubjectService, private dialog: MatDialog) {
this.route.params.subscribe(
params => {
this.idSubject = this.route.snapshot.params.idSubject ;
this.subjectService.findSubject(this.idSubject ).subscribe(subject => {
this.subject = subject
})
}
)
}
ngOnInit(): void {
}
deleteSubject(idSubject: number) {
if(confirm('Are you sure')) {
this.subjectService.deleteSubject(idSubject).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-subjects`)
})
}
}
updateSubject(idSubject: number) {
this.dialog.open(AddSubjectComponent, {
data: {idSubject},
height: '620px',
width: '400px',
});
}
addProgram(idSubject: number) {
this.dialog.open(AddProgramComponent, {
data: {idSubject},
height: '320px',
width: '400px',
});
}
}
find-subject.component.html
<mat-card>
<mat-card-header [style.background-color]="subject.color" style="padding-top: 10px; border-radius: 5px; margin-bottom: 10px;">
<mat-card-title>Subject: {{subject.name}}</mat-card-title>
<mat-card-subtitle>Created at: {{subject.createdAt|date}} </mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-content><br>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{subject.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteSubject(subject.id)" >Delete subject</button>
<button mat-stroked-button color="primary" (click)="updateSubject(subject.id)">Update subject</button>
<button mat-stroked-button color="primary" (click)="addProgram(subject.id)">Add a new program</button>
</mat-card-actions>
</mat-card>
Add Program Components
In Add Program component we can add a new Program
src/app/add-program-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Program } from '../model/Model';
import { ProgramService } from '../service/program.service';
@Component({
selector: 'app-add-program',
templateUrl: './add-program.component.html',
styleUrls: ['./add-program.component.css']
})
export class AddProgramComponent implements OnInit {
progressBar = false;
program: Program = {} as Program;
constructor(private programService: ProgramService, @Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if(this.data.idProgram!=null) {
this.programService.findProgram(this.data.idProgram).subscribe(program => {
this.program = program;
})
}
}
addProgram() {
this.progressBar = true;
if(this.data.idProgram!=null) {
this.programService.editProgram(this.program, this.data.idProgram).subscribe(program => {
this.program = program;
window.location.reload();
})
} else {
this.programService.addProgram(this.program, this.data.idSubject).subscribe(program => {
this.program = program;
window.location.reload();
})
}
}
}
src/app/add-program-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new program</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form
<mat-form-field style="width: 100%;">
<mat-label>Name</mat-label>
<input type="text" matInput placeholder="name" name="name"
[(ngModel)]="program.name" #name="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="program.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="name.invalid || description.invalid"
(click)="addProgram()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Find Program Components
In Find Program component we can display information of Program and add a new Coefficien
src/app/find-program-component.ts
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Program } from '../model/Model';
import { ProgramService } from '../service/program.service';
import { AddCoefficientComponent } from '../add-coefficient/add-coefficient.component';
import { ActivatedRoute, Router } from '@angular/router';
import { AddProgramComponent } from '../add-program/add-program.component';
@Component({
selector: 'app-find-program',
templateUrl: './find-program.component.html',
styleUrls: ['./find-program.component.css']
})
export class FindProgramComponent implements OnInit {
program: Program = {} as Program;
idProgram: number;
constructor(private route: ActivatedRoute, private programService: ProgramService, private dialog: MatDialog) {
this.route.params.subscribe(
params => {
this.idProgram = this.route.snapshot.params.idProgram;
this.programService.findProgram(this.idProgram).subscribe(program => {
this.program = program;
})
}
)
}
ngOnInit(): void {}
updateProgram(idProgram: number) {
this.dialog.open(AddProgramComponent, {
data: {idProgram},
height: '320px',
width: '400px',
});
}
deleteProgram(idProgram: number) {
if(confirm('Are you sure')) {
this.programService.deleteProgram(idProgram).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-subjects`)
})
}
}
addCoefficient(idProgram: number) {
this.dialog.open(AddCoefficientComponent, {
data: {idProgram},
height: '320px',
width: '400px',
});
}
}
src/app/find-program-component.html
<mat-card>
<mat-card-header>
<mat-card-title>Program: {{program.name}}</mat-card-title>
<mat-card-subtitle>Created at: {{program.createdAt|date}} </mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-content><br>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{program.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteProgram(program.id)" >Delete program</button>
<button mat-stroked-button color="primary" (click)="updateProgram(program.id)">Update program</button>
<button mat-stroked-button color="primary" (click)="addCoefficient(program.id)">Add a new coefficient</button>
</mat-card-actions>
</mat-card>
Add Coefficien Components
In Add Coefficien component we can add a new Coefficien
src/app/add-coefficien-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Coefficient } from '../model/Model';
import { CoefficientService } from '../service/coefficient.service';
@Component({
selector: 'app-add-coefficient',
templateUrl: './add-coefficient.component.html',
styleUrls: ['./add-coefficient.component.css']
})
export class AddCoefficientComponent implements OnInit {
progressBar = false;
coefficient: Coefficient = {} as Coefficient;
constructor(private coefficientService: CoefficientService, @Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if(this.data.idCoefficient!=null) {
this.coefficientService.findCoefficient(this.data.idCoefficient).subscribe(coefficient => {
this.coefficient = coefficient;
})
}
}
addCoefficient() {
this.progressBar = true;
if(this.data.idCoefficient!=null) {
this.coefficientService.editCoefficient(this.coefficient, this.data.idCoefficient).subscribe(coefficient => {
this.coefficient = coefficient;
window.location.reload();
})
} else {
this.coefficientService.addCoefficient(this.coefficient, this.data.idProgram).subscribe(coefficient => {
this.coefficient = coefficient;
window.location.reload();
})
}
}
}
src/app/add-coefficien-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new coefficient</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<mat-label>Grade</mat-label>
<input type="number" matInput placeholder="grade" name="grade"
[(ngModel)]="coefficient.grade" #grade="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="coefficient.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="grade.invalid || description.invalid"
(click)="addCoefficient()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Find Coefficien Components
In Find Coefficien component we can display information of Coefficien and update/delete
src/app/find-coefficien-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Coefficient } from '../model/Model';
import { CoefficientService } from '../service/coefficient.service';
import { AddCoefficientComponent } from '../add-coefficient/add-coefficient.component';
@Component({
selector: 'app-find-coefficient',
templateUrl: './find-coefficient.component.html',
styleUrls: ['./find-coefficient.component.css']
})
export class FindCoefficientComponent implements OnInit {
coefficien: Coefficient = {} as Coefficient;
idCoefficient: number;
constructor(private route: ActivatedRoute, private coefficientService: CoefficientService, private dialog: MatDialog) {
this.route.params.subscribe(
params => {
this.idCoefficient = this.route.snapshot.params.idCoefficient;
this.coefficientService.findCoefficient(this.idCoefficient).subscribe(coefficien => {
this.coefficien = coefficien;
})
}
)
}
ngOnInit(): void {
}
deleteCoefficien(idCoefficient: number) {
if(confirm('Are you sure')) {
this.coefficientService.deleteCoefficient(idCoefficient).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-subjects`)
})
}
}
updateCoefficien(idCoefficient: number) {
this.dialog.open(AddCoefficientComponent, {
data: {idCoefficient},
height: '320px',
width: '400px',
});
}
}
src/app/find-coefficien-component.html
<mat-card>
<mat-card-header>
<mat-card-title>Coefficien grade: {{coefficien.grade}}</mat-card-title>
<mat-card-subtitle>Created at: {{coefficien.createdAt|date}} </mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-content><br>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{coefficien.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteCoefficien(coefficien.id)" >Delete coefficien</button>
<button mat-stroked-button color="primary" (click)="updateCoefficien(coefficien.id)">Update coefficien</button>
</mat-card-actions>
</mat-card>
Find Exam Components
In Find Exam component we can display information of Exam and update/delete We need elso add a new note for exam
src/app/find-exam-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Exam, Subject } from '../model/Model';
import { ExamService } from '../service/exam.service';
import { AddExamComponent } from '../add-exam/add-exam.component';
import { ActivatedRoute, Router } from '@angular/router';
import { SubjectService } from '../service/subject.service';
import { AddNoteComponent} from '../add-note/add-note.component';
@Component({
selector: 'app-find-exam',
templateUrl: './find-exam.component.html',
styleUrls: ['./find-exam.component.css']
})
export class FindExamComponent implements OnInit {
exam: Exam = {} as Exam;
subject: Subject = {} as Subject;
idExam: number;
constructor(private route: ActivatedRoute, private examService: ExamService,
private subjectService: SubjectService, private dialog: MatDialog) {
this.route.params.subscribe(
params => {
this.idExam = this.route.snapshot.params.idExam;
this.examService.findExam(this.idExam).subscribe(exam => {
this.exam = exam;
this.subjectService.findSubjectForExam(this.idExam).subscribe(subject => {
this.subject = subject;
})
})
}
)
}
ngOnInit(): void {
}
deleteExam(idExam: number, idSubject) {
if(confirm('Are you sure')) {
this.examService.deleteExam(idExam, idSubject).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-exams`)
})
}
}
updateExam(idExam: number) {
this.dialog.open(AddExamComponent, {
data: {idExam},
height: '480px',
width: '400px',
});
}
addNote(idExam: number) {
this.dialog.open(AddNoteComponent, {
data: {idExam},
height: '300px',
width: '400px',
});
}
}
src/app/find-exam-component.html
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Exam of <strong style="color: #4CAF50; text-decoration: underline;">{{subject?.name}}</strong> subject</mat-card-title>
<mat-card-subtitle>{{exam.createdAt|date}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<mat-list>
<mat-divider></mat-divider>
<mat-list-item>Date: {{exam.date|date: 'dd/MM/yyyy'}}</mat-list-item>
<mat-divider style="width: 180px !important;"></mat-divider>
<mat-list-item>Start: {{exam.start}}</mat-list-item>
<mat-divider style="width: 180px !important;"></mat-divider>
<mat-list-item>End: {{exam.end}}</mat-list-item>
<mat-divider style="width: 180px !important;"></mat-divider>
</mat-list>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{exam.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteExam(exam.id, subject.id)" >Delete exam</button>
<button mat-stroked-button color="primary" (click)="updateExam(exam.id)">Update exam</button>
<button mat-stroked-button color="primary" (click)="addNote(exam.id)">Add note</button>
</mat-card-actions>
</mat-card>
Add Note Components
In Add Note component we can add a new Note and update/delete
src/app/add-note-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Note } from '../model/Model';
import { NoteService } from '../service/note.service';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-add-note',
templateUrl: './add-note.component.html',
styleUrls: ['./add-note.component.css']
})
export class AddNoteComponent implements OnInit {
progressBar = false;
note: Note = {} as Note;
constructor(private noteService: NoteService, private route: ActivatedRoute,
@Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if(this.data.idNote) {
this.noteService.findNote(this.data.idNote).subscribe(note => {
this.note = note;
})
}
}
addNote() {
this.progressBar = true;
if(this.data.idNote) {
this.noteService.editNote(this.note, this.data.idNote).subscribe(note => {
this.note = note;
window.location.reload();
})
} else {
this.noteService.addNote(this.note, this.data.idExam).subscribe(note => {
this.note = note;
window.location.reload();
})
}
}
}
src/app/add-note-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new note</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<mat-label>Score</mat-label>
<input type="number" matInput placeholder="score" name="score"
[(ngModel)]="note.score" #score="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="note.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="score.invalid || description.invalid"
(click)="addNote()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Find Note Components
In Find Note component we can display inofrmation of Note and update/delete
src/app/find-note-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Note } from '../model/Model';
import { NoteService } from '../service/note.service';
import { AddNoteComponent } from '../add-note/add-note.component';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-find-note',
templateUrl: './find-note.component.html',
styleUrls: ['./find-note.component.css']
})
export class FindNoteComponent implements OnInit {
note: Note = {} as Note;
idNote: number;
constructor(private route: ActivatedRoute, private noteService: NoteService, private dialog: MatDialog) {
this.route.params.subscribe(
params => {
this.idNote = this.route.snapshot.params.idNote;
this.noteService.findNote(this.idNote).subscribe(note => {
this.note = note;
})
}
)
}
ngOnInit(): void {
}
deleteNote(idNote: number) {
if(confirm('Are you sure')) {
this.noteService.deleteNote(idNote).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-exams`)
})
}
}
updateNote(idNote: number) {
this.dialog.open(AddNoteComponent, {
data: {idNote},
height: '300px',
width: '400px',
});
}
}
src/app/find-note-component.html
<mat-card>
<mat-card-header>
<mat-card-title>Note score:
<button mat-mini-fab disabled style="color: #27ae60">
{{note.score}}
</button></mat-card-title>
<mat-card-subtitle>Created at: {{note.createdAt|date}} </mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-content><br>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{note.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteNote(note.id)" >Delete note</button>
<button mat-stroked-button color="primary" (click)="updateNote(note.id)">Update note</button>
</mat-card-actions>
</mat-card>
Find Room Components
In Find Room component we can display inofrmation of Room and update/delete We can elso add a new level of exists levels
src/app/find-room-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Level, Room } from '../model/Model';
import { RoomService } from '../service/room.service';
import { AddRoomComponent } from '../add-room/add-room.component';
import { AddLevelToRoomComponent } from '../add-level-to-room/add-level-to-room.component';
import { LevelService } from '../service/level.service';
@Component({
selector: 'app-find-room',
templateUrl: './find-room.component.html',
styleUrls: ['./find-room.component.css']
})
export class FindRoomComponent implements OnInit {
idRoom: number;
room: Room = {} as Room;
level: Level = {} as Level;
constructor(private route: ActivatedRoute, private roomService: RoomService, private dialog: MatDialog,
private levelService: LevelService) {
this.route.params.subscribe(
params => {
this.idRoom = this.route.snapshot.params.idRoom;
this.roomService.findRoom(this.idRoom).subscribe(room => {
this.room = room;
if(this.level!=null) {
this.levelService.findLevelForRoom(this.idRoom).subscribe(level => {
this.level = level;
})
}
});
}
);
}
ngOnInit(): void {
}
deleteRoom(idRoom: number) {
if(confirm('Are you sure')) {
this.roomService.deleteRoom(idRoom).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-rooms`)
})
}
}
updateRoom(idRoom: number) {
this.dialog.open(AddRoomComponent, {
data: { idRoom },
height: '370px',
width: '400px',
});
}
addLevelToRoom(idRoom: number) {
this.dialog.open(AddLevelToRoomComponent, {
data: { idRoom },
height: '240px',
width: '400px',
});
}
deleteLevelFromRoom(idRoom: number, idLevel: number) {
if(confirm('Are you sure')){
this.levelService.deleteLevelFromRoom(idRoom, idLevel).subscribe((data) => {
window.location.reload();
})
}
}
}
src/app/find-room-component.html
<mat-card>
<mat-card-header>
<mat-card-title>Room: {{room.code}}</mat-card-title>
<mat-card-title>Capacity: {{room.capacity}}</mat-card-title>
<mat-card-subtitle>Created at: {{room.createdAt|date}} </mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-content><br>
<mat-list>
<h2 style="margin-left: 15px;">Levels</h2>
<mat-list-item style="color: cadetblue;" *ngIf="level!=null">
{{level.label}}
<span class="material-icons" style="color: #c0392b; margin-left: 15px; cursor: pointer;" (click)="deleteLevelFromRoom(room.id, level.id)">
close
</span>
</mat-list-item>
<mat-list-item style="color: cadetblue;" *ngIf="level==null"> No level</mat-list-item>
</mat-list>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{room.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteRoom(room.id)" >Delete room</button>
<button mat-stroked-button color="primary" (click)="updateRoom(room.id)">Update room</button>
<button mat-stroked-button color="primary" (click)="addLevelToRoom(room.id)" *ngIf="level==null">Add level to this room </button>
</mat-card-actions>
</mat-card>
Add Level To Room Components
In Add Level To Room component we can Add Level To Room Of exists levels from schooling
add-level-to-room.component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Level } from '../model/Model';
import { LevelService } from '../service/level.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class AddLevelToRoomComponent implements OnInit {
progressBar = false;
levels: Level[];
idLevel: number;
constructor(private levelService: LevelService, @Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
this.levelService.findLevels().subscribe(levels => {
this.levels = levels;
})
}
onSelecLevel(e) {
this.idLevel = e.target.value;
this.levelService.addLevelToRoom(this.data.idRoom, this.idLevel).subscribe(() => {
window.location.reload();
})
}
cancel() {
window.location.reload();
}
}
add-level-to-room.component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new course</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<mat-label>Please choose a level</mat-label>
<select matNativeControl required (change)="onSelecLevel($event)">
<option selected disabled>Levels</option>
<option *ngFor="let s of levels" [value]="s.id">{{s.label}}</option>
</select>
</mat-form-field><br>
<button mat-raised-button color="accent"
(click)="cancel()" style="width: 10em !important">Cancel</button>
</form>
</mat-card-content>
</mat-card>
</div>
Find Schooling Components
In Find Schooling component we can display information of schooling and update/delete, We can elso Add a new Level for each Schooling
src/app/find-schooling-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Schooling } from '../model/Model';
import { SchoolingService } from '../service/schooling.service';
import { AddSchoolingComponent } from '../add-schooling/add-schooling.component';
import { ActivatedRoute, Router } from '@angular/router';
import { AddLevelComponent } from '../add-level/add-level.component';
@Component({
selector: 'app-find-schooling',
templateUrl: './find-schooling.component.html',
styleUrls: ['./find-schooling.component.css']
})
export class FindSchoolingComponent implements OnInit {
schooling: Schooling = {} as Schooling;
idSchooling: number;
constructor(private route: ActivatedRoute, private schoolingService: SchoolingService, private dialog: MatDialog,
private router: Router) {
this.route.params.subscribe(
params => {
this.idSchooling = this.route.snapshot.params.idSchooling;
this.schoolingService.findSchooling(this.idSchooling).subscribe(schooling => {
this.schooling = schooling;
})
}
)
}
ngOnInit(): void {}
deleteSchooling(idSchooling: number) {
if(confirm('Are you sure')) {
this.schoolingService.deleteSchooling(idSchooling).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-schoolings`)
})
}
}
src/app/find-schooling-component.html
<mat-card class="example-card">
<mat-card-content>
<h2 style="margin-left: 15px;">Year: {{schooling.year}}</h2>
<mat-card-title>Created at: {{schooling.createdAt|date}}</mat-card-title>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{schooling.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteSchooling(schooling.id)" >Delete activity</button>
<button mat-stroked-button color="primary" (click)="updateSchooling(schooling.id)">Update activity</button>
<button mat-stroked-button color="primary" (click)="addLevel(schooling.id)">Add level</button>
</mat-card-actions>
</mat-card>
Add Level Components
In Add Level component we can add a new level
src/app/add-level-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Level } from '../model/Model';
import { LevelService } from '../service/level.service';
@Component({
selector: 'app-add-level',
templateUrl: './add-level.component.html',
styleUrls: ['./add-level.component.css']
})
export class AddLevelComponent implements OnInit {
progressBar = false;
level: Level = {} as Level;
constructor( private levelService: LevelService, @Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if(this.data.idLevel!=null) {
this.levelService.findLevel(this.data.idLevel).subscribe(level => {
this.level = level;
})
}
}
addLevel() {
if(this.data.idLevel!=null) {
this.levelService.editLevel(this.level, this.data.idLevel).subscribe(level => {
this.level = level;
window.location.reload();
})
} else {
this.levelService.addLevel(this.level, this.data.idSchooling).subscribe(level => {
this.level = level;
window.location.reload();
})
}
}
}
src/app/add-level-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new level</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<input type="text" matInput name="label"
[(ngModel)]="level.label" #label="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="level.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="description.invalid || label.invalid"
(click)="addLevel()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Find Level Components
In Find Level component we can display information of level and update/delete, We can elso add a new course
src/app/find-level-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Level } from '../model/Model';
import { LevelService } from '../service/level.service';
import { AddNoteComponent } from '../add-note/add-note.component';
import { ActivatedRoute, Router } from '@angular/router';
import { AddLevelComponent } from '../add-level/add-level.component';
import { AddCourseComponent } from '../add-course/add-course.component';
@Component({
selector: 'app-find-level',
templateUrl: './find-level.component.html',
styleUrls: ['./find-level.component.css']
})
export class FindLevelComponent implements OnInit {
level: Level = {} as Level;
idLevel: number;
idSchool: number;
constructor(private levelService: LevelService, private route: ActivatedRoute, private dialog: MatDialog) {
this.route.params.subscribe(
params => {
this.idSchool = this.route.parent.snapshot.params.idSchool;
this.idLevel = this.route.snapshot.params.idLevel;
this.levelService.findLevel(this.idLevel).subscribe(level => {
this.level = level;
})
}
)
}
ngOnInit(): void {}
deleteLevel(idLevel: number) {
if(confirm('Are you sure')) {
this.levelService.deleteLevel(idLevel).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-schoolings`)
})
}
}
updateLevel(idLevel: number) {
this.dialog.open(AddLevelComponent, {
data: {idLevel},
height: '300px',
width: '400px',
});
}
addCourse(idLevel: number) {
this.dialog.open(AddCourseComponent, {
data: {idLevel},
height: '500px',
width: '400px',
});
}
}
src/app/find-level-component.html
<mat-card>
<mat-card-header>
<mat-card-title>Level: {{level.label}}</mat-card-title>
<mat-card-subtitle>Created at: {{level.createdAt|date}} </mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-content><br>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{level.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteLevel(level.id)" >Delete level</button>
<button mat-stroked-button color="primary" (click)="updateLevel(level.id)">Update level</button>
<button mat-stroked-button color="primary" [routerLink]="['/find-school/' + idSchool + '/add-course/', level.id]">Add course</button>
</mat-card-actions>
</mat-card>
Add Course Components
In Add Course component we can add a new course
src/app/add-course-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Course, Subject } from '../model/Model';
import { CourseService } from '../service/course.service';
import { SubjectService } from '../service/subject.service';
import { ActivatedRoute, Router } from '@angular/router';
import { SchoolService } from '../service/school.service';
@Component({
selector: 'app-add-course',
templateUrl: './add-course.component.html',
styleUrls: ['./add-course.component.css']
})
export class AddCourseComponent implements OnInit {
progressBar = false;
course: Course = {} as Course;
subject: Subject = {} as Subject;
subjects: Subject[];
idSubject: number;
idSchool: number;
idCourse: number;
idLevel: number;
constructor(private courseService: CourseService,
private subjectService: SubjectService, private route: ActivatedRoute) { }
ngOnInit(): void {
this.idLevel = this.route.snapshot.params.idLevel;
this.idCourse = this.route.snapshot.params.idCourse;
this.idSchool = this.route.parent.snapshot.params.idSchool;
if(this.idCourse!=null) {
this.courseService.findCourse(this.idCourse).subscribe(course => {
this.course = course;
this.subjectService.findSubjectForCourse(this.idCourse).subscribe(subject => {
this.subject = subject;
})
})
}
this.subjectService.findAllSubjectsForSchool(this.idSchool).subscribe(subjects => {
this.subjects = subjects;
})
}
onSelecSubject(e) {
this.idSubject = e.target.value;
}
onDateTime(e) {
this.course.date = e.target.value;
}
addCourse() {
this.progressBar = true;
if(this.idCourse!=null) {
this.courseService.editCourse(this.course, this.idCourse, this.idSubject).subscribe(course => {
this.course = course;
window.location.reload();
})
} else {
this.courseService.addCourse(this.course, this.idLevel, this.idSubject).subscribe(course => {
this.course = course;
window.location.reload();
})
}
}
}
src/app/add-course-component.html
<div style="margin: auto; width: 40%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new course</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<mat-label>Please choose a subject</mat-label>
<select matNativeControl required (change)="onSelecSubject($event)">
<option selected disabled>Subjects</option>
<option *ngFor="let s of subjects" [value]="s.id" [selected]="s.name==subject.name">{{s.name}}</option>
</select>
</mat-form-field><br>
<mat-form-field style="width: 100%;">
<input type="date" matInput name="date" min="minDate"
[(ngModel)]="course.date" #date="ngModel" required (change)="onDateTime($event)">
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>START</mat-label>
<input type="time" matInput placeholder="startTime" name="startTime"
[(ngModel)]="course.startDate" #startTime="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>END</mat-label>
<input type="time" matInput placeholder="endTime" name="endTime"
[(ngModel)]="course.endDate" #endTime="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="course.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="description.invalid || startTime.invalid || endTime.invalid"
(click)="addCourse()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Find Course Components
In Find Course component we can display inofrmation of Course and update/delete
src/app/find-course-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Course, Subject } from '../model/Model';
import { CourseService } from '../service/course.service';
import { SubjectService } from '../service/subject.service';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-find-course',
templateUrl: './find-course.component.html',
styleUrls: ['./find-course.component.css']
})
export class FindCourseComponent implements OnInit {
course: Course = {} as Course;
subject: Subject = {} as Subject;
idCourse: number;
idSchool: number;
constructor(private route: ActivatedRoute, private courseService: CourseService, private dialog: MatDialog,
private router: Router, private subjectService: SubjectService) {
this.route.params.subscribe(
params => {
this.idSchool = this.route.parent.snapshot.params.idSchool;
this.idCourse = this.route.snapshot.params.idCourse;
this.courseService.findCourse(this.idCourse).subscribe(course => {
this.course = course;
this.subjectService.findSubjectForCourse(this.idCourse).subscribe(subject => {
this.subject = subject;
})
})
}
)
}
ngOnInit(): void {}
deleteCourse(idCourse: number, idSubject: number) {
if(confirm('Are you sure')) {
this.courseService.deleteCourse(idCourse, idSubject).subscribe(() => {
window.location.replace(`/find-school/ ${this.route.parent.snapshot.params.idSchool} /find-schoolings`)
})
}
}
}
src/app/find-course-component.html
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Course of <strong style="color: #4CAF50; text-decoration: underline;">{{subject.name}}</strong> subject</mat-card-title>
<mat-card-subtitle>{{course.createdAt|date}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<mat-list>
<mat-divider></mat-divider>
<mat-list-itemDate: {{course.date|date: 'dd/MM/yyyy'}}</mat-list-item
<mat-divider style="width: 180px !important;"></mat-divider>
<mat-list-itemStart: {{course.startDate}}</mat-list-item
<mat-divider style="width: 180px !important;"></mat-divider>
<mat-list-itemEnd: {{course.endDate}}</mat-list-item
<mat-divider style="width: 180px !important;"></mat-divider>
</mat-list>
<p style="padding: 10px; color: #333; background: #f5f6fa;">
{{course.description}}
</p>
</mat-card-content>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="deleteCourse(course.id, subject.id)">Delete course</button>
<button mat-stroked-button color="primary" [routerLink]="['/find-school/' + idSchool + '/edit-course/', course.id]">Update course</button>
</mat-card-actions>
</mat-card>
NgModules and JavaScript modules
The NgModule system is different from and unrelated to the JavaScript (ES2015) module system for managing collections of JavaScript objects. These are complementary module systems that you can use together to write your apps.
In JavaScript each file is a module and all objects defined in the file belong to that module. The module declares some objects to be public by marking them with the export key word. Other JavaScript modules use import statements to access public objects from other modules.
app-module.ts
import { BrowserModule } form '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule, NO_ERRORS_SCHEMA } form '@angular/core';
import { AppRoutingModule } form './app-routing.module';
import { AppComponent } form './app.component';
import { NoopAnimationsModule } form '@angular/platform-browser/animations';
import { MaterialModule } form './material-module';
import { HomeComponent } form './home/home.component';
import { HttpClientModule } form '@angular/common/http';
import { FormsModule } form '@angular/forms';
import { AddSchoolComponent } form './add-school/add-school.component';
import { FindSchoolComponent } form './find-school/find-school.component';
import { AddManagerComponent } form './add-manager/add-manager.component';
import { DisplaySchoolComponent } form './display-school/display-school.component';
import { AddActivityComponent } form './add-activity/add-activity.component';
import { FindActivityComponent } form './find-activity/find-activity.component';
import { FindActivitiesComponent } form './find-activities/find-activities.component';
import { AddSchoolingComponent } form './add-schooling/add-schooling.component';
import { FindSchoolingsComponent } form './find-schoolings/find-schoolings.component';
import { FindSchoolingComponent } form './find-schooling/find-schooling.component';
import { AddExamComponent } form './add-exam/add-exam.component';
import { AddRoomComponent } form './add-room/add-room.component';
import { FindRoomsComponent } form './find-rooms/find-rooms.component';
import { FindRoomComponent } form './find-room/find-room.component';
import { ColorPickerModule } form 'ngx-color-picker';
import { AddSubjectComponent } form './add-subject/add-subject.component';
import { FindSubjectsComponent } form './find-subjects/find-subjects.component';
import { FindSubjectComponent } form './find-subject/find-subject.component';
import { AddProgramComponent } form './add-program/add-program.component';
import { FindProgramComponent } form './find-program/find-program.component';
import { AddCoefficientComponent } form './add-coefficient/add-coefficient.component';
import { FindCoefficientComponent } form './find-coefficient/find-coefficient.component';
import { FindExamsComponent } form './find-exams/find-exams.component';
import { FindExamComponent } form './find-exam/find-exam.component';
import { AddNoteComponent } form './add-note/add-note.component';
import { FindNoteComponent } form './find-note/find-note.component';
import { AddLevelComponent } form './add-level/add-level.component';
import { FindLevelComponent } form './find-level/find-level.component';
import { AddCourseComponent } form './add-course/add-course.component';
import { FindCourseComponent } form './find-course/find-course.component';
import { AddLevelToRoomComponent } form './add-level-to-room/add-level-to-room.component';
import { FindLevelToRoomComponent } form './find-level-to-room/find-level-to-room.component';
import { DashboardComponent } form './dashboard/dashboard.component';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
AddSchoolComponent,
FindSchoolComponent,
AddManagerComponent,
DisplaySchoolComponent,
AddActivityComponent,
FindActivityComponent,
FindActivitiesComponent,
AddSchoolingComponent,
FindSchoolingsComponent,
FindSchoolingComponent,
AddExamComponent,
AddRoomComponent,
FindRoomsComponent,
FindRoomComponent,
AddSubjectComponent,
FindSubjectsComponent,
FindSubjectComponent,
AddProgramComponent,
FindProgramComponent,
AddCoefficientComponent,
FindCoefficientComponent,
FindExamsComponent,
FindExamComponent,
AddNoteComponent,
FindNoteComponent,
AddLevelComponent,
FindLevelComponent,
AddCourseComponent,
FindCourseComponent,
AddLevelToRoomComponent,
FindLevelToRoomComponent,
DashboardComponent
],
imports: [
BrowserModule,
HttpClientModule,
FormsModule,
NoopAnimationsModule,
MaterialModule,
AppRoutingModule,
ColorPickerModule
],
providers: [],
bootstrap: [AppComponent],
schemas: [ CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA ]
})
export class AppModule { }
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.