TypeError: Cannot read properties of undefined (reading 'ɵcmp') Angular
H

3

6

I have created a custom ui library using only standalone components and here's my public-api.ts file.

/*
 * Public API Surface of ih-ui-lib
 */

export * from './lib/ui-lib.service';
export * from './lib/ui-lib.component';
export * from './lib/ui-lib.module';

// Exporting components
export * from './lib/components/card/card.component';
export * from './lib/components/card/card-heading/card-heading.component';
export * from './lib/components/card/card-content/card-content.component';
export * from './lib/components/cards-responsive/cards-responsive.component';
export * from './lib/components/collapsible/collapsible.component';
export * from './lib/components/heading/heading.component';
export * from './lib/components/icon/icon.component';
export * from './lib/components/paragraph/paragraph.component';
export * from './lib/components/pill/pill.component';
export * from './lib/components/scrollbar/scrollbar.component';
export * from './lib/components/search/search.component';
export * from './lib/components/search/components/search-column/search-column.component';
export * from './lib/components/search/components/search-row/search-row.component';
export * from './lib/components/status-bar/status-bar.component';
export * from './lib/components/timeline/timeline.component';

Here's a example of a component:

import { Component, Input, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'card',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './card.component.html',
  styleUrls: ['./card.component.css']
})
export class CardComponent implements OnInit {

  @Input() classes: string = '';
  @Input() width: string = '';
  @Input() radius: string = 'sm';

  constructor() { }

  ngOnInit(): void {
  }

}

Here's how I'm adding to my app's package.json

  "ui-library": "git+repo+url.git#branch",

I also have index.ts file at the root of my lib which just exports the public-api.ts file so I can access it from the root.

export * from './dist/ih-ui-lib/public-api';

I created a new standalone component in my app and tried to import that component into my app.

And that is when I get this error: TypeError: Cannot read properties of undefined (reading 'ɵcmp')

I'm using angular 16.

I tried using modules for components and still it is the same. I tried importing standalone component to a module in my app and it failed to recognise that component.

Hostile answered 5/9, 2023 at 6:34 Comment(4)
You need to build the library. From the given information it appears you only wrote the source files for the library, but never built it.Sixtyfour
@JSONDerulo I have built the lib, sorry forgot to mention that.Hostile
Did you check in the dist folder to VCS? It is not recommended to "install" the library via git repository, you should publish the contents of your dist folder in a npm registry instead (you can also use a private registry). The problem could be that the package.json of your library is in dist folder, but the root package.json is used which doesn't contain the library.Sixtyfour
hmm, thanks @JSONDerulo Let me try publishing it.Hostile
S
1

You need to build the library and publish the build result as an npm package. From the docs:

Use the Angular CLI and the npm package manager to build and publish your library as an npm package.

ng build my-lib
cd dist/my-lib
npm publish

Installing your library via git repository does not work, because this is just the source code for the library, but you need a built library.

Sixtyfour answered 5/9, 2023 at 12:30 Comment(1)
Publishing or npm linking it works as well for local developmentHostile
D
8

You likely have circular imports which makes it impossible to instantiate the class.

One way to find which one is to use madge :

npx madge --circular --extensions ts ./
Diaconate answered 5/9, 2023 at 7:45 Comment(4)
No, that's not the case as the component I'm importing is dynamic and I've only used once on the standalone component I want which is erroring out. In the html of the component from ui lib it has ng-content mainly.Hostile
That was my problem :-) That's a really bad error tho, even if you've seen it before it's very non-obvious :-/Azedarach
Worked for me, had an injection token defined in the app.component file, and imports in some components caused issues.Tradeswoman
@Azedarach I fully agree. NPE's (or trying to read property of undefined) usually are. This error should have been caught by the framework to give it a better description. Someone™ should file a bugreport to Angular about this. I got this error recently when converting one component to standalone. And the problem seemed to be that this component was both used by and dependent on NgModule-based components from the same module. So I had to convert all dependencies from that module to standalone as well...Heptad
S
5

We recently encountered a similar problem. In our case, it helped to use "forwardRef" in imports forwardRef(() => "component or directive")

Simons answered 17/1 at 3:20 Comment(2)
forwardRef() did the trick for me. Usage notes say: "forwardRef is also used to break circularities in standalone components imports."Lane
Great tip since it helps as well for standalone components! ThxNonchalance
S
1

You need to build the library and publish the build result as an npm package. From the docs:

Use the Angular CLI and the npm package manager to build and publish your library as an npm package.

ng build my-lib
cd dist/my-lib
npm publish

Installing your library via git repository does not work, because this is just the source code for the library, but you need a built library.

Sixtyfour answered 5/9, 2023 at 12:30 Comment(1)
Publishing or npm linking it works as well for local developmentHostile

© 2022 - 2024 — McMap. All rights reserved.