I have a somewhat odd issue with EventEmitter in a class. While I have some ideas to work around the problem, I would like to ask you if you have an idea to directly solve my issue.
Short summary
I have a parent and a child component. The parent component would like to get notified when something in the child is changed.
Within the child, we have a button. On click, it executes a http request which modifies data. In the subscribe
code part, I would like to inform the parent class that something has been done.
This breaks down the idea and works as expected: https://stackblitz.com/edit/angular-l7hafr
The issue
In my application, the event from the child component is never emitted as long as it is done in the subscribe
of a http
request. If I emit the event before (outside the subscribe function), it works as expected.
What I have tried
I tried to find the cause. The problem is that I simply cannot manage to isolate the problem. The Stackblitz above works as expected, while nearly the same in my application does not.
Other posts related to this question suggested to execute the .emit()
in a NgZone runner like this:
this.ngZone.run(() => {
console.log(NgZone.isInAngularZone());
this.dataHasChanged.emit();
});
I implemented this within the subscribe callback, but the result is that console logs true
, but the test event is still never emitted.
How is this even possible? What can I do?
So I was finally able to isolate the issue and it is demonstrated in this very small example: https://stackblitz.com/edit/angular-46pndy
The reason for all the problems is in the getter
for the array. Why is this causing a problem here?
I think this might be weird behavior with Angular change detection. If you disable change detection, the event is received.
What is actually happening here, is that the EventEmitter actually has no subscribers when you use the getter to create the buttons. Detaching the change detection resolves the issue but is probably causing other side effects in your app.
This StackBlitz demonstrates one of the workarounds describe using a pure pipe.
Example StackBlitz: here
GitHub issues:
angular/angular/issues/6057
angular/angular/issues/5918