I have a service in an Angular 2 app, events.service.ts:
const EVENTS = {
1512205360: {
event: 'foo'
},
1511208360: {
event: 'bar'
}
}
@Injectable()
export class EventsService {
getEvents() {
return EVENTS;
}
deleteEvent(timestamp) {
delete EVENTS[timestamp];
}
}
I have a home component which calls this service's getEvents method in its ngOnInit hook:
getEvents(): void {
this.events = this.eventsService.getEvents();
this.eventKeys = Object.keys(this.events);
}
ngOnInit(): void {
this.getEvents();
}
The home component's template simply loops over the events and prints them out, with a delete icon next to each one:
<event *ngFor="let eventKey of eventKeys" [timestamp]="eventKey" [title]="events[eventKey].event"></event>
This is the event component:
@Component({
selector: 'event',
templateUrl: './event.component.html',
providers: [EventsService]
})
export class EventComponent {
@Input() timestamp: string;
@Input() title: string;
constructor(private eventsService: EventsService) { }
deleteEvent(timestamp) {
this.eventsService.deleteEvent(timestamp);
}
}
Clicking the delete icon calls the deleteEvent method in the events service. My problem is that when I click the delete icon, although I can see that the event has been deleted (by console.logging the EVENTS object), the home component isn't updated and produces this error:
Cannot read property 'event' of undefined
The point is that HomeComponent.eventKeys array does not linked with HomeComponent.events object which is linked with EVENTS. You set HomeComponent.eventKeys array one time on start of the HomeComponent via Object.keys(). All operations with HomeComponent.events (and EVENTS) do not affect HomeComponent.eventKeys array. So ngFor continues tracking the initial keys array and blows up on unexisted events item.
There are many possible solutions, but the main idea is to sync HomeComponent.eventKeys with EVENTS. This could be done, for example, via passing a delete-method from the HomeComponent to the EventComponent and recalculating the eventKeys array after deletion:
// HomeComponent
deleteEvent(timestamp) {
this.eventsService.deleteEvent(timestamp);
this.getEvents();
}
UPDATE
Just created a plunk demo for this situation, enjoy: https://plnkr.co/edit/ogfmEY?p=preview
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