I have a child Calendar Component that receives events from his father through an input field.
@Input() private events: any[];
When the month changes the parent gets new events from an API Service and calls the child component to show them.
private populateEventsForCurrentMonth() {
return this.calendarService.getEventsAsAdmin(this.getCurrentStartDate(),
this.getCurrentEndDate())
.then((evts) => {
this.events = evts;
this.calendarChild.selectEventDaysIfApplies();
})
.catch((err) => {
console.log('error getting events', err);
});
}
But when the child tries to access the events they haven't been updated!
My workaround was wrapping the child function in a timeout of 0 milliseconds to put the entire execution at the end of the event loop.
public selectEventDaysIfApplies() {
setTimeout(() => {
if (this.events) {
this.events.forEach((event) => {
let eventDate = new Date(event.starts_at);
if (this.datesBelongToSameMonth(eventDate, this.currentDate)) {
let dayWithEvent = this.days.find( (day) => {
return day.number == eventDate.getDate();
});
if (!dayWithEvent.selected) {
dayWithEvent.hasEvent = true;
}
}
});
}
}, 0);
}
Is there a better way of doing it? Maybe an Angular best practice that I should be implementing?
Thanks!
1- To create a method that accepts a value and do something with it in the parent component. 2- Then pass that same method as props to the child component. 3- After that, inside the child component you pass in the email as an argument to the method sent from the parent.
Otherwise, remember the three steps: Prepare Child component to emit data. Bind Property in Parent Component template. Use Property in Parent Component class.
The data is not available yet, because this function is handled synchronously:
this.events = evts;
this.calendarChild.selectEventDaysIfApplies();
Immediately, after this.events
has been set, the child components runs its method selectEventDaysIfApplies()
. That is before the Angular change detection is run.
In my opinion, the parent component should not know about any checks and modifications its child components have to do.
A better solution would be to use the lifecycle hook OnChanges
, which is triggered whenever an input of the component changes.
ngOnChanges(changes: SimpleChanges) {
this.selectEventDaysIfApplies();
}
If your component has more than one input, you can check which one was changed.
Read more about this in the docs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With