3

I am trying to create an image slider in Angular2 as shown below.

<nstr-slider>
    <nstr-slide src="image-1.jpg">Slide Caption #1</slide>
    <nstr-slide src="image-2.jpg">Slide Caption #2</slide>
</nstr-slider>

In my slider component, I would like to be able to get the height of each slide, so I am using @ContentChildren to get the list of slides within the slider and have also imported ElementRef to slide component in order to have access to nativeElement properties.

In ngAfterViewInit() function I am able to successfully console.log(slide.el), which shows me two ElementRef objects. When I manually click though it all the way to the properties, I am seeing that clientHeight is 303 px (view console output).

Now comes the weird part...When I console.log(slide.el.nativeElement.clientHeight), all of a sudden, I am seeing a different and totally incorrect number (view console output). For the life of me, I am not able to figure out why this would be the case and how one would go about accessing the correct height value.

slider.component.ts

import { Component, OnInit, ContentChildren, QueryList, AfterViewInit} from '@angular/core';
import { SlideComponent } from './slide/slide.component';

@Component({
    selector: 'nstr-slider',
    templateUrl: './slider.component.html',
    styleUrls: ['./slider.component.scss']
})
export class SliderComponent implements AfterViewInit{

    @ContentChildren(SlideComponent) slidesList: QueryList<SlideComponent>;
    slides: Array<any>;

    constructor() {}

    ngAfterViewInit(){
        this.slides = this.slidesList.toArray();

        for( let slide of this.slides){

            // This shows correct height
            console.log(slide.el);

            // This does not
            console.log(slide.el.nativeElement.clientHeight)

        }
    }

}

slide.component.ts

import { Component, ElementRef } from '@angular/core';

@Component({
    selector: 'nstr-slide',
    templateUrl: './slide.component.html',
    styleUrls: ['./slide.component.scss']
})
export class SlideComponent {

    constructor( private el: ElementRef ) { }

}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Mia
  • 31
  • 2
  • `console.log` shows deep mutable objects at the last state of execution, not at the state when console.log was called. You need to wait till images is completely loaded. Take a look at `load` event for image – yurzui Feb 02 '17 at 07:19
  • @yurzui this makes perfect sense. I actually ended up coming up with the exact solution that you suggested right after posting the question, but it is super helpful to know why logging console behaves the way it does! – Mia Feb 02 '17 at 19:04

1 Answers1

2

If you want to access DOM element properties, you can't use queried components.

Use the read parameter to tell the query what to return:

@ContentChildren(SlideComponent, {read: ElementRef}) slidesList: QueryList<ElementRef>;

See also angular 2 / typescript : get hold of an element in the template

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 2
    Thank you taking your time to reply. The issue actually had to do with slide component taking it's time to load an image inside it, as @yurzuui has suggested. I was able to access all other DOM properties with the setup I had, except for element height. Creating an observable inside image onload event within SlideComponent, and then subscribing to it in SliderComponent did the trick. – Mia Feb 02 '17 at 19:11
  • Great. Thanks for the feedback! – Günter Zöchbauer Feb 02 '17 at 19:12