Dependency chain:
Parent1Component -> SomeTableComponent -> SlideToggleComponent -> MatSlideToggleModule
Parent2Component -> SomeTableComponent -> SlideToggleComponent -> MatSlideToggleModule
Parent component #1
@Component({
selector: 'app-parent1',
standalone: true,
imports: [
SomeTableComponent, <------------
CommonModule,
FormArrayPipe,
FormsModule,
MatButtonModule,
MatDividerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
ReactiveFormsModule,
],
templateUrl: './parent1.component.html',
styleUrl: './parent1.component.scss',
})
export class Parent1Component {
}
Parent component #2
@Component({
selector: 'app-parent2',
standalone: true,
imports: [
SomeTableComponent, <------------
CommonModule,
GridItemComponent,
NavBarComponent,
NavBarV2Component,
MatTabsModule,
],
templateUrl: './parent2.component.html',
styleUrls: ['./parent2.component.scss', '../mat-tabs.scss'],
})
export class Parent2Component
implements AfterViewInit, OnDestroy, CanComponentDeactivate
{}
Both my parent1 & parent2 use a shared table (SomeTableComponent)
SomeTableComponent controller:
@Component({
selector: 'app-some-table',
standalone: true,
imports: [
CommonModule,
ClipboardIconComponent,
MatExpansionModule,
MatTooltipModule,
MatIconModule,
MatButtonModule,
MatProgressSpinnerModule,
PaginationComponent,
SlideToggleComponent, <-- problematic, at Module.SlideToggleComponent (some-table-component.component.ts:14:25)
GetDatePipe,
GetTimePipe,
],
templateUrl: './some-table.component.html',
styleUrls: ['./some-table.component.scss'],
})
export class SomeTableComponent implements OnInit {}
SomeTableComponent template:
...html stuff...
<app-slide-toggle
></app-slide-toggle>
SlideToggleComponent controller:
@Component({
selector: 'app-slide-toggle',
standalone: true,
imports: [MatSlideToggleModule],
templateUrl: './slide-toggle.component.html',
styleUrl: './slide-toggle.component.scss',
})
export class SlideToggleComponent {
}
SlideToggleComponent html:
<mat-slide-toggle
bunch of directives...
>
</mat-slide-toggle>
When using the SomeTableComponent
in my Parent2Component
, everything worked. When I tried adding SomeTableComponent
to my Parent1Component
, I get an angular application error:
some-random.component.ts:14 Uncaught TypeError: Cannot read properties of undefined (reading 'SlideToggleComponent')
at Module.SlideToggleComponent (some-table-component.component.ts:14:25)
at <static_initializer> (some-table.component.ts:50:5)
at 63805 (some-table.component.ts:30:55)
at __webpack_require__ (bootstrap:19:1)
at 5347 (some-other-random-component.component.ts:30:24)
at __webpack_require__ (bootstrap:19:1)
at 186 (index.ts:45:104)
at __webpack_require__ (bootstrap:19:1)
at 25940 (some-random.component.ts:14:25)
After some testing, I noticed that if I comment out the SlideToggleComponent
from my SomeTableComponent
, it works. What I don't understand is why this works when my SomeTableComponent
was only being used in my Parent2Component
, but as soon as it's added to Parent1Component
, it can't resolve SlideToggleComponent
.
Standalone components in Angular behave differently compared to module-based components. When you import components from a barrel file (like index.ts), Angular might not correctly resolve the dependencies during the build, especially when dealing with standalone components. This is because Angular's internal dependency resolution for standalone components doesn't always handle re-exports in the same way as module-based components. Standalone components must be directly imported and referenced in the imports array, and any indirect import (through an index.ts barrel) could cause Angular to lose track of the actual components at runtime.
Solution was to remove SlideToggleComponent
from the index.ts file and directly import it in my SomeTableComponent
. Excerpt is from chatgpt so take some of it with a grain of salt, but this was the solution to my problem