Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On console.log, ViewChild variable is undefined in unit test

I'm trying to test a component that has an @ViewChild annotation. One of the functions that I'm trying to test calls the @ViewChild's element for focus. However, when I try to log out the @ViewChild variable, it is always undefined. I thought componentFixture.detectChanges() would initiate the ElementRef, but it doesn't seem to.

Is there any way to make it so it isn't undefined?

like image 912
tallkid24 Avatar asked Apr 06 '16 00:04

tallkid24


People also ask

Why is ViewChild undefined in Angularjs?

So, when the component is initialized the component is not yet displayed until "showMe" is true. Thus, my @ViewChild references were all undefined. This is where I used @ViewChildren and the QueryList that it returns. See angular article on QueryList and a @ViewChildren usage demo.

What does ViewChild return?

Another critical difference is that @ViewChild returns a single native DOM element as a reference, while the @ViewChildren decorator returns the list of different native DOM elements in the form of QueryList , which contains the set of elements.

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.


2 Answers

You didn't show your code but, probably u have that undefined because you did your ViewChild like: @ViewChild(MySubComponent) instead of

@ViewChild('componentref')

and then in your template:

<my-sub-component #componentref></my-sub-component>

and of course you need to init your component with componentFixture.detectChanges()

like image 66
PaTT Avatar answered Sep 29 '22 13:09

PaTT


I don't know which version of Angular2 you use and how you initialize your test suite but the detectChanges method on the ComponentFixture instance is responsible to set such fields.

Here is a sample test that shows this:

it('should set testElt', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
    return tcb.createAsync(MyList).then((componentFixture: ComponentFixture) => {
      expect(componentFixture.componentInstance.testElt).toBeUndefined();

      componentFixture.detectChanges();

      expect(componentFixture.componentInstance.testElt).toBeDefined();
      var testElt = componentFixture.componentInstance.testElt;
      expect(testElt.nativeElement.textContent).toEqual('Some test');
    });
}));

See the corresponding plunkr: https://plnkr.co/edit/THMBXX?p=preview.

like image 22
Thierry Templier Avatar answered Sep 29 '22 13:09

Thierry Templier