typescript - ERROR TypeError: No se puede leer la propiedad 'createComponent' de indefinido en angular 4
Soy nuevo en Angular 4 y estoy usando "carga de componentes dinámica" para hacer un proyecto, pero hay un problema con createComponent para cargar el componente.
En la imagen de arriba hay cuatro secciones.
- Sección superior (componente de encabezado)
- Sección de eventos (EventsComponent) Nota:- La sección de eventos tiene dos componentes dinámicos (2.1, 2.2)
2.1. Sección de detalles del evento (EventDetailComponent) de un evento en particular 2.2. Sección del formulario de usuario (UserFormComponent)
Cuando se hace clic en la pestaña "Evento" del encabezado superior, estamos llamando a la API de eventos y mostrando los eventos en la barra lateral izquierda, y luego se llama a la API de detalles del evento para cargar la pantalla "2.1 detalles del evento". Cuando se hace clic en mostrar usuario, nuevamente se carga el formulario dinámico "2.2 Formulario de Usuario".
Problema:- al acceder a la API del detalle de un evento en particular y la API está en estado de espera, y luego el usuario hace clic en la pestaña "crear evento", entonces se va a la pantalla de creación de evento y nuevamente el usuario hace clic en la pestaña de evento, entonces muestra un error de createComponent para el detalle del evento. Además, al hacer clic en el botón de agregar usuario, nuevamente muestra el mismo error.
Código:-
ngAfterViewInit() {
this.getEventList('init');
}
public getEventList(listsource) {
this.appService.getJsonRequest(AppSettings.EVENT_LIST).subscribe(result => {
if (result.status === 200 && result.events) {
this.events = result.events;
this.publicEvents = result.events;
this.events[0].selected = true;
this.selectedEVentInfo = this.events[0];
this.noImgFlag = true;
this.eventDetailFlag = false;
this.eventDetailInfo(listsource);
} else {
this.loaderMsg = AppSettings.EVENT_LIST_ERROR_MSG;
}
// this.loaderFlag = false;
}, err => {
this.loaderMsg = AppSettings.EVENT_LIST_ERROR_MSG;
this.loaderFlag = false;
this.snackBar.open(err, AppSettings.CLOSE, {
duration: AppSettings.DURATION,
});
});
}
eventDetailInfo (event, source: String = null) { // event detail
console.log('### Get event detail information');
if (this.eventDetailFlag === false) {
if ((source === 'list' || source === 'delete' || source === 'stripe') && this.ed !== undefined) { // testing needed
console.log('clear');
this.ed.clear();
}
let edCompFactory: ComponentFactory<any>;
edCompFactory = this.compFactoryResolver.resolveComponentFactory(EdComponent);
const componentRef = this.ed.createComponent(edCompFactory);
(<EdComponent>componentRef.instance).event = this.selectedEVentInfo;
}
}
}
Código para Agregar Usuario:-
expandAddEventMember(fullWidth) {
if (this.fullWidth === true && fullWidth === true) {
console.log('Before');
if (this.am !== undefined) {
this.am.clear();
}
// setTimeout(() => {
let amCompFactory: ComponentFactory<any>;
amCompFactory = this.compFactoryResolver.resolveComponentFactory(AmComponent);
const componentRef = this.am.createComponent(amCompFactory);
(<AmComponent>componentRef.instance).event = this.selectedEVentInfo;
this.fullWidth = false;
// }, 100);
}
}
Error:-
Aquí está mi componente de entrada
entryComponents: [
AppComponent,
ForgotModalComponent,
EventDetailsModalComponent,
AddManagerModalComponent,
AddAdminModalComponent,
CopyLinkModalComponent,
OrderSummaryModalComponent,
EventPreviewModalComponent,
PaidMemberModalComponent,
SendMessageModalComponent,
TicketInfoModalComponent,
AddPaidMemberModalComponent,
MessageModalComponent,
TicketCheckInDetailModalComponent,
SaleItemModalComponent,
SaleItemListModalComponent,
ApmComponent,
PmComponent,
AsmComponent,
SlmComponent,
TiComponent,
EdComponent,
AmComponent,
SihComponent,
ImageModalComponent,
GoogleMapModalComponent
]
Respuesta #1
Solo necesitas asegurarte de que am y em estén instanciados antes de crear el componente. Supongo que pueden estar indefinidos, ya que en tu código ya verificas si am o em están instanciados if(this.am !== undefined) en algún momento (antes de llamar a clear), pero no al llamar a createComponent. Es solo que necesitas incluir nuestro código de createComponent dentro del if.
eventDetailInfo(event, source: String = null)
{ // event detail
console.log('### Get event detail information');
if (this.eventDetailFlag === false)
{
if ((source === 'list' || source === 'delete' || source === 'stripe') && this.ed !== undefined)
{ // testing needed
console.log('clear');
this.ed.clear();
/*} <======= Remove this bracket*/
let edCompFactory: ComponentFactory<any>;
edCompFactory = this.compFactoryResolver.resolveComponentFactory(EdComponent);
const componentRef = this.ed.createComponent(edCompFactory);
(<EdComponent>componentRef.instance).event = this.selectedEVentInfo;
}/* <========== Add it here */
}
}
Lo mismo para addUser
expandAddEventMember(fullWidth)
{
if (this.fullWidth === true && fullWidth === true)
{
console.log('Before');
if (this.am !== undefined)
{
this.am.clear();
/* } <=== Remove this bracket **/
let amCompFactory: ComponentFactory<any>;
amCompFactory = this.compFactoryResolver.resolveComponentFactory(AmComponent);
const componentRef = this.am.createComponent(amCompFactory);
(<AmComponent>componentRef.instance).event = this.selectedEVentInfo;
this.fullWidth = false;
} /** <==== Add it here */
}
}
Editar: Con respecto a tu comentario sobre normalizarlo, probablemente deberías abrir otra pregunta ya que es un problema completamente diferente. El siguiente fragmento de código puede que no funcione (no probado) pero podría darte una idea de un enfoque
@Injectable()
export class CompFactoryHelper
{
constructor(private resolver: ComponentFactoryResolver)
{
}
public createAndAddComponent(containerRef: ViewContainerRef, eventInfo : any, type: any)
{
containerRef.clear();
let compFactory = this.resolver.resolveComponentFactory(type);
const componentRef = containerRef.createComponent(compFactory);
(componentRef.instance as any).event = eventInfo;
}
}
y en tus componentes
expandAddEventMember(fullWidth)
{
if (this.fullWidth === true && fullWidth === true)
{
console.log('Before');
if (this.am !== undefined)
{
this.compFactoryHelper.createAndAddComponent(this.am, this.selectedEVentInfo, AmComponent);
}
}
}

