Muhammad
Muhammad

Reputation: 181

Uncaught (in promise): TypeError: Cannot read property 'ɵcmp' of undefined in angular 10

I am getting this error Uncaught (in promise): TypeError: Cannot read property 'ɵcmp' of undefined in angular when trying to load the app I just compiled with --prod flag with both optimization and buildOptimizer set as true, when I set both to false the issue disappear and application is loading without issues but the application size is bigger and performance isn't as expected, I need to build a production with both optimization and buildOptimizer set as true, anyone have a good solution to this issue?

angular.json file :

            "staging": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.staging.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }

My Code in .ts to load dynamic component and this part not work when production angular application and have pervious error :

//Directive created
  @ViewChild(RequestsDirective) tabHost: RequestsDirective;

  constructor(
    private componentFactoryResolver: ComponentFactoryResolver,
    private viewContainerRef: ViewContainerRef,
    public requestsMainService: RequestsMainService,
    private spinner: NgxSpinnerService) { }

  ngOnInit(): void { }

  // Load Component in ng template  and set request name in services and hide category - request type part
  async loadTabComponent(_requestid: number, _requestname: string) {
    //debugger;
    // to set request name dynamic in all requests
    this.requestsMainService.RequestName = _requestname;
    // Hide Category And Requests type
    $('#div_main').hide('slow');

    // Search in App Model about component name
    const factories = Array.from( 
        this.componentFactoryResolver['ngModule']
            .instance.constructor.ɵmod.declarations
    );
    const factoryClass = factories.find(
        (x: any) => x.name === ('Request1Component')
    ) as Type<any>;

    // clear any previous component
    this.viewContainerRef.detach();
    this.viewContainerRef.clear();
    // get dynamic component by name
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(factoryClass);
    // load it in ng template
    this.viewContainerRef = this.tabHost.viewContainerRef;
    this.viewContainerRef.createComponent(componentFactory);
  }

Note

Request1Component this name of component I want to load it dynamic

Upvotes: 18

Views: 41883

Answers (10)

Worthy7
Worthy7

Reputation: 1561

This was unexplainable to be because my two components were using a singleton service, I tried to recreate this in the latest v19 in a stackblitz but it surprisingly worked.

After checking all settings, I found my app was using old HMR this package, https://github.com/PatrickJS/angular-hmr

After removing/disabling this, it worked.

Upvotes: 0

Salvador Mares
Salvador Mares

Reputation: 1

In my case:

For example in Nx if your index.ts file exports two components: Component1 and Component2 and you import Component2 into Component1 using ...from '@...'; It will throw this reading 'ɵcmp' error

To fix use './...'

Component1 is basically re-exporting Component2

Upvotes: 0

Salem Ouerdani
Salem Ouerdani

Reputation: 7906

I just had this error with Angular 19. Everything is standalone. It happens when I import the same directive inside 2 different components. Not sure why, but, the fix was switching the way I import it, from this:

 imports: [InputFormulaDirective],

to this:

 import {forwardRef} from '@angular/core';
 ...
 imports: [
    forwardRef(() => InputFormulaDirective),
 ],

Upvotes: 2

Rivaldo Cortez
Rivaldo Cortez

Reputation: 9

this problem appear when you import any component(carlitos) on other(example:pepito) and import pepito on carlitos, this is one of the reasons appear this problem :)

Upvotes: 0

Mike
Mike

Reputation: 979

In my case I had:

A - standalone, wraps <svg> to make custom icon
B - standalone, wraps A, injects ngrx store and sets inputs of A based on the result
C - regular, in module, uses A and B and also injects store
D - regular, unrelated module, loaded later, also uses A and B

And the culprit was that when B was importing A it did so via a barrel file.
One of other imports in that barrel was causing issues.

Upvotes: 2

Lesauf
Lesauf

Reputation: 31

I also had it when testing my library on local using npm link. Instead of running the npm link command from the library in dist folder, I was running it from the library in projects folder.

Upvotes: 0

AmirHossein Rezaei
AmirHossein Rezaei

Reputation: 1420

If you are importing components from an Angular library project, please double-check for circular dependencies. One common cause of this error is having circular dependencies in your project.

Upvotes: 12

Julien Ambos
Julien Ambos

Reputation: 2098

I had this issue using Angular 17 and Angular Material:

  • Have a standalone component A
  • Open another standalone component B inside a MatDialog
  • Referencing another standalone component C inside component B caused this issue to appear (when commenting out the reference to component C, the error disappeared)

What solved it for me was to convert standalone component A to an oldschool module and component (pre standalone).

Upvotes: 2

Igor Kurkov
Igor Kurkov

Reputation: 5101

I was faced this error while used microfrontends with NX on angular 15, and it was happened because some of components inside the shared lib were not exported from index.ts file. Just check the index.ts files which component you forgot to export.

Upvotes: 25

Shaybc
Shaybc

Reputation: 3177

this issue happens when you try to create/add/attach an undefined component to an existing component ref

change this line:

this.viewContainerRef.createComponent(componentFactory);

to this:

if (factoryClass != undefined) this.viewContainerRef.createComponent(factoryClass);

*note 1:

you don't need to use componentFactoryResolver.resolveComponentFactory() for createComponent() anymore it is deprecated, you should simply pass the class reference directly to createComponent()

*note 2:

when passing a value to viewContainerRef.createComponent() always check if it is undefined if it is not (maybe the class was not registered or created yet) - then don't add it, or replace it with some place holder component

Upvotes: 4

Related Questions