Villux-NV
Villux-NV

Reputation: 33

TS - Argument of type '(x: HTMLElement) => void' is not assignable to parameter

Hello and thanks in advance for any help!

Working with my first Angular page and was working through a tutorial to get my mat-cards to all be the same height dynamically for size changes. Having the error pop up on my forEach((x: HTMLElement) => ... Please see code below.

TS:
import { Directive, ElementRef, AfterViewChecked, Input, HostListener } from '@angular/core';

@Directive({
  selector: '[myMatchHeight]'
})

export class MatchHeightDirective implements AfterViewChecked {
  // Class name to match height
  @Input()
  myMatchHeight: any;

  constructor(private el: ElementRef) {

  }

  ngAfterViewChecked() {
    // Call our matchHeight function here
    this.matchHeight(this.el.nativeElement, this.myMatchHeight);
  }

  @HostListener('window:resize')
  onResize() {
    // Call our matchHeight function
    this.matchHeight(this.el.nativeElement, this.myMatchHeight);
  }

  matchHeight(parent: HTMLElement, className: string) {
    // Match height logic here
    if (!parent) return;

    const children = parent.getElementsByClassName(className);

    if (!children) return;

    // Reset children height
    Array.from(children).forEach((x: HTMLElement) => {
      x.style.height = 'auto';
    });

    // Get all child el heights
    const itemHeights = Array.from(children).map(x => x.getBoundingClientRect().height);


    // Find max height
    const maxHeight = itemHeights.reduce((prev, curr) => {
      return curr > prev ? curr : prev;
    }, 0);

    // Apply max height
    Array.from(children).forEach((x: HTMLElement) => {
      x.style.height = `${maxHeight}px`;
    });
  }
}

HTML:
<div class="cards-container">
        <div myMatchHeight="mat-card" fxLayout="row wrap" fxLayoutGap="16px grid" fxLayoutAlign="center stretch">
          <div fxFlex="500px" fxFlex.xs="85%" fxFlex.md="40%">
            <mat-card fxLayout="column" fxLayoutAlign="space-between center">
              <mat-card-header>
                <mat-card-title>First M. Last</mat-card-title>
              </mat-card-header>

              <div class="image-container" fxLayoutAlign="center">
                <img src="../../assets/images/image1.jpg" />
              </div>

              <mat-card-content>
                <p>
                  I'm baby seitan tilde vape, farm-to-table in enamel pin forage reprehenderit. Retro sunt VHS
                  fingerstache, cray aliquip activated charcoal you probably haven't heard of them actually brooklyn
                  banjo labore vinyl four loko. Velit poke cupidatat pour-over nisi adipisicing master cleanse sriracha
                  lo-fi prism. Austin adipisicing duis mlkshk, occaecat hot chicken wayfarers disrupt pabst dolore
                  cold-pressed next level trust fund snackwave.
                </p>
              </mat-card-content>
            </mat-card>
          </div>

          <div fxFlex="500px" fxFlex.xs="85%" fxFlex.md="40%">
            <mat-card fxLayout="column" fxLayoutAlign="space-between center">
              <mat-card-header>
                <mat-card-title>First M. Last</mat-card-title>
              </mat-card-header>

              <div class="image-container" fxLayoutAlign="center">
                <img src="../../assets/images/image2.jpg" />
              </div>

              <mat-card-content>
                <p>
                  Hammock scenester veniam eiusmod truffaut mixtape, raw denim aesthetic. Mlkshk franzen cornhole
                  flannel. Letterpress bitters deserunt ut in ad dolor tumeric. Prism meggings brooklyn chillwave,
                  mixtape readymade salvia enamel pin fam fingerstache voluptate in man braid.
                </p>
              </mat-card-content>
            </mat-card>
          </div>
        </div>
      </div>


Error:
error TS2345: Argument of type '(x: HTMLElement) => void' is not assignable to parameter of type '(value: Element, index: number, array: Element[]) => void'.
      Types of parameters 'x' and 'value' are incompatible.
        Type 'Element' is not assignable to type 'HTMLElement'.

      Array.from(children).forEach((x: HTMLElement) => {

Please let me know if more info is needed. Again, thank you for any support!

Upvotes: 3

Views: 2121

Answers (1)

maidi
maidi

Reputation: 3489

document.getElementsByClassName returns a HTMLCollection of Element objects.

Have you tried using Element as type instead of HTMLElement?

Array.from(children).forEach((x: Element) => { 
   if (x instanceof HTMLElement) {
     x.style.height = 'auto';
   }
});

An Alternative could be to use querySelector:

const children = parent.querySelector(`.${className}`) as HTMLElement;

if (!children) return;

Array.from(children).forEach((x: HTMLElement) => {
  x.style.height = 'auto';
});

Upvotes: 4

Related Questions