Unable to access CommonModule in Angular 10 component loaded dynamically

I'm currently working on a project using Angular. One of my methods involves dynamically creating a component, but I'm encountering difficulties when trying to use directives like ngClass and ngIf from the CommonModule within this component.

Here's an example of the issue:

See the error when using ngIf or ngClass within the dynamically loaded component

WHAT I'VE TRIED SO FAR:

  • I've already imported the CommonModule in my app.module.ts file
  • The CommonModule is also imported in my display component, where I can successfully use ngIf and ngClass without any problems
  • I can import any component without any errors, as long as I'm not using directives from the CommonModule in the HTML
  • I attempted to import an instance of NgModule through the component factory createComponent function as outlined in the Angular documentation.

Check out the Angular documentation on component factory createComponent for more details

I've spent countless hours on this issue and I suspect it's related to my usage of the createComponent method.

Please, I need assistance!

Here's a snippet from my app.module.ts file:

import { NgModule } from '@angular/core';
import { BrowserModule, HammerGestureConfig, HammerModule, 
 HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
import { GoogleAnalyticsService } from 
 './shared/services/googleanalytics'; // import our Google Analytics 
 service
import { BrowserAnimationsModule } from '@angular/platform- 
browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CommonModule } from '@angular/common';


@NgModule({
  declarations: [AppComponent],
  imports: [
   CommonModule,
   BrowserModule,
   AppRoutingModule,
   HttpClientModule,
   BrowserAnimationsModule,
   ],
  providers: [GoogleAnalyticsService], 
  bootstrap: [AppComponent],
 })
 export class AppModule {}

Here's a snippet from my Display component (Bdoc-a.component.ts):

// Code for Display component goes here
 

Here's a snippet from Logo1a.component.html:

// Code for Logo1a component HTML goes here

Here's a snippet from Logo1a.component.ts:

// Code for Logo1a component TypeScript logic goes here

Here's a snippet from Logo1a.module.ts:

// Code for Logo1a module definition goes here

After dynamically importing the module instead of the component in my Angular 10 app, I encountered this error:

ERROR Error: Uncaught (in promise): Error: ASSERTION ERROR: Type passed in is not ComponentType, it does not have 'ɵcmp' property. ....

Answer №1

To ensure proper association with the CommonModule at runtime, the component must reside within its own module that declares the CommonModule.

1. Establish a module for the component

@NgModule({
  declarations: [ YourCustomComponent ],
  imports: [ CommonModule ] // THIS INDICATES ANGULAR TO INCLUDE IT WITHIN THE COMPONENT
  exports: [ YourCustomComponent ]
})

export class YourCustomModule { }

2. Integrate the component

constructor(private compiler: Compiler, private viewContainerRef: ViewContainerRef) {}


createCustomComponent(): void {
  const componentModule = this.compiler.compileModuleAndAllComponentsSync(YourCustomModule);
  const factory = componentModule.componentFactories.find(c => comp.componentType === YourCustomComponent);  
  this.viewContainerRef.createComponent(factory);
}

3. Ensure the component is adorned with the CommonModule decorator

Answer №2

After much effort, I have managed to devise a somewhat messy solution to my original query.

  1. To tackle the issue, I decided to create a new module called LogoModules. Here, I imported all the logo modules that needed to be displayed in my component.

    import { NgModule } from '@angular/core'; import { Logo1aModule } from '../templates/logo/1/logo1a/logo1a.module'; {Logo2aModule } from '../templates/logo/2/logo2a/logo2a.module'; {Logo3aModule } from '../templates/logo/3/logo3a/logo3a.module';

    @NgModule({ // imports: [], // exports: [], })

    export class LogoModules {}

Although this approach is a variation of @jburtondev's recommendation to pre-import all modules, I believe there must be a more efficient way to handle this. While dynamically loading modules and components without pre-importing can work, it also encounters failures at times. I suspect there might be certain configurations in tsconfig related to the compiler and webpack causing these issues. Further investigation is required to confirm this.

  1. In my display component, I proceeded to import the LogoModules module.

    import { LogoModules } from '../templates/logo/logos.module'; ...

However, in order to successfully store the paths of each logo template in my database and exhibit them dynamically based on user interactions, I made adjustments to my dynamic component loader within Bdoc-a.component.ts:

....
async loadDynAsset(url, pgIndex) {
  const mObj = await import('src/app/' + url2);
  const mKeys = Object.keys(mObj);
  const mName = mKeys[0];

  this.compiler.compileModuleAndAllComponentsAsync(mObj[mName])
    .then((factories) => {
      const f = factories.componentFactories[0];
      const newComp = this.testDynComp.createComponent(f);
      newComp.instance['bol']['test'] = 'LOGO TEST TEXT HERE... ' + pgIndex;
    });

  .... 

}
....

By implementing this revised approach, I was able to achieve a consistent outcome without encountering any errors. Special thanks to @jburtondev for providing valuable insights. I will update my solution once I come across a more refined method to address my initial query.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can the .pre() middleware function in Mongoose be utilized?

I'm curious about the use cases for mongoose .pre('validate') and .pre('save'). I understand their functionality, but I'm struggling to think of specific scenarios where I would need to utilize them. Can't all necessary a ...

Node.js frequently returns null with its url methods

I'm having some trouble getting node.js to display the HTTP request properties in the browser. I've tried printing the properties of the request URL, but they either show up as null or don't display at all. Below is the code for the server ( ...

Sending an array of objects over socket io: A step-by-step guide

Recently, I've been struggling with an issue when trying to send an array of objects through socket io. This is my server-side code: var addEntity = function(ent) { entityBag.push(ent); }; var entityBag = []; addEntity(new Circle({ ...

What is the method for ensuring text remains within a square while it is being relocated?

Check out this jsfiddle where you can interact with a moving square: http://jsfiddle.net/helpme128/3kwwo53t/2/ <div ng-app="test" ng-controller="testCtrl"> <div id="container"> <div class="shape" ng-draggable='dragOptions& ...

When I set the width of my script to 100% in CSS, it causes the width to become distorted

I encountered an issue with my Div Slider that swaps out Divs on click. When I modified the CSS to include the following: .hslide-item {width: 100%}; The script started ignoring the entire div width. I am looking for a solution where the .hslide-item ca ...

Transform webservice data into TypeScript object format, ensuring mapping of objects from capital letters to camel case

Something peculiar caught my attention in my Angular2 TypeScript project. When objects are fetched from a web service, they have the type "Level" and the properties are in Pascal case. However, during runtime, I noticed that the properties of these Levels ...

Angular page fails to refresh upon addition or deletion of data

There's a recurring issue with my angular application where the page fails to refresh after data manipulation such as addition, editing, or removal. For example, when I add a new item to a list of subjects, it doesn't show up unless I navigate aw ...

The radar chart created with amchart.js disappears when placed within bootstrap columns

I'm encountering an issue while trying to display radar charts using amchart.js in bootstrap columns. The "amStockGraph" charts render perfectly, however, the radar charts appear blank with no errors in the console. Any advice on this matter would be ...

What is the best way to ensure that JavaScript form errors disappear as soon as new input is entered?

Below is the code snippet: var nameInput = formHandle.f_Name; var idInput = formHandle.f_Id; // VALIDATING NAME if(nameInput.value === ""){ nameMsg = document.getElementById("nameErr"); nameMsg.style.background ...

How to Redirect between Controllers in Nest.Js

I'm currently working with a module that looks like this: @Module({ imports: [], controllers: [AppController, AnotherController], providers: [], }) Within the AppController, I am attempting to implement res.redirect('/books') which r ...

The issue with loading scripts in a ReactJS NextJS app is related to the inline condition not working

I'm having trouble with an inline condition for loading scripts. The condition seems to be working because the tag is displaying text, but when it comes to scripts, it doesn't work. How can I resolve this issue? const cookie = new Cookies().get ...

Can Tescafe be used to simulate a login process?

Scenario: Testing the features of an app built with Testcafe and Vue requires being logged in, as being logged out redirects to the login page. Roles have been utilized to streamline the login process, but is there a way to simulate logging in without actu ...

Update elements dynamically using JSX

I have an array called data.info that gets updated over time, and my goal is to replace placeholder rendered elements with another set of elements. The default state of app.js is as follows: return ( <Fragment> {data.info.map((index) =&g ...

Angular Observables do not update local variables when making API calls

For some reason, I cannot set a value in my local variable as expected. Here is the code snippet: export class memberComponent implements OnInit { member : Member = new Member(); constructor(private memberService: MemberService) {} ngOnInit() { ...

When HTML/JS code is utilized, the submit button or image should function to open the same page as

In addition to the left and right mouse buttons, you also have a middle mouse button. If you click on an image or hyperlink with this middle mouse button while browsing any website, it will open a new window in the background. Now, I want to achieve a sim ...

How to utilize methods from different pages in Ionic 2

Looking to display the total number of items in an array on a card located on the home screen, but facing issues referencing methods outside of the typescript file they're written in. Trying to extract the array size method and utilize it in a differe ...

Toggle visibility of cards using bootstrap

I've been attempting to show and hide a selection of cards in bootstrap, but I'm having trouble figuring it out. All the cards share the class "card," and my goal is to hide them all when a specific button is clicked. Below is my current code: ...

Navigating URL to switch data access

Is there a way to toggle the visibility of a div when I add #ID at the end of the URL? For instance, if I access a URL like domain.com/xxxxxx#01, then the specified div should be displayed. $(document).ready(function() { $(".toogle_button_<?php echo ...

communicating global variables between Django and JavaScript

I want to make variables from my settings.py accessible in all JavaScript code used throughout my project. What is the best way to accomplish this elegantly? Currently, I am considering two options: Create a context processor and define these globals ...

A guide on converting character objects to strings

Presented below is an array of characters: Resource {0: "-", 1: "-", 2: "-", 3: "-", 4: "-", 5: "B", 6: "E", 7: "G", 8: "I", 9: "N", 10: " ", 11: "C", 12: "E", 13: "R", 14: "T", 15: "I", .... } I am looking to convert it into the following format: --- ...