I am desperately seeking for help as I cannot figure out how to solve a problem in my Angular application,
I have created a custom modal:
modal.component.html
<div class="modal {{ size }}">
<lib-card [background]="'#FFF'">
<div class="wrapper">
<div class="modal-content">
<ng-content></ng-content>
</div>
<div class="modal-footer">
<lib-button [size]="'small'" [variant]="'secondary'">Cancel</lib-button>
<lib-button [size]="'small'" (click)="submit()">Save</lib-button>
</div>
</div>
</lib-card>
</div>
<div class="modal-backdrop" (click)="close()"></div>
modal.component.ts
import {
Component,
ElementRef,
EventEmitter,
Input,
Output,
} from '@angular/core';
import { ButtonComponent, CardComponent } from 'tgtr-fe-comp-lib';
@Component({
selector: 'app-modal',
standalone: true,
imports: [ButtonComponent, CardComponent],
templateUrl: './modal.component.html',
styleUrl: './modal.component.scss',
})
export class ModalComponent {
@Input() size? = 'md';
@Input() title? = 'Modal title';
@Output() closeEvent = new EventEmitter();
@Output() submitEvent = new EventEmitter();
constructor(private elementRef: ElementRef) {}
close(): void {
this.elementRef.nativeElement.remove();
this.closeEvent.emit();
}
submit(): void {
this.elementRef.nativeElement.remove();
this.submitEvent.emit();
}
}
modal.service.ts
import { DOCUMENT } from '@angular/common';
import {
ComponentFactoryResolver,
Inject,
Injectable,
Injector,
TemplateRef,
} from '@angular/core';
import { Subject } from 'rxjs';
import { ModalComponent } from './modal.component';
@Injectable()
export class ModalService {
private modalNotifier?: Subject<string>;
constructor(
private resolver: ComponentFactoryResolver,
private injector: Injector,
@Inject(DOCUMENT) private document: Document
) {}
open(content: TemplateRef<any>, options?: { size?: string; title?: string }) {
this.document.body.style.overflow = 'hidden';
const modalComponentFactory =
this.resolver.resolveComponentFactory(ModalComponent);
const contentViewRef = content.createEmbeddedView(null);
const modalComponent = modalComponentFactory.create(this.injector, [
contentViewRef.rootNodes,
]);
modalComponent.instance.size = options?.size;
modalComponent.instance.title = options?.title;
modalComponent.instance.closeEvent.subscribe(() => this.closeModal());
modalComponent.instance.submitEvent.subscribe(() => this.submitModal());
modalComponent.hostView.detectChanges();
this.document.body.appendChild(modalComponent.location.nativeElement);
this.modalNotifier = new Subject();
return this.modalNotifier?.asObservable();
}
closeModal() {
this.modalNotifier?.complete();
this.document.body.style.overflow = 'auto';
}
submitModal() {
this.modalNotifier?.next('confirm');
this.closeModal();
}
}
Everything outside the ng-content is correctly displayed, however, all the custom components inside are not. Ex, my custom p component is missing the bold style. My custom input component are not displayed at all, or my radio button component only display the radio.
MyComponentWithModalCall.component.html
<div class="itinerary">
<div class="head">
<lib-h1 [bold]="true">Itinerary</lib-h1>
<lib-p [bold]="true" [responsive]="true"
>A visual itinerary shows customers exactly where they’ll go and what
they’ll do during your activity.
</lib-p>
</div>
<div class="button-container">
<lib-button [fill]="true" [variant]="'secondary'"
>Add Meeting / Pickup Point</lib-button
>
</div>
<button (click)="openModal(modalTemplate)">Open Modal</button>
</div>
<ng-template #modalTemplate>
<app-itinerary-modal />
</ng-template>
MyComponentWithModalCall.component.ts
import { Component, TemplateRef } from '@angular/core';
import {
ButtonComponent,
Heading1Component,
InputComponent,
ParagraphComponent,
RadioComponent,
} from 'tgtr-fe-comp-lib';
import { ModalService } from '../../modal/modal.service';
import { ItineraryModalComponent } from './itinerary-modal/itinerary-modal.component';
@Component({
selector: 'app-itinerary',
standalone: true,
imports: [
Heading1Component,
ParagraphComponent,
ButtonComponent,
InputComponent,
RadioComponent,
ItineraryModalComponent,
],
templateUrl: './itinerary.component.html',
styleUrl: './itinerary.component.scss',
})
export class ItineraryComponent {
constructor(private modalService: ModalService) {}
openModal(modalTemplate: TemplateRef<any>) {
console.log(modalTemplate);
this.modalService
.open(modalTemplate, { size: 'lg', title: 'Add location' })
.subscribe((action) => {
console.log('modalAction', action);
});
}
}
I get no errors in my console. Here is a picture of the html inspection from the browser
Browser html structure screenshot
I would be grateful for any help!
I have tried asking chatGPT to figure out if something was missing in my modal.service, I also tried changing the encapsulation.
Pietro Curcio is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.