Search code examples
angularoverlayangular-directive

Angular: error on cdk overlay when used with *ngIf


I try to add a contextual menu to a button, I implemented the very simple example from the angular material documentation and it works well:

my-component.html

<button 
    type="button" cdkOverlayOrigin #trigger="cdkOverlayOrigin"
    (click)="isOpen = !isOpen">
    Menu 
</button>

<ng-template
  cdkConnectedOverlay
  [cdkConnectedOverlayOrigin]="trigger"
  [cdkConnectedOverlayOpen]="isOpen">
  <ul class="example-list">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
</ng-template>

This works very well but then I have a more complex button: actually, the trigger button is displayed or not with the *ngIf directive.

<button *ngIf="accessMenu"
    type="button" cdkOverlayOrigin #trigger="cdkOverlayOrigin"
    (click)="isOpen = !isOpen">
    Menu
</button>

When I add this directive, I have an error at compilation:

Property 'trigger' does not exist on type 'myComponent'. Line 79 [cdkConnectedOverlayOrigin]="trigger"

I tried to set the directive out of the button by wrapping the button by an ng-container and adding the directive to the ng-container but it's the same.

Do you know why adding this structural directive make my compilation fail? And how should I do this? Thanks


Solution

  • The solution is simply to wrap the trigger button WITH the ng-template of the overlay in the ng-container, and not the ng-template alone:

    <ng-container *ngIf="accessMenu">
    
      <button mat-mini-fab
        type="button" cdkOverlayOrigin #trigger="cdkOverlayOrigin"
        (click)="isOpen = !isOpen">
        Menu
      </button>
    
      <ng-template
        cdkConnectedOverlay
        [cdkConnectedOverlayOrigin]="trigger"
        [cdkConnectedOverlayOpen]="isOpen">
        <ul class="example-list">
          <li>Item 1</li>
          <li>Item 2</li>
          <li>Item 3</li>
        </ul>
      </ng-template>
    
    </ng-container>