Search code examples
angularangular-cliangular-directiveng-build

Angular attribute directive - error on prod build expected 1 arguments but got 0


I am working on a large app, developed by multiple teams over a period of time.

A frontend developer from a different location added a lot of repetitive imperative code, with dom manipulation using jquery everywhere in the app (in every component), to solve accessibility issues.

I am trying to clean up that code. I moved some code into a directive (for eg:- to outline an element when it's focused by keyboard, or remove outline when blurred)

Here is my directive.

import { Directive, HostListener, ElementRef, OnInit, Input, AfterViewInit } from '@angular/core';
import { AccessibilityService } from 'src/app/services/accessibility.service';

@Directive({
  selector: '[keyboardFocus]'
})
export class KeyboardFocusDirective implements OnInit, AfterViewInit {

  @Input('outlineOnFocusFor') outlineFor: 'self'|'parent'|'none'|null|undefined;

  private readonly outlineStyleOnFocus = '1px solid black';
  private tabindexChange: boolean;
  private elemToOutine: any;

  constructor(private el: ElementRef, private accessibilityService: AccessibilityService) { }

  ngOnInit() {
    this.accessibilityService.currentTabindexChange.subscribe((tabindexChange: boolean) => {
      this.tabindexChange = tabindexChange;

      if (this.el && this.el.nativeElement) {
        this.el.nativeElement.tabIndex = this.tabindexChange ? -1 : 0;
      }
    });
  }

  ngAfterViewInit() {
    switch (this.outlineFor) {
      case 'parent':
        this.elemToOutine = this.el.nativeElement.parentElement;
        break;
      case 'none':
        this.elemToOutine = null;
        break;
      case 'self':
      case null:
      case undefined:
      default:
        this.elemToOutine = this.el.nativeElement;
        break;
    }
  }

  @HostListener('keyup.tab', ['$event']) 
  @HostListener('keyup.shift.tab') 
  onKeyboardTabFocus(event: KeyboardEvent) {
    if (!this.elemToOutine)
      return;

    this.elemToOutine.style.outline = this.outlineStyleOnFocus;
    event.stopImmediatePropagation();
  }

  @HostListener('blur', ['$event'])
  onKeyboardBlur(event: KeyboardEvent) {    
    if (!this.elemToOutine)
      return;

    this.elemToOutine.style.outline = '';
    event.stopImmediatePropagation();
  }
}

Here is how I use it in an imaginary component.

<div class="something">
  <section class="something-else" keyboardFocus outlineOnFocusFor="parent">some content 1</section>
  <section class="something-else-2" keyboardFocus>some content 2</section>
  <section class="something-else-3" keyboardFocus outlineOnFocusFor="none">some content 3</section>
</div>

This seems to work fine in dev build. However CLI build with --prod flag gives error like this:

ERROR in src/app/features/enrollments/ate-requests/ate-requests.component.html(73,17): : Directive KeyboardFocusDirective, Expected 1 arguments, but got 0. src/app/features/enrollments/ate-requests/ate-requests.component.html(141,17): : Directive KeyboardFocusDirective, Expected 1 arguments, but got 0. src/app/features/enrollments/ate-requests/ate-requests.component.html(156,23): : Directive KeyboardFocusDirective, Expected 1 arguments, but got 0.

The same error, from all the places the directive is used. I couldn't figure out what the missing argument could be. Any suggestions would be appreciated. Thank you :)


Solution

  • Found it. So damn silly.. Thanks all for your time and suggestions :o)

    The missing argument $event in the decorator

    @HostListener('keyup.shift.tab'). 
    

    It should be

    @HostListener('keyup.shift.tab', ['$event'])