I'm trying to implement a modal in my app by following the guide (the portion using ng-template) below
Thing is, I'm getting an error in the console whenever I try to click on the button to open the modal: "this.vc.insert is not a function". I've read that we should use the ngAfterViewInit hook, but I'm not sure how to apply it as I only want the modal to show when the user clicks the button and not when ngAfterViewInit fires.
Below are some code snippets
.ts file
import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core';
@Component({
selector: 'app-browse-food',
templateUrl: './browse-food.component.html',
styleUrls: ['./browse-food.component.css']
})
export class BrowseFoodComponent implements OnInit {
constructor() {
}
ngOnInit() {
// unrelated code
}
@ViewChild('orderModal') orderModal: TemplateRef<any>;
@ViewChild('vc') vc: ViewContainerRef;
openModal() {
let view = this.orderModal.createEmbeddedView(null);
this.vc.insert(view);
}
closeModal() {
this.vc.clear();
}
html
<button (click)="openModal()">Open Modal</button>
<ng-container #vc></ng-container>
<ng-template #orderModal>
<div class="modal">
<div class="modal-content">
<div class="modal-header">
<i (click)="closeModal()"></i>
</div>
<div class="modal-body">
</div>
</div>
</div>
</ng-template>
Any help is appreciated, TIA :)
Changing @ViewChild('vc') vc: ViewContainerRef;
to @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
gets it to work.
Using @ViewChild('vc') vc: ViewContainerRef;
makes this.vc
an ElementRef
, not a ViewContainerRef
as expected. Consequently the ElementRef
this.vc
has no method named insert
.
Using @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
, Angular explicitly gives you the ViewContainerRef
associated with the #vc
local reference. Here's a small and fuller explanation.