title: Angular12 - Use @HostBinding or @HostListener rather than the `host` metadata property
body: <p>I'm using Angular 12 with ESLint and ESLint prints out the following error:</p>
  <blockquote>
  <p>70:3   error  Use @HostBinding or @HostListener rather than the <code>host</code> metadata property (<a href="https://angular.io/styleguide#style-06-03" rel="nofollow noreferrer">https://angular.io/styleguide#style-06-03</a>)  @angular-eslint/no-host-metadata-property</p>
  </blockquote>
  <p>There are lots of similar topics, like <a href="https://stackoverflow.com/questions/37965647/hostbinding-and-hostlistener-what-do-they-do-and-what-are-they-for">this one</a>, but my host is more complicated.</p>
  <pre><code>  host: {
      '[class.active-menuitem]':
        '(selectedKey &amp;&amp; app.isHorizontal()) || (active &amp;&amp; !app.isHorizontal()) ' +
        '|| (active &amp;&amp; !root &amp;&amp; app.isHorizontal())',
      '[class.active-rootmenuitem]': 'active &amp;&amp; root &amp;&amp; app.isHorizontal()'
    },
  </code></pre>
  <p>What am I supposed to make it to? Something like:</p>
  <pre><code>@HostBinding('[class.active-menuitem]') menuItem = '(selectedKey &amp;&amp; app.isHorizontal()) || (active &amp;&amp; !app.isHorizontal()) ' + '|| (active &amp;&amp; !root &amp;&amp; app.isHorizontal())'; 
  </code></pre>
  <p>?</p>
  <h3 id="complete-snippet-edjk">Complete Snippet:</h3>
  <pre><code>import { Component, Input, OnInit, ChangeDetectorRef, OnDestroy } from '@angular/core';
  import { Router, NavigationEnd } from '@angular/router';
  import { trigger, state, style, transition, animate } from '@angular/animations';
  import { Subscription } from 'rxjs';
  import { filter } from 'rxjs/operators';
  import { LayoutComponent } from '../layout.component';
  import { MenuService } from '@core/services';
  
  @Component({
    selector: '[app-menu-item]',
    template: `
      &lt;ng-container&gt;
        &lt;a
          [attr.href]=&quot;item.url&quot;
          (click)=&quot;itemClick($event)&quot;
          *ngIf=&quot;!item.routerLink || item.items&quot;
          pRipple
          [ngClass]=&quot;item.class&quot;
          (mouseenter)=&quot;onMouseEnter()&quot;
          (keydown.enter)=&quot;itemClick($event)&quot;
          [attr.target]=&quot;item.target&quot;
          [attr.tabindex]=&quot;0&quot;
        &gt;
          &lt;i [ngClass]=&quot;item.icon&quot; class=&quot;layout-menuitem-icon&quot;&gt;&lt;/i&gt;
          &lt;span class=&quot;layout-menuitem-text&quot;&gt;{{ item.label }}&lt;/span&gt;
          &lt;i class=&quot;pi pi-fw pi-angle-down layout-submenu-toggler&quot; *ngIf=&quot;item.items&quot;&gt;&lt;/i&gt;
        &lt;/a&gt;
        &lt;a
          (click)=&quot;itemClick($event)&quot;
          (mouseenter)=&quot;onMouseEnter()&quot;
          *ngIf=&quot;item.routerLink &amp;&amp; !item.items&quot;
          pRipple
          [ngClass]=&quot;item.class&quot;
          [routerLink]=&quot;item.routerLink&quot;
          routerLinkActive=&quot;active-menuitem-routerlink&quot;
          [routerLinkActiveOptions]=&quot;{ exact: true }&quot;
          [attr.target]=&quot;item.target&quot;
          [attr.tabindex]=&quot;0&quot;
        &gt;
          &lt;i [ngClass]=&quot;item.icon&quot; class=&quot;layout-menuitem-icon&quot;&gt;&lt;/i&gt;
          &lt;span class=&quot;layout-menuitem-text&quot;&gt;{{ item.label }}&lt;/span&gt;
          &lt;i class=&quot;pi pi-fw pi-angle-down layout-submenu-toggler&quot; *ngIf=&quot;item.items&quot;&gt;&lt;/i&gt;
        &lt;/a&gt;
        &lt;ul
          *ngIf=&quot;item.items &amp;&amp; (active || animating || selectedKey)&quot;
          (@children.done)=&quot;onAnimationDone()&quot;
          [ngStyle]=&quot;{ padding: active &amp;&amp; root ? '' : '0' }&quot;
          [@children]=&quot;
            app.isHorizontal() &amp;&amp; root &amp;&amp; !app.isMobile()
              ? active
                ? 'visible'
                : 'hidden'
              : active
              ? 'visibleAnimated'
              : 'hiddenAnimated'
          &quot;
        &gt;
          &lt;ng-template ngFor let-child let-i=&quot;index&quot; [ngForOf]=&quot;item.items&quot;&gt;
            &lt;li
              app-menu-item
              [item]=&quot;child&quot;
              [index]=&quot;i&quot;
              [parentKey]=&quot;key&quot;
              [class]=&quot;child.badgeClass&quot;
            &gt;&lt;/li&gt;
          &lt;/ng-template&gt;
        &lt;/ul&gt;
      &lt;/ng-container&gt;
    `,
    host: {
      '[class.active-menuitem]':
        '(selectedKey &amp;&amp; app.isHorizontal()) || (active &amp;&amp; !app.isHorizontal()) ' +
        '|| (active &amp;&amp; !root &amp;&amp; app.isHorizontal())',
      '[class.active-rootmenuitem]': 'active &amp;&amp; root &amp;&amp; app.isHorizontal()'
    },
    animations: [
      trigger('children', [
        state(
          'void',
          style({
            height: '0px'
          })
        ),
        state(
          'hiddenAnimated',
          style({
            height: '0px'
          })
        ),
        state(
          'visibleAnimated',
          style({
            height: '*'
          })
        ),
        state(
          'visible',
          style({
            height: '*',
            'z-index': 999
          })
        ),
        state(
          'hidden',
          style({
            height: '0px',
            'z-index': '*'
          })
        ),
        transition(
          'visibleAnimated =&gt; hiddenAnimated',
          animate('400ms cubic-bezier(0.86, 0, 0.07, 1)')
        ),
        transition(
          'hiddenAnimated =&gt; visibleAnimated',
          animate('400ms cubic-bezier(0.86, 0, 0.07, 1)')
        ),
        transition(
          'void =&gt; visibleAnimated, visibleAnimated =&gt; void',
          animate('400ms cubic-bezier(0.86, 0, 0.07, 1)')
        )
      ])
    ]
  })
  export class MenuItemComponent implements OnInit, OnDestroy {
    @Input() item: any;
    @Input() index: number;
    @Input() root: boolean;
    @Input() parentKey: string;
  
    animating: boolean;
    active = false;
    menuSourceSubscription: Subscription;
    menuResetSubscription: Subscription;
  
    key: string;
  
    selectedKey: boolean;
  
    constructor(
      public app: LayoutComponent,
      public router: Router,
      private cd: ChangeDetectorRef,
      private menuService: MenuService
    ) {
      this.menuSourceSubscription = this.menuService.menuSource$.subscribe((key) =&gt; {
        // deactivate current active menu
        if (this.active &amp;&amp; this.key !== key &amp;&amp; key.indexOf(this.key) !== 0) {
          this.active = false;
        }
      });
  
      this.menuResetSubscription = this.menuService.resetSource$.subscribe(() =&gt; {
        this.active = false;
      });
  
      this.router.events
        .pipe(filter((event) =&gt; event instanceof NavigationEnd))
        .subscribe((params) =&gt; {
          if (this.app.isHorizontal() &amp;&amp; this.item.routerLink) {
            this.active = false;
            this.selectedKey = this.router.isActive(
              this.item.routerLink[0],
              this.item.items ? false : true
            );
          } else {
            if (this.item.routerLink) {
              this.updateActiveStateFromRoute();
            } else {
              this.active = false;
            }
          }
        });
    }
  
    ngOnInit() {
      if (!this.app.isHorizontal() &amp;&amp; this.item.routerLink) {
        this.updateActiveStateFromRoute();
      }
  
      if (this.app.isHorizontal() &amp;&amp; this.item.routerLink) {
        this.active = false;
        this.selectedKey = this.router.isActive(
          this.item.routerLink[0],
          this.item.items ? false : true
        );
      }
  
      this.key = this.parentKey ? this.parentKey + '-' + this.index : String(this.index);
    }
  
    updateActiveStateFromRoute() {
      this.active = this.router.isActive(this.item.routerLink[0], this.item.items ? false : true);
    }
  
    itemClick(event: Event) {
      // avoid processing disabled items
      if (this.item.disabled) {
        event.preventDefault();
        return;
      }
  
      // navigate with hover in horizontal mode
      if (this.root) {
        this.app.menuHoverActive = !this.app.menuHoverActive;
      }
  
      // notify other items
      this.menuService.onMenuStateChange(this.key);
  
      // execute command
      if (this.item.command) {
        this.item.command({ originalEvent: event, item: this.item });
      }
  
      // toggle active state
      if (this.item.items) {
        this.active = !this.active;
        this.animating = true;
      } else {
        // activate item
        this.active = true;
  
        // reset horizontal menu
        if (this.app.isHorizontal()) {
          this.menuService.reset();
        }
  
        this.app.overlayMenuActive = false;
        this.app.overlayMenuMobileActive = false;
        this.app.menuHoverActive = !this.app.menuHoverActive;
      }
    }
  
    onMouseEnter() {
      // activate item on hover
      if (this.root &amp;&amp; this.app.menuHoverActive &amp;&amp; this.app.isHorizontal() &amp;&amp; this.app.isDesktop()) {
        this.menuService.onMenuStateChange(this.key);
        this.active = true;
      }
    }
  
    onAnimationDone() {
      this.animating = false;
    }
  
    ngOnDestroy() {
      if (this.menuSourceSubscription) {
        this.menuSourceSubscription.unsubscribe();
      }
  
      if (this.menuResetSubscription) {
        this.menuResetSubscription.unsubscribe();
      }
    }
  }
  
  </code></pre>