Ngx-bootstrap: ViewChild not working for ElementRef inside modals.

Created on 19 Feb 2018  路  10Comments  路  Source: valor-software/ngx-bootstrap

Bug description or feature request:

I am trying to access the element reference inside my modal and use it with agm but I can't actually access my element as the reference doesn't exist untill modal is open i.e. ElementRef for anything inside modal is undefined.

html looks like -

<ng-template #addressFormModal>
  <div class="modal-header">
    <button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
      <img src="assets/images/icons/close.svg">
    </button>
    <h4 class="dark-grey-text mb-5 text-center">
      <strong>{{addressFormModalTitle}}</strong>
    </h4>
  </div>
  <div class="modal-body text-center">
    <form [formGroup]="addressForm" (ngSubmit)="addressFormSubmit(addressForm);" novalidate>
      <div class="form-group">
        <label class="popup-label" for="apartment-number">Address</label>
        <input #search type="text" class="form-control" formControlName="address" placeholder="Enter your address" autocorrect="off"
          autocapitalize="off" spellcheck="off" maxlength="100">
        <output *ngIf="addressForm.get('address').hasError('required') && addressForm.get('address').touched">Please enter your address.</output>
      </div>
      <button type="submit" class="btn btn-primary signup-btn" [disabled]="addressForm.invalid">{{addressFormModalAction}}</button>
    </form>
  </div>
</ng-template>

ts looks like -

@ViewChild('search') public searchElement: ElementRef;
this.mapsAPILoader.load().then(
  () => {
    console.log(this.searchElement); // undefined
    const autocomplete = new google.maps.places.Autocomplete(this.searchElement.nativeElement, { types: ['address'] });
    autocomplete.addListener('place_changed', () => {
      this.ngZone.run(() => {
        const place: google.maps.places.PlaceResult = autocomplete.getPlace();
        if (place.geometry === undefined || place.geometry === null) {
          return;
        }
      });
    });
  }
);

Versions of ngx-bootstrap, Angular, and Bootstrap:

ngx-bootstrap:2.0.2

Angular: 4.10

Bootstrap: 3.4

Build system: Angular CLI

can be closed? comp(modal)

Most helpful comment

ViewChild doesn't work because all content of ng-template isn't in DOM. You can use component approach instead of template and get a reference to what you need. Example - https://stackblitz.com/edit/angular-t5dfp7?file=app/service-component.ts

All 10 comments

Issue is similar to this - https://stackoverflow.com/questions/39366981/angular-2-viewchild-in-ngif

But setter approach doesn't work!

ViewChild doesn't work because all content of ng-template isn't in DOM. You can use component approach instead of template and get a reference to what you need. Example - https://stackblitz.com/edit/angular-t5dfp7?file=app/service-component.ts

Interesting, many thanks. :)

Important! in app.module.ts (For ILyaSurmay answer)

`
@NgModule({
declarations: [...],
imports: [
...
],
entryComponents: [ModalContentComponent], //Important!
bootstrap: [...]
})

`

If you just get a black screen.

I am dealing with the same problem but I am unable to find it's solution. Can anyone give me a short example?

Well just do not use ng-template and it will work!
This issue was actually my lack on knowledge of Angular.

ViewChild doesn't work because all content of ng-template isn't in DOM.

I think we can use ViewChildren for this case

I think we can use ViewChildren for this case

How?

I am facing the same issue. Have anyone solved this issue? I am calling a small component inside the modal and I need the reference to it once the modal is open. It is coming undefined.

I think we can use ViewChildren for this case

How?

It was hard to solve this issue even though I've tried not to use ng-template or ng-container.
My solution is also using viewChildren instead of viewChild.

When you use viewChild, I believe, you decide to use one tag.
If then, you can just contact it like below:

[Issue case - viewchild]
@ViewChild('search') public searchElement: ElementRef;
console.log(this.searchElement); // return undefined to me also

[Solution]
@ViewChildren('search') public searchElement: ElementRef;
console.log(this.searchElement.toArray()[0]); // will return properly

Or different solution is, the reason that we encountered this issue is element is not on DOM.
Using hidden instead of ngIf is another solution that I am using.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hugonne picture hugonne  路  3Comments

phmello picture phmello  路  3Comments

haisaco picture haisaco  路  3Comments

MrBlaise picture MrBlaise  路  3Comments

ctrl-brk picture ctrl-brk  路  3Comments