Reputation: 33
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
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