We must modify the default Employee controller with below code changes.
We will be adding a new record to Notification table after adding, editing or deleting a record in the Employee table inside the respective web methods. Also notice that, we have broadcasted the message to all connected clients inside these web methods.
We must create below models for notification count and notification result.
We can create new API class “NotificationsController” to get details from Notification table. This controller will also use to delete entire records from Notification table.
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.AspNetCore.SignalR;
- using Microsoft.EntityFrameworkCore;
- using NET5SignalR.Data;
- using NET5SignalR.Models;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
-
- namespace NET5SignalR.Controllers
- {
- [Route("api/[controller]")]
- [ApiController]
- public class NotificationsController : ControllerBase
- {
- private readonly MyDbContext _context;
- private readonly IHubContext<BroadcastHub, IHubClient> _hubContext;
-
- public NotificationsController(MyDbContext context, IHubContext<BroadcastHub, IHubClient> hubContext)
- {
- _context = context;
- _hubContext = hubContext;
- }
-
-
- [Route("notificationcount")]
- [HttpGet]
- public async Task<ActionResult<NotificationCountResult>> GetNotificationCount()
- {
- var count = (from not in _context.Notification
- select not).CountAsync();
- NotificationCountResult result = new NotificationCountResult
- {
- Count = await count
- };
- return result;
- }
-
-
- [Route("notificationresult")]
- [HttpGet]
- public async Task<ActionResult<List<NotificationResult>>> GetNotificationMessage()
- {
- var results = from message in _context.Notification
- orderby message.Id descending
- select new NotificationResult
- {
- EmployeeName = message.EmployeeName,
- TranType = message.TranType
- };
- return await results.ToListAsync();
- }
-
-
- [HttpDelete]
- [Route("deletenotifications")]
- public async Task<IActionResult> DeleteNotifications()
- {
- await _context.Database.ExecuteSqlRawAsync("TRUNCATE TABLE Notification");
- await _context.SaveChangesAsync();
- await _hubContext.Clients.All.BroadcastMessage();
-
- return NoContent();
- }
- }
- }
Above controller has three web methods. “GetNotificationCount” is used to get total notification count and “GetNotificationMessage” is used to get all notification details (Employee name and Transaction type). “DeleteNotifications” is used to delete entire records from Notification table.
We have completed all API side code. If needed, you can check all the web methods using Swagger or Postman tool.
Create Angular 11 application using CLI
We can create the Angular 11 application using Angular CLI. We will create all the services and components step by step.
Create a new Angular application using below command.
ng new AngularSignalR
We can choose the option to create Routing. (Be default, it is false)
It will take some time to install all the node packages. We can install below three packages using npm command.
npm install @microsoft/signalr
npm install bootstrap
npm install font-awesome
We have now installed the SignalR client, bootstrap and font-awesome packages in our Angular application. We must modify “styles.css” file in the root folder with below changes to access these packages globally in the application without further references.
styles.css
- @import "~bootstrap/dist/css/bootstrap.css";
- @import "~font-awesome/css/font-awesome.css";
Create an environment variable inside environment class for baseUrl. This will be used across the application.
environment.ts
-
-
-
-
- export const environment = {
- production: false,
- baseUrl: 'http://localhost:62769/'
- };
-
-
-
-
-
-
-
-
-
Please replace the API end point with your API end point port number.
We can create an employee class now.
ng g class employee\employee
employee.ts
- export interface Employee {
- id: string,
- name: string,
- address: string,
- gender: string,
- company: string,
- designation: string,
- cityname: string
- }
We can create an employee service now.
ng g service employee\employee
employee.service.ts
- import { Injectable } from '@angular/core';
- import { HttpClient, HttpHeaders } from '@angular/common/http';
- import { Observable, throwError, of } from 'rxjs';
- import { catchError, map } from 'rxjs/operators';
- import { Employee } from './employee';
- import { environment } from 'src/environments/environment';
-
- @Injectable({
- providedIn: 'root'
- })
- export class EmployeeService {
- private employeesUrl = environment.baseUrl + 'api/employees';
-
- constructor(private http: HttpClient) { }
-
- getEmployees(): Observable<Employee[]> {
- return this.http.get<Employee[]>(this.employeesUrl)
- .pipe(
- catchError(this.handleError)
- );
- }
-
- getEmployee(id: string): Observable<Employee> {
- if (id === '') {
- return of(this.initializeEmployee());
- }
- const url = `${this.employeesUrl}/${id}`;
- return this.http.get<Employee>(url)
- .pipe(
- catchError(this.handleError)
- );
- }
-
- createEmployee(employee: Employee): Observable<Employee> {
- const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
- return this.http.post<Employee>(this.employeesUrl, employee, { headers: headers })
- .pipe(
- catchError(this.handleError)
- );
- }
-
- deleteEmployee(id: string): Observable<{}> {
- const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
- const url = `${this.employeesUrl}/${id}`;
- return this.http.delete<Employee>(url, { headers: headers })
- .pipe(
- catchError(this.handleError)
- );
- }
-
- updateEmployee(employee: Employee): Observable<Employee> {
- debugger
- const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
- const url = `${this.employeesUrl}/${employee.id}`;
- return this.http.put<Employee>(url, employee, { headers: headers })
- .pipe(
- map(() => employee),
- catchError(this.handleError)
- );
- }
-
- private handleError(err) {
- let errorMessage: string;
- if (err.error instanceof ErrorEvent) {
- errorMessage = `An error occurred: ${err.error.message}`;
- } else {
- errorMessage = `Backend returned code ${err.status}: ${err.body.error}`;
- }
- console.error(err);
- return throwError(errorMessage);
- }
-
- private initializeEmployee(): Employee {
- return {
- id: null,
- name: null,
- address: null,
- gender: null,
- company: null,
- designation: null,
- cityname: null
- };
- }
- }
We can create employee list component. This component will be used to display all the employee information. This component also uses to edit and delete employee data.
ng g component employee\EmployeeList
We can modify the class file with below code.
employee-list.component.ts
- import { Component, OnInit } from '@angular/core';
- import { Employee } from '../employee';
- import { EmployeeService } from '../employee.service';
- import * as signalR from '@microsoft/signalr';
- import { environment } from 'src/environments/environment';
-
- @Component({
- selector: 'app-employee-list',
- templateUrl: './employee-list.component.html',
- styleUrls: ['./employee-list.component.css']
- })
- export class EmployeeListComponent implements OnInit {
- pageTitle = 'Employee List';
- filteredEmployees: Employee[] = [];
- employees: Employee[] = [];
- errorMessage = '';
-
- _listFilter = '';
- get listFilter(): string {
- return this._listFilter;
- }
- set listFilter(value: string) {
- this._listFilter = value;
- this.filteredEmployees = this.listFilter ? this.performFilter(this.listFilter) : this.employees;
- }
-
- constructor(private employeeService: EmployeeService) { }
-
- performFilter(filterBy: string): Employee[] {
- filterBy = filterBy.toLocaleLowerCase();
- return this.employees.filter((employee: Employee) =>
- employee.name.toLocaleLowerCase().indexOf(filterBy) !== -1);
- }
-
- ngOnInit(): void {
- this.getEmployeeData();
-
- const connection = new signalR.HubConnectionBuilder()
- .configureLogging(signalR.LogLevel.Information)
- .withUrl(environment.baseUrl + 'notify')
- .build();
-
- connection.start().then(function () {
- console.log('SignalR Connected!');
- }).catch(function (err) {
- return console.error(err.toString());
- });
-
- connection.on("BroadcastMessage", () => {
- this.getEmployeeData();
- });
- }
-
- getEmployeeData() {
- this.employeeService.getEmployees().subscribe(
- employees => {
- this.employees = employees;
- this.filteredEmployees = this.employees;
- },
- error => this.errorMessage = <any>error
- );
- }
-
- deleteEmployee(id: string, name: string): void {
- if (id === '') {
- this.onSaveComplete();
- } else {
- if (confirm(`Are you sure want to delete this Employee: ${name}?`)) {
- this.employeeService.deleteEmployee(id)
- .subscribe(
- () => this.onSaveComplete(),
- (error: any) => this.errorMessage = <any>error
- );
- }
- }
- }
-
- onSaveComplete(): void {
- this.employeeService.getEmployees().subscribe(
- employees => {
- this.employees = employees;
- this.filteredEmployees = this.employees;
- },
- error => this.errorMessage = <any>error
- );
- }
-
- }
If you look at the code, you can see that inside ngOnInit method, I have created a constant variable with signalR hub connection builder and also started the connection. This connection will be listening to the messages from SignlarR hub from backend Web API. Whenever, backend sends a message, getEmployeeData method will be triggered automatically.
We can modify the template and style files also.
employee-list.component.html
- <div class="card">
- <div class="card-header">
- {{pageTitle}}
- </div>
- <div class="card-body">
- <div class="row" style="margin-bottom:15px;">
- <div class="col-md-2">Filter by:</div>
- <div class="col-md-4">
- <input type="text" [(ngModel)]="listFilter" />
- </div>
- <div class="col-md-2"></div>
- <div class="col-md-4">
- <button class="btn btn-primary mr-3" [routerLink]="['/employees/0/edit']">
- New Employee
- </button>
- </div>
- </div>
- <div class="row" *ngIf="listFilter">
- <div class="col-md-6">
- <h4>Filtered by: {{listFilter}}</h4>
- </div>
- </div>
- <div class="table-responsive">
- <table class="table mb-0" *ngIf="employees && employees.length">
- <thead>
- <tr>
- <th>Name</th>
- <th>Address</th>
- <th>Gender</th>
- <th>Company</th>
- <th>Designation</th>
- <th></th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let employee of filteredEmployees">
- <td>
- <a [routerLink]="['/employees', employee.id]">
- {{ employee.name }}
- </a>
- </td>
- <td>{{ employee.address }}</td>
- <td>{{ employee.gender }}</td>
- <td>{{ employee.company }}</td>
- <td>{{ employee.designation}} </td>
- <td>
- <button class="btn btn-outline-primary btn-sm"
- [routerLink]="['/employees', employee.id, 'edit']">
- Edit
- </button>
- </td>
- <td>
- <button class="btn btn-outline-warning btn-sm"
- (click)="deleteEmployee(employee.id,employee.name);">
- Delete
- </button>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- <div *ngIf="errorMessage" class="alert alert-danger">
- Error: {{ errorMessage }}
- </div>
employee-list.component.css
- thead {
- color: #337AB7;
- }
We can create employee edit component with below command
ng g component employee\EmployeeEdit
Modify the class file with below code.
employee-edit.component.ts
- import { Component, OnInit, OnDestroy, ElementRef, ViewChildren } from '@angular/core';
- import { FormControlName, FormGroup, FormBuilder, Validators } from '@angular/forms';
- import { Subscription } from 'rxjs';
- import { ActivatedRoute, Router } from '@angular/router';
- import { Employee } from '../employee';
- import { EmployeeService } from '../employee.service';
-
- @Component({
- selector: 'app-employee-edit',
- templateUrl: './employee-edit.component.html',
- styleUrls: ['./employee-edit.component.css']
- })
- export class EmployeeEditComponent implements OnInit, OnDestroy {
- @ViewChildren(FormControlName, { read: ElementRef }) formInputElements: ElementRef[];
- pageTitle = 'Employee Edit';
- errorMessage: string;
- employeeForm: FormGroup;
- tranMode: string;
- employee: Employee;
- private sub: Subscription;
-
- displayMessage: { [key: string]: string } = {};
- private validationMessages: { [key: string]: { [key: string]: string } };
-
- constructor(private fb: FormBuilder,
- private route: ActivatedRoute,
- private router: Router,
- private employeeService: EmployeeService) {
-
- this.validationMessages = {
- name: {
- required: 'Employee name is required.',
- minlength: 'Employee name must be at least three characters.',
- maxlength: 'Employee name cannot exceed 50 characters.'
- },
- cityname: {
- required: 'Employee city name is required.',
- }
- };
- }
-
- ngOnInit() {
- this.tranMode = "new";
- this.employeeForm = this.fb.group({
- name: ['', [Validators.required,
- Validators.minLength(3),
- Validators.maxLength(50)
- ]],
- address: '',
- cityname: ['', [Validators.required]],
- gender: '',
- company: '',
- designation: '',
- });
-
- this.sub = this.route.paramMap.subscribe(
- params => {
- const id = params.get('id');
- const cityname = params.get('cityname');
- if (id == '0') {
- const employee: Employee = { id: "0", name: "", address: "", gender: "", company: "", designation: "", cityname: "" };
- this.displayEmployee(employee);
- }
- else {
- this.getEmployee(id);
- }
- }
- );
- }
-
- ngOnDestroy(): void {
- this.sub.unsubscribe();
- }
-
- getEmployee(id: string): void {
- this.employeeService.getEmployee(id)
- .subscribe(
- (employee: Employee) => this.displayEmployee(employee),
- (error: any) => this.errorMessage = <any>error
- );
- }
-
- displayEmployee(employee: Employee): void {
- if (this.employeeForm) {
- this.employeeForm.reset();
- }
- this.employee = employee;
- if (this.employee.id == '0') {
- this.pageTitle = 'Add Employee';
- } else {
- this.pageTitle = `Edit Employee: ${this.employee.name}`;
- }
- this.employeeForm.patchValue({
- name: this.employee.name,
- address: this.employee.address,
- gender: this.employee.gender,
- company: this.employee.company,
- designation: this.employee.designation,
- cityname: this.employee.cityname
- });
- }
-
- deleteEmployee(): void {
- if (this.employee.id == '0') {
- this.onSaveComplete();
- } else {
- if (confirm(`Are you sure want to delete this Employee: ${this.employee.name}?`)) {
- this.employeeService.deleteEmployee(this.employee.id)
- .subscribe(
- () => this.onSaveComplete(),
- (error: any) => this.errorMessage = <any>error
- );
- }
- }
- }
-
- saveEmployee(): void {
- if (this.employeeForm.valid) {
- if (this.employeeForm.dirty) {
- const p = { ...this.employee, ...this.employeeForm.value };
- if (p.id === '0') {
- this.employeeService.createEmployee(p)
- .subscribe(
- () => this.onSaveComplete(),
- (error: any) => this.errorMessage = <any>error
- );
- } else {
- this.employeeService.updateEmployee(p)
- .subscribe(
- () => this.onSaveComplete(),
- (error: any) => this.errorMessage = <any>error
- );
- }
- } else {
- this.onSaveComplete();
- }
- } else {
- this.errorMessage = 'Please correct the validation errors.';
- }
- }
-
- onSaveComplete(): void {
- this.employeeForm.reset();
- this.router.navigate(['/employees']);
- }
- }
We can modify the template file also.
employee-edit.component.html
We need one more component to display the employee details in a separate window. We can create now.
ng g component employee\EmployeeDetail
We can modify the class file with below code.
employee-detail.component.ts
- import { Component, OnInit } from '@angular/core';
- import { ActivatedRoute, Router } from '@angular/router';
- import { Employee } from '../employee';
- import { EmployeeService } from '../employee.service';
-
- @Component({
- selector: 'app-employee-detail',
- templateUrl: './employee-detail.component.html',
- styleUrls: ['./employee-detail.component.css']
- })
- export class EmployeeDetailComponent implements OnInit {
- pageTitle = 'Employee Detail';
- errorMessage = '';
- employee: Employee | undefined;
-
- constructor(private route: ActivatedRoute,
- private router: Router,
- private employeeService: EmployeeService) { }
-
- ngOnInit() {
- const id = this.route.snapshot.paramMap.get('id');
- if (id) {
- this.getEmployee(id);
- }
- }
-
- getEmployee(id: string) {
- this.employeeService.getEmployee(id).subscribe(
- employee => this.employee = employee,
- error => this.errorMessage = <any>error);
- }
-
- onBack(): void {
- this.router.navigate(['/employees']);
- }
- }
Modify the template file with below code.
employee-detail.component.html
- <div class="card">
- <div class="card-header"
- *ngIf="employee">
- {{pageTitle + ": " + employee.name}}
- </div>
- <div class="card-body"
- *ngIf="employee">
- <div class="row">
- <div class="col-md-8">
- <div class="row">
- <div class="col-md-3">Name:</div>
- <div class="col-md-6">{{employee.name}}</div>
- </div>
- <div class="row">
- <div class="col-md-3">City:</div>
- <div class="col-md-6">{{employee.cityname}}</div>
- </div>
- <div class="row">
- <div class="col-md-3">Address:</div>
- <div class="col-md-6">{{employee.address}}</div>
- </div>
- <div class="row">
- <div class="col-md-3">Gender:</div>
- <div class="col-md-6">{{employee.gender}}</div>
- </div>
- <div class="row">
- <div class="col-md-3">Company:</div>
- <div class="col-md-6">{{employee.company}}</div>
- </div>
- <div class="row">
- <div class="col-md-3">Designation:</div>
- <div class="col-md-6">{{employee.designation}}</div>
- </div>
- </div>
- </div>
- <div class="row mt-4">
- <div class="col-md-4">
- <button class="btn btn-outline-secondary mr-3"
- style="width:80px"
- (click)="onBack()">
- <i class="fa fa-chevron-left"></i> Back
- </button>
- <button class="btn btn-outline-primary"
- style="width:80px"
- [routerLink]="['/employees', employee.id,'edit']">
- Edit
- </button>
- </div>
- </div>
- </div>
- <div class="alert alert-danger"
- *ngIf="errorMessage">
- {{errorMessage}}
- </div>
- </div>
We need a modal popup window to display the notification messages. As I mentioned earlier, application will create new record into notification table for each transaction like Add/Edit/Delete.
We can create modal service first.
ng g service modal\modal
Modify the service class with below code.
modal.service.ts
- import { Injectable } from '@angular/core';
-
- @Injectable({
- providedIn: 'root'
- })
- export class ModalService {
-
- constructor() { }
-
- private modals: any[] = [];
-
- add(modal: any) {
- this.modals.push(modal);
- }
-
- remove(id: string) {
- this.modals = this.modals.filter(x => x.id !== id);
- }
-
- open(id: string) {
- const modal = this.modals.find(x => x.id === id);
- modal.open();
- }
-
- close(id: string) {
- const modal = this.modals.find(x => x.id === id);
- modal.close();
- }
- }
Now, we can create the component using below command.
ng g component modal
Modify the class file with below code.
modal.component.ts
- import { Component, ElementRef, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
- import { ModalService } from './modal.service';
-
- @Component({
- selector: 'app-modal',
- templateUrl: './modal.component.html',
- styleUrls: ['./modal.component.less'],
- encapsulation: ViewEncapsulation.None
- })
- export class ModalComponent implements OnInit, OnDestroy {
-
- @Input() id: string;
- private element: any;
-
- constructor(private modalService: ModalService, private el: ElementRef) {
- this.element = el.nativeElement;
- }
-
- ngOnInit() {
- if (!this.id) {
- console.error('modal must have an id');
- return;
- }
-
- document.body.appendChild(this.element);
-
- this.element.addEventListener('click', el => {
- if (el.target.className === 'app-modal') {
- this.close();
- }
- });
-
- this.modalService.add(this);
- }
-
- ngOnDestroy(): void {
- this.modalService.remove(this.id);
- this.element.remove();
- }
-
- open(): void {
- this.element.style.display = 'block';
- document.body.classList.add('app-modal-open');
- }
-
- close(): void {
- this.element.style.display = 'none';
- document.body.classList.remove('app-modal-open');
- }
- }
Please note that, we are using the “less” stylesheet instead of default “css” for this component.
modal.component.less
- app-modal {
- display: none;
-
- .app-modal {
- position: fixed;
- top: 1%;
- right: 0;
- bottom: 0;
- left: 25%;
-
- z-index: 1000;
-
- overflow: auto;
-
- .app-modal-body {
- padding: 10px;
- background: #fff;
-
- overflow-y: auto;
- margin-top: 40px;
- width: 700px;
- height: 450px;
- }
- }
-
- .app-modal-background {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
-
- background-color: #000;
- opacity: 0.75;
-
- z-index: 900;
- }
- }
-
- body.app-modal-open {
- overflow: hidden;
- }
“less” stylesheet files allow us the flexibility to add some logical coding inside the stylesheet.
We can modify the html template with below code.
modal.component.html
- <div class="app-modal">
- <div class="app-modal-body">
- <ng-content></ng-content>
- </div>
- </div>
- <div class="app-modal-background"></div>
We can create a notification class file and add two models “NotificationCountResult” and “NotificationResult” inside it.
ng g class notification\notification
notification.ts
- export class NotificationCountResult {
- count: number;
- }
-
- export class NotificationResult {
- employeeName: string;
- tranType: string;
- }
We can create the notification service now.
ng g service notification\notification
Replace service with below code.
notification.service.ts
- import { HttpClient, HttpHeaders } from '@angular/common/http';
- import { Injectable } from '@angular/core';
- import { Observable, throwError } from 'rxjs';
- import { catchError } from 'rxjs/operators';
- import { environment } from 'src/environments/environment';
- import { NotificationCountResult, NotificationResult } from './notification';
-
- @Injectable({
- providedIn: 'root'
- })
- export class NotificationService {
-
- private notificationsUrl = environment.baseUrl +'api/notifications';
-
- constructor(private http: HttpClient) { }
-
- getNotificationCount(): Observable<NotificationCountResult> {
- const url = `${this.notificationsUrl}/notificationcount`;
- return this.http.get<NotificationCountResult>(url)
- .pipe(
- catchError(this.handleError)
- );
- }
-
- getNotificationMessage(): Observable<Array<NotificationResult>> {
- const url = `${this.notificationsUrl}/notificationresult`;
- return this.http.get<Array<NotificationResult>>(url)
- .pipe(
- catchError(this.handleError)
- );
- }
-
- deleteNotifications(): Observable<{}> {
- const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
- const url = `${this.notificationsUrl}/deletenotifications`;
- return this.http.delete(url, { headers: headers })
- .pipe(
- catchError(this.handleError)
- );
- }
-
- private handleError(err) {
- let errorMessage: string;
- if (err.error instanceof ErrorEvent) {
- errorMessage = `An error occurred: ${err.error.message}`;
- } else {
- errorMessage = `Backend returned code ${err.status}: ${err.body.error}`;
- }
- console.error(err);
- return throwError(errorMessage);
- }
- }
Create the navigation menu component now.
ng g component NavMenu
Modify the class file with below code.
nav-menu.component.ts
- import { Component, OnInit } from '@angular/core';
- import { ModalService } from '../modal/modal.service';
- import * as signalR from '@microsoft/signalr';
- import { NotificationCountResult, NotificationResult } from '../Notification/notification';
- import { NotificationService } from '../Notification/notification.service';
- import { environment } from 'src/environments/environment';
-
- @Component({
- selector: 'app-nav-menu',
- templateUrl: './nav-menu.component.html',
- styleUrls: ['./nav-menu.component.css']
- })
- export class NavMenuComponent implements OnInit {
-
- notification: NotificationCountResult;
- messages: Array<NotificationResult>;
- errorMessage = '';
-
- constructor(private notificationService: NotificationService, private modalService: ModalService) { }
- isExpanded = false;
-
- ngOnInit() {
- this.getNotificationCount();
- const connection = new signalR.HubConnectionBuilder()
- .configureLogging(signalR.LogLevel.Information)
- .withUrl(environment.baseUrl + 'notify')
- .build();
-
- connection.start().then(function () {
- console.log('SignalR Connected!');
- }).catch(function (err) {
- return console.error(err.toString());
- });
-
- connection.on("BroadcastMessage", () => {
- this.getNotificationCount();
- });
- }
-
- collapse() {
- this.isExpanded = false;
- }
-
- toggle() {
- this.isExpanded = !this.isExpanded;
- }
-
- getNotificationCount() {
- this.notificationService.getNotificationCount().subscribe(
- notification => {
- this.notification = notification;
- },
- error => this.errorMessage = <any>error
- );
- }
-
- getNotificationMessage() {
- this.notificationService.getNotificationMessage().subscribe(
- messages => {
- this.messages = messages;
- },
- error => this.errorMessage = <any>error
- );
- }
-
- deleteNotifications(): void {
- if (confirm(`Are you sure want to delete all notifications?`)) {
- this.notificationService.deleteNotifications()
- .subscribe(
- () => {
- this.closeModal();
- },
- (error: any) => this.errorMessage = <any>error
- );
- }
- }
- openModal() {
- this.getNotificationMessage();
- this.modalService.open('custom-modal');
- }
-
- closeModal() {
- this.modalService.close('custom-modal');
- }
- }
Like the employee list component, we will add the singalR connection here as well.