-2

I read all presented questions stack overflow showed me, none of which solved my issue.

I'm new to Angular and I have a couple Modules and Components. I want a child module to import a component. Then have a parent module import the child module and create it's component. And yes, I have exported the Component in the child module.

I want it like so:

  • Parent Module
    • Child Module
      • Component (Toy)

But I get the error:

ERROR in parent/parent.module.ts(8,5): error TS2304: Cannot find name 'ToyComponent'.

I do not understand why this is not working. I would appreciate an explanation over some sample code. Thanks!


This is the relevant code:

Toy Component

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

@Component({
  selector: 'app-toy',
  templateUrl: './toy.component.html',
  styleUrls: ['./toy.component.css']
})
export class ToyComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

Toy Component HTML

<p>
  Awesome toy!
</p>

Child Module

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ToyComponent } from './toy/toy.component';
import { ChildComponent } from './child.component';

@NgModule({
  declarations: [
    ToyComponent,
    ChildComponent
  ],
  imports: [
    CommonModule
  ],
  exports: [
    ToyComponent
  ]
})
export class ChildModule { }

Parent Module

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChildModule } from './child/child.module';
import { ParentComponent } from './parent.component';

@NgModule({
  declarations: [
    ToyComponent,
    ParentComponent
  ],
  imports: [
    ChildModule,
    CommonModule
  ],
  exports: [
  ]
})
export class ParentModule { }

Parent Component HTML

<p>
  parent works! Child: Toy: <app-toy></app-toy>
</p>
Hichem BOUSSETTA
  • 1,791
  • 1
  • 21
  • 27
Kerwin Sneijders
  • 750
  • 13
  • 33
  • In parent component, you don't need to have ToyComponent in exports and declarations array – Dilan Tharaka May 22 '19 at 08:56
  • Export was an accident. I have updated the code. Why not in declarations though? I thought I had to declare it in every module I used it. If not, where should I declare the component? – Kerwin Sneijders May 22 '19 at 08:57
  • 1
    declarations array contains 'The components, directives, and pipes that belong to this NgModule.' ( according to https://angular.io/guide/architecture-modules#ngmodule-metadata ). ToyComponent is a component belongs to ChildModule. It doesn't belong to the parent module. Since, you don't neet to add it as a declarations to parent module – Dilan Tharaka May 22 '19 at 09:03
  • Thanks for the explanation, I do have another question related to this. I hope you could answer: As I cannot declare the `component`, how would I do this with a route. If I have a route to the parent and in the parent I have: `const parentRoutes: Routes = [{ path: '', component: ToyComponent }];`. I get the same error again. `Cannot find name...`. How would I fix this? – Kerwin Sneijders May 22 '19 at 09:40
  • 1
    Don't define child module routes in parent route, define routes to child module and implement its own router module in child module – Dilan Tharaka May 22 '19 at 12:57

2 Answers2

3

Fix:
1. Remove ToyComponent from the declarations and exports of ParentModule.
2. Declare ToyComponent in your Child Module and export it.
3. Add ChildModule as an import to your parent module.

Reason:
Your ToyComponent is declared under your ChildModule. Since you use ToyComponent in your ParentModule, you need to export your ToyComponent from your ChildModule. And import the ChildModule in your ParentModule.

Kerwin Sneijders
  • 750
  • 13
  • 33
Dulanjaya Tennekoon
  • 2,408
  • 1
  • 18
  • 31
  • Thanks, I had it exported and imported but had no idea I shouldn't declare it. (For anyone wanting to know why, read Dilan Tharaka comment below the question.) – Kerwin Sneijders May 22 '19 at 09:09
1

Problem

It looks like that the import statement for ToyComponent is missing in ParentModule which causes the error.

Fix

  • Since ToyComponent is added to exports in ChildModule it must not be referenced in ParentModule
  • Remove ToyComponent from the declarations-list in ParentModule

The ToyComponent is known to the ParentModule because ChildModule is added to the imports-List.

Gregor Woiwode
  • 1,046
  • 1
  • 9
  • 12
  • Thank you, although your **fix** fixes my issue it is not the answer to my question. Your 'problem' states I didn't have `ToyComponent` imported in the parent. Which is the thing I was trying to avoid. – Kerwin Sneijders May 22 '19 at 09:07
  • 1
    No worries, import statement means: `import { ToyComponent } from ...`. It was not related to Angular. I just tried to explain why you receive the error in the console. Maybe, I could express it a little bit better. Thanks for your feedback! – Gregor Woiwode May 22 '19 at 09:25
  • That makes sense, thank you. I have a question related to that though, if I had a route to the parent, how would I use that because I have to mention the component in the `Routes` array, right? – Kerwin Sneijders May 22 '19 at 09:42
  • Right, a route needs to be configured with path and the corresponding component. If you want to navigate to this route you either use the Directive `routerLink` (building the href) or you inject Angular's `Router`. You can either use absolute paths starting with `/` or relative paths accessing parent nodes `../../parent-path` – Gregor Woiwode May 22 '19 at 09:47
  • Thank you for the fast answer but I don't think I explained it well. What I meant was, I have the `RouterModule` from `@angular/router` imported in my `ParentModule`. I want to redirect it to `ToyComponent` like so: `const routes: Routes = [{ path: '', component: ToyComponent }];` but I get the same error that ToyComponent is not defined. How would I fix this? Use another `loadChildren` in that array again to the `ChildModule` ? – Kerwin Sneijders May 22 '19 at 09:53
  • 1
    In general, you use `loadChildren` referencing the `ChildModule`. The `ChildModule` has it's own `RouterModule` that defines the route for `ToyComponent`. In this way you do not need to reference ToyComponent in the ParentModule. – Gregor Woiwode May 22 '19 at 10:05