Currently delving into the world of Angular (along with Typescript). I've put together a small application consisting of two components. This app is designed to help track work hours (yes, I am aware there are commercial products available for this purpose, but this project is purely for educational reasons).
One component is responsible for creating new hour entries which include details like employee, project, hours, and date. It features input fields and an "Add" button.
The other component displays the hours booked by the user for the selected day. Upon clicking the "Add" button in the first component, the second component should refresh its data from the API or database.
After researching online, it seems that using @Input arguments is the recommended approach. In this scenario, the detail component takes employeeId and date as inputs, where these remain constant while only the results (database content) may vary. I considered invoking a method on the detail component from the container housing both components, but encountered challenges in doing so.
How can I trigger a refresh in the detail component after the "Add" button is clicked?
Any insights or suggestions will be greatly appreciated.
EDIT: Relevant code
dailyHoursOverview.components.ts
import { HttpClient } from "@angular/common/http";
import { Component, Input, OnChanges, OnInit, SimpleChanges } from "@angular/core";
import { Activity } from "../shared/Activity";
import { Employee } from "../shared/Employee";
import { Project } from "../shared/Project";
@Component({
selector: "hour-daily",
templateUrl: "./dailyHoursOverview.component.html"
})
export class DailyHoursOverview implements OnInit, OnChanges
{
// @Input() date: string = "";
@Input() employeeId: number = 0;
@Input() date: string = "";
_http: HttpClient;
entries: HourEntry[] = [];
totalHours: number= 0;
constructor(http: HttpClient) {
this._http = http;
}
ngOnChanges(changes: SimpleChanges): void {
this.refreshData();
}
ngOnInit(): void {
this.refreshData();
}
refreshData() {
this._http.get<HourEntry[]>("http://localhost:5257/Employee/" + this.employeeId + "/HourEntry/ByDay/" + this.date)
.subscribe(
result => {
this.entries = result;
this.totalHours = this.entries.reduce((sum, entry) => sum + (entry.hours), 0);
},
error => console.error(error)
);
}
}
interface HourEntry {
project: Project;
activity: Activity;
employee: Employee;
hours: number;
date: string;
}
main.component.html (container of both sub components)
<div class="container">
<div class="row">
<div class="col-md-6 col-sm-8">
<hours-new [employeeId]="employeeId" [hourDate]="date" (entryCreated)="onEntryCreated();"></hours-new>
</div>
</div>
<div class="row">
<div class="col-12">
<hour-daily [employeeId]="employeeId" [date]="date"></hour-daily>
</div>
</div>
</div>
newHourEntry.component.ts
import { HttpClient } from '@angular/common/http';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Activity } from '../shared/Activity';
import { Project } from '../shared/Project';
import { Employee } from '../shared/Employee';
import { NewHourEntryDto } from '../shared/NewHoursEntryDto';
@Component({
selector: "hours-new",
templateUrl: "./newHourEntry.component.html"
})
export class NewHourEntryComponent implements OnInit {
@Input() employeeId: number = 0;
@Input() hourDate: string = "";
@Output() entryCreated: EventEmitter<any> = new EventEmitter();
private _http: HttpClient;
employeeName: string = "";
hourEntry: NewHourEntryDto;
projects: Project[];
activities: Activity[];
constructor(http: HttpClient) {
this._http = http;
this.hourEntry = { "activityId": 0, "projectId": 0, "date": "", "hours": 0, "employeeId": 0 };
this.projects = [];
this.activities = [];
}
ngOnInit(): void {
// Get options for comboboxes
this._http.get<Project[]>('http://localhost:5257/Project')
.subscribe({
next: result => { this.projects = result; },
error: error => console.error(error)
});
this._http.get<Activity>("http://localhost:5257/Activity")
.subscribe({
next: result => { this.activities = result; },
error: error => console.error(error)
});
this._http.get<Employee>("http://localhost:5257/Employee/" + this.employeeId)
.subscribe({
next: result => { this.employeeName = result.name; },
error: error => console.error(error)
});
}
createHourEntry(): void { // OnClick for the "Add" Button
this.hourEntry.date = this.hourDate;
this.hourEntry.employeeId = this.employeeId;
this._http.post("http://localhost:5257/HourEntry", this.hourEntry)
.subscribe({
next: result => { },
error: error => console.error(error)
});
this.entryCreated.emit();
}
}