I am having an issue that under a specific scenario, I need to click twice in order to trigger the (click) event on a DIV in my Angualar 6 component.
I realize that it would probably be more helpful to provide some example code. But the number of code segments needed to properly convey and the need to sanitize would just be too much to include and I fear too much to digest and may not even prove to be reproducible for anyone anyhow. So I am going to try to describe what I am doing and the things that I have tried so far in hopes that someone might be able to point me in the right direction or give me some additional ideas on what to look for.
My application is a search engine which upon returning and displaying the results also displays a list of facets to further narrow the results by. For example, a facet might include a list of relevant categories with a checkbox next to each one. When a user selects the checkbox the search results are narrowed to only show the results that meat the selected category. The facet lists are only built once with the initial search and remain constant until a brand new search is done. A user can then click on a result item to navigate to a details page showing a finer level of detail about the result item they have selected.
The facets are displayed with the following HTML template snippet:
<div class="facet-spacer-top"></div>
<ng-container *ngIf="facets">
<ng-container *ngFor="let facet of facets; let index = index">
<ng-container *ngIf="facet.isFacetList()">
<facet-list-comp [facet]="facet" [facetIndex]="index" (facetChangeEvent)='onFacetChange($event)'></facet-list-comp>
</ng-container>
<ng-container *ngIf="facet.isFacetDateRange()">
<facet-date-range-comp [facet]="facet" (facetChangeEvent)='onFacetChange($event)'></facet-date-range-comp>
</ng-container>
</ng-container>
</ng-container>
The search results are displayed with the following HTML template snippet:
<div *ngFor="let rowNum of results | rows:3; let idx=index;" class="row result-row no-gutter">
<div *ngFor="let result of results | slice:(idx*3):((idx+1)*3); let jdx=index;" class="col-md-4">
<ng-container *ngComponentOutlet="getResultComponent(); injector: getProvider(result, (idx * 3) + jdx);"></ng-container>
</div>
</div>
The results are added dynamically so that the correct component type for the particular result can be used to display the result. For example our results might include bicycles and cars. The component that we use to display the bicycle result would be different than the component we use to display the car result.
The interesting thing is that this all works wonderfully and when no facet value is selected to pair down the results a single click on a search result item will open the detail as expected. However, if a user selects a facet (such as selecting a category). Then when a user clicks on a resultant result the first time nothing happens. However if the user persists and clicks again, the detail opens as expected. Testing has revealed that if user actually clicks anywhere on the page and then clicks on the result then detail will open as expected. So it is almost like the page needs to regain "focus". It is odd.
So far, I have tried to abandon the Angular (click) event binding for getting a handle DOM HTML element and attaching the event myself. I have tried to programmaticly set the focus to an element on the page after the results have loaded. I have tried to programmaticly click on a DIV element on the page after the search results have loaded. All of these things resulted in the same behavior.
I have attempted to debug, but it is a nightmare trying to step through this Angular and zone.js code!!! I have set break points on the function that gets called in my code when a user clicks on the search result. It is never reached on that first click. Only on the second click. So it seems like this issue is happening somewhere in Angular or maybe zone.js. This might be a red herring, but it does seem like when I try to walk through the code in the debugger that the event is getting lost in zone.js. But I am not for certain.
I know this is not ideal and possibly too abstract, but I am out of ideas. So please any ideas you have would be greatly appreciated!