Currently, I am immersed in a project involving Angular 6 and utilizing the @Input and @Output decorators. In this scenario, I have the Bookride Component functioning as the parent component with RideDetails serving as the child component. Successfully transmitting data from the parent component to the child component using the @Input decorator proved to be smooth sailing. However, my attempts to transfer data from the child component back to the parent component hit a snag, resulting in an error message displayed in the console:
"ERROR TypeError: Cannot read property 'seatsavailable' of undefined"
BookRide Component - HTML(Parent Component)
<tr *ngFor = "let book of shrides | filterpipe:filterargs" (click) = "message = book">
<td>{{book.startloc}}</td>
<td>{{book.destination}}</td>
<td>{{book.seatsavailable}}</td>
<td (click)="deleteProduct(book.id)"><a>DELETE</a></td>
<td [routerLink] = "['/update-ride', book.id]" (click) = "update(book.id)"><a>UPDATE</a></td>
<app-ridedetails [cName] = "message" (onRegister)="courseReg($event)"></app-ridedetails>
The above line triggers an error in the console: "ERROR TypeError: Cannot read property 'seatsavailable' of undefined at RestserviceService.push../src/app/restservice.service.ts.RestserviceService.updateRide2 (restservice.service.ts:84)"
BookRide Component - TS
export class RidedetailsComponent implements OnInit {
seatsavailable: number;
courseReg(seatsavailable: number){
console.log("Booking ID", seatsavailable);
this.messages = `Booking Done. Your Booking name is : ${seatsavailable}`;
this.render = !this.render;
}}
RideDetails Component - HTML(Child Component)
<tr>
<td>{{loadData?.id}}</td>
<td>{{loadData?.name}}</td>
<td>{{loadData?.car}}</td>
<td>{{loadData?.seatsavailable}}</td>
<td>{{loadData?.startloc}}</td>
<td>{{loadData?.destination}}</td>
</tr>
<button type="button" (click)="register(loadData.id, loadData.seatsavailable)" [ngClass] = "render ? 'btn-primary' : 'btn-danger'"> {{render == true ? 'Book!' : 'Cancel! Booked ride'}} </button>
RideDetails Component - TS
export class RidedetailsComponent implements OnInit {
loadData:any;
sendData: any;
messages: any;
render: boolean = true;
seatsavailable: number;
ride: Ride[];
constructor(private restservice : RestserviceService) { }
ngOnInit() {
}
@Input() set cName(sampleObject){
this.loadData=sampleObject;
}
//Child to Parent Communication
//Sending an event to BookrideComponent and hide the table using @Output Decorator
@Output() onRegister = new EventEmitter();
register(bookingID: string, seatsavailable: number, ride: Ride) {
this.render = !this.render;
this.onRegister.emit({seatsavailable} as Ride);
this.messages = `Booking Done(ridedetails). Your Booking id: ${bookingID}`;
console.log("After clicking on Book button, the seats available data in ride details component is", this.loadData.seatsavailable);
if(this.loadData.seatsavailable === seatsavailable){
console.log("this.loadData.seatsavailable", this.loadData.seatsavailable - 1);
this.restservice.updateRide2(ride, seatsavailable).subscribe( shride => { this.loadData.seatsavailable - 1 });
}
}
}
In analyzing the RideDetails Component, it becomes apparent that the creation of a property named onRegister of type EventEmitter and coupling it with the @Output decorator facilitates the transmission of data from the child to the parent component. Subsequently, within the register() function, the seatsavailable value gets emitted back to the parent component. However, upon reaching the parent component, an error emerges.
A discrepancy also arises in the courseReg() method of the BookRide Component, where the console logs display 'Your Booking name is: [object Object]'.