I'm learning Angular, so forgive me if my terminology isn't quite accurate. I've provided a full version output at the bottom of this post.
This is what I have right now, and it successfully triggers a hard-coded modal. But what I want is for the modal to be an empty vessel such that I can click multiple icons, and the parent component will send the appropriate data object to the modal before it displays.
request-membership.component.html
<ng-container>
...
<span (click)="toggleModal('itemOne')">Icon</div>
...
</ng-container>
<app-modal
#contentModal
*ngIf="showModal"
title="This is the title"
(canceled)="showModal = false">
Show the content to the user.
</app-modal>
request-membership.component.ts
...
@Component({
selector: 'app-request-membership',
templateUrl: './request-membership.component.html',
styleUrls: ['./request-membership.component.scss']
})
export class RequestMembershipComponent implements OnInit {
constructor(...) { }
showModal = false;
data = {
itemOne: {
title: 'This is the title for item one',
content: 'This is the title for item one'
},
itemTwo: {
title: 'This is the title for item one',
content: 'This is the title for item one'
},
};
ngOnInit() {...}
toggleModal(element: string) {
this.showModal = true;
}
}
content-modal.component.ts
...
@Component({
selector: 'app-modal',
templateUrl: './content-modal.component.html',
styleUrls: ['./content-modal.component.scss']
})
export class AppModalComponent {
@Input() title: string;
@Input() bulkContent;
@Output() canceled = new EventEmitter();
cancel_click() {
this.canceled.emit({ canceled: true });
}
}
I've read dozens of SO and blog posts about this topic. Most of them recommend the use of the ViewChild decorator to get a reference to the modal, then I can pump data into it. Something like this is what I might expect.
request-membership.component.ts
@ViewChild('contentModal') contentModal: ElementRef;
// then within the toggleModal method
this.contentModal.title = this.data[element].title
this.contentModal.content = this.data[element].content
But when I drop a debugger statement in the toggleModal method I always get undefined when I try to reference this.contentModal
.
I've tried referencing contentModal as the specific type of component:
@ViewChild('contentModal') contentModal: AppModalComponent;
I've tried adding {static: true}
to the ViewChild declaration
@ViewChild('contentModal', {static: true}) contentModal: ElementRef;
I've tried direct references to the target component:
@ViewChild(AppModalComponent) contentModal: AppModalComponent;
But with all of these the this.contentModal
variable is always null. I know I'm likely doing something wrong, but I'm still new enough that I can't figure it out.
Angular CLI: 15.2.9
Node: 21.5.0 (Unsupported)
Package Manager: npm 10.2.4
OS: darwin arm64
Angular: 15.2.2
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1502.9
@angular-devkit/build-angular 15.2.4
@angular-devkit/core 15.2.9
@angular-devkit/schematics 15.2.9
@angular/cli 15.2.9
@schematics/angular 15.2.9
rxjs 6.6.7
typescript 4.8.4
when you click on the toggle button showModal set to true and it takes a time to build that modal and add that modal to dom. so your viewchild still is null if you check it immediately. you can see that is true with a settimeout.
toggleModal(element: string) {
this.showModal = true;
setTimeout(() => {
console.log(this.contentModal);
}, 100);
}