Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@ViewChild always returns undefined

I know this has been asked before, but none of the selected answers are working for me.

I am trying to use @ViewChild to get my ng-select from the dom. And it always returns undefined.

here is the select inside the main.html:

<ng-select id = "user-select" 
     #userSelect 
     [allowClear]="true"
     [items]="singleSignOnUsers"
     [disabled]="disabled"
     placeholder="No user selected">
</ng-select>

here is my component

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

@Component({
    moduleId: module.id,
    selector: 'app-main',
    templateUrl: '../app/main.html',
    providers: [ApiHttpService, UserAdministrationService]
})

export class AppComponent {
    @ViewChild('userSelect') userSelect;


    ngAfterViewInit() {
        alert(this.userSelect);
    }
}

what am i missing here?

Update: Oh My Soul! I figured out why this wasn't working when it should.

I have the whole view wrapped in a div with an ngSwitch. If I move it out I can access them.

Now I don't know how to access them while in the ngSwitch however. But I don't have to use the ngSwitch.

<div [ngSwitch]='loading'>
        <div *ngSwitchCase="false">
            ...
            <ng-select id="user-select"
                       #userSelect
                       [allowClear]="true"
                       [items]="singleSignOnUsers"
                       [disabled]="disabled"
                       placeholder="No city selected">
            </ng-select>
            ...
        </div>
    <div
like image 660
twaldron Avatar asked Nov 04 '16 16:11

twaldron


People also ask

Why is my ViewChild undefined?

The problem can be caused by the *ngIf or other directive. The solution is to use the @ViewChildren instead of @ViewChild and subscribe the changes subscription that is executed when the component is ready. For example, if in the parent component ParentComponent you want to access the child component MyComponent .

What does ViewChild return?

ViewChild returns the first matching element and ViewChildren returns all the matching elements as a QueryList of items. We can use these references to manipulate element properties in the component.

Why do we use @ViewChild in angular2?

Conclusion. 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.

What is the difference between @ViewChild and @input?

While Angular inputs/outputs should be used when sharing data to and from child components, ViewChild should be used when trying to utilize properties and methods of the child component directly in the parent component.


1 Answers

@twaldron Are you using some delayed data loading in ngOnInit?

Because in that case, in my experience, reading a @ViewChild as a ElementRef produces no results

If your component has the data already resolved (like the case when a parent passes a child data object to a sub component) it should work (at least for me it did).

In the case of asynchronous data loading, the way I was able to make it work is using a change notification

 @ViewChildren('userSelect') userSelect: QueryList<ElementRef>;

 ngAfterViewInit(): void {
    this.userSelect.changes.subscribe(item => {
        if (this.userSelect.length) {
            alert(this.userSelect.first.nativeElment.outerHTML)
        }
    })
 }
like image 164
Florin D Avatar answered Sep 28 '22 07:09

Florin D