1

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?


EDIT

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?

andreas
  • 7,844
  • 9
  • 51
  • 72
  • You say "nearly the same". What is different to your app? – Fabian Beyerlein Sep 18 '19 at 14:05
  • your stackblitz example seems to successfully emit on every button click, what's the issue there ? – Nitsan Baleli Sep 18 '19 at 14:08
  • If your application does not behave like the stackblitz demo, you should include the relevant code of your application in the question (HTML markup + component code). – ConnorsFan Sep 18 '19 at 14:23
  • 1
    The relevant code is quite difficult to include, that is why I tried the minimal example. But it looks like there is no obvious solution or issue, so I will update the post soon! – andreas Sep 18 '19 at 14:43
  • I added some information with a new Stackblitz. Do you know why the getter causes all of this trouble here? Is there a reason or is this even a bug? – andreas Sep 18 '19 at 15:40
  • The issue with your stackblitz example is it throws a CORS error which is why you see the response as false all the time. If you replace the URL with something like https://jsonplaceholder.typicode.com/posts/1 it works just fine. You should add some loggers to your subscription to verify if you are even receiving data. – saNiks Sep 18 '19 at 15:59
  • @saNiks But the bottom buttons are working even with the CORS errors. And with your URL the top buttons are still not working – Fabian Beyerlein Sep 18 '19 at 16:08
  • CORS is not the problem. I just wanted to use a random http request. The problem is with the callback. – andreas Sep 18 '19 at 19:13

1 Answers1

2

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

Fabian Beyerlein
  • 767
  • 1
  • 10
  • 17