Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My template reference variable .nativeElement is undefined

this.child02.nativeElement is undefined and I can't figure out why. What am I doing wrong? Thank you. Here is my current stackblitz.

app.component.ts:

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

switchDirection = true;
head: ElementRef;

@ViewChild('child02') child02: ElementRef;

  onScroll(event: Event) {
    console.log("viewBoundaryL:" + (event.target as HTMLElement).scrollLeft);
    if((event.target as HTMLElement).scrollLeft >= 50 && this.switchDirection === true){
  console.log("nativeElement:" + this.child02.nativeElement)
  console.log(this.child02)
  console.log('snap')
this.child02.nativeElement.scrollIntoView({ behavior: 'smooth' });
  this.switchDirection = false;
    }
  }
}

app.component.html:

Keep an eye on the console while scrolling...
<div class="container"  (scroll)="onScroll($event)" >

<child1></child1>
<child2 #child02></child2>
<child3></child3>

</div>

Context: I am trying to make a snap-to-component-directive, similar to this functionality (open in firefox). Here is my current stackblitz. My question is how would you build this? Trying not to use a singleton.

There are so many ways to do this but heres one: When the user scrolls horizontally from one component to another component so that it comes into view fifty pixels or more past the child component boundary, the component will scrollIntoView(). Would need a switchDirection variable so that once the snap happens its not operating on the same positioning logic. And again I want to put this into directive(s).

Pseudocode for the above logic used for snapping between child 1 and child2 (see stackblitz console for context):

//snap from child1 to child2
    If (viewBoundary >= child1L + 50px && switchDirection === true){
child2.scrollIntoView();
switchDirection = false;
debounceTime(250);
}
//snap from child2 to child1
else if(viewBoundary <= child1R - 50px && switchDirection === false){
child1.scrollIntoView();
switchDirection = true;
debounceTime(250);
}

Thanks for your insights!

like image 421
imnickvaughn Avatar asked Jul 05 '18 13:07

imnickvaughn


2 Answers

Update @ViewChild declaration to:

@ViewChild('child02',{read: ElementRef}) child02: ElementRef;

Keep everything else same.

Example

like image 174
Shantanu Avatar answered Oct 13 '22 00:10

Shantanu


You need to access the element using el like below. This is due to the fact that you have defined #child02 on the custom component which is not a native element and hence you need to access it via el.

this.child02.el.nativeElement.scrollIntoView({ behavior: 'smooth' });

I have verified and there are no more console errors.

https://stackblitz.com/edit/angular-horizontalscrollsetup-logging2-e7b9jy?file=app/app.component.ts


However, use the property # as last resort as it results in tight coupling in your application.

You may refer the below link to know more.

https://angular.io/api/core/ElementRef

like image 20
Ankit Sharma Avatar answered Oct 13 '22 01:10

Ankit Sharma