Outputs initialized after inputs which leads to missed events triggered synchronously from constructors/setters
Hi,
I created a little POC with ng-dynamic-component. I have a TicketDetailComponent which fetches some data and outputs it internal loading state by an event emitter. I can clearly see it emitting the correct loading state in line 34 of TicketDetailComponent. In DashboardCardComponent I dynanmically add outputs to this dynamically instantiated component. However, the loading function (line 26) in DashboardCardComponent is only called once. What could be the cause for this unexpected behaviour?
https://stackblitz.com/github/pelssersconsultancy/dashboard
Hey, thanks for providing reproduction repo - it was very useful to debug the issue!
I have found the problem and it lays down in a way you process input changes or rather using a setter instead of a OnChanges lifecycle hook =)
The reason setters don't work in your case is that inputs are set on dynamic components before the outputs are subscribed and if you know observables will miss any events that happened before the subscription, and since you are setting the id in the setter which triggers the loading state change the output will miss this first event and only work on the subsequent events.
So to fix your issue you could either use OnChanges hook to set the id as this will delay the event until after outputs were processed or you can add a timeout when setting id (I've added the timeout just to check and it fixed the issue).
I would recommend/prefer to always use OnChanges hook as it is semantically cleaner and also it always guarantees that all initialization logic of your constructors/props is executed but you are free to do as you please 😊
With regards to this issue I believe we could reverse the order of processing first outputs and then inputs to make it consistent with what seems like Angular is doing under the hood but to be hones I would rather not rely on the order of what is processed first/last...
What do you think?
I'm closing this issue as it's outdated and no fix is planned for it. If you want to reopen the discussion please feel free to open a new issue.