Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get nativeElement from @ViewChild in Ionic 4/Angular7?

I am using Ionic 4's ion-search like so:

     <ion-searchbar
            #searchbarElem
            (ionInput)="getItems($event)"
            (tap)="handleTap($event)"
            [(ngModel)]="keyword"
            (ngModelChange)="updateModel()"
            [cancelButtonText]="options.cancelButtonText == null ? defaultOpts.cancelButtonText : options.cancelButtonText"
            [showCancelButton]="options.showCancelButton == null ? defaultOpts.showCancelButton : options.showCancelButton"
            [debounce]="options.debounce == null ? defaultOpts.debounce : options.debounce"
            [placeholder]="options.placeholder == null ? defaultOpts.placeholder : options.placeholder"
            [autocomplete]="options.autocomplete == null ? defaultOpts.autocomplete : options.autocomplete"
            [autocorrect]="options.autocorrect == null ? defaultOpts.autocorrect : options.autocorrect"
            [spellcheck]="options.spellcheck == null ? defaultOpts.spellcheck : options.spellcheck"
            [type]="options.type == null ? defaultOpts.type : options.type"
            [disabled]="disabled"
            [ngClass]="{'hidden': useIonInput}"
            (ionClear)="clearValue(true)"
            (ionFocus)="onFocus()"
            (ionBlur)="onBlur()"
    >
    </ion-searchbar>

On click I run the following from within the component:

@HostListener('document:click', ['$event'])
private documentClickHandler(event) {
    if ((this.searchbarElem
            && !this.searchbarElem._elementRef.nativeElement.contains(event.target))
        ||
        (!this.inputElem && this.inputElem._elementRef.nativeElement.contains(event.target))
    ) {
        this.hideItemList();
    }
}

However, I am getting the following error:

ERROR TypeError: Cannot read property 'nativeElement' of undefined

I have tried setting timeouts and declaring searchbarElem as ElementRef with no luck.

I know this worked in Angular 2/Ionic 2 but now it is not. Did something change or is the shadow dom affecting thing? Any help would be appreciated, thanks.

like image 853
Jeremy Avatar asked Nov 15 '18 16:11

Jeremy


People also ask

Why do we use @ViewChild in angular2?

The @ViewChild decorator allows us to inject into a component class references to elements used inside its template, that's what we should use it for. Using @ViewChild we can easily inject components, directives or plain DOM elements.

How do I use ElementRef in Angular 4?

To manipulate the DOM using the ElementRef , we need to get the reference to the DOM element in the component/directive. Create a template reference variable for the element in the component/directive. Use the template variable to inject the element into component class using the ViewChild or ViewChildren.

What is @ViewChild Angular?

ViewChildlink Property decorator that configures a view query. The change detector looks for the first element or the directive matching the selector in the view DOM. If the view DOM changes, and a new child matches the selector, the property is updated.


1 Answers

You should use ViewChild with the read: ElementRef metadata property:

@ViewChild("searchbarElem", { read: ElementRef }) private searchbarElem: ElementRef;

and access the HTMLElement with this.searchbarElem.nativeElement:

@HostListener('document:click', ['$event'])
private documentClickHandler(event) {
    console.log(this.searchbarElem.nativeElement);
}

See this stackblitz for a demo (see the code in the Home page).

like image 65
ConnorsFan Avatar answered Sep 19 '22 03:09

ConnorsFan