229

I'm trying to use a component I created inside the AppModule in other modules. I get the following error though:

"Uncaught (in promise): Error: Template parse errors:

'contacts-box' is not a known element:

  1. If 'contacts-box' is an Angular component, then verify that it is part of this module.
  2. If 'contacts-box' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

My project structure is quite simple: Overall project structure

I keep my pages in pages directory, where each page is kept in different module (e.g. customers-module) and each module has multiple components (like customers-list-component, customers-add-component and so on). I want to use my ContactBoxComponent inside those components (so inside customers-add-component for example).

As you can see I created the contacts-box component inside the widgets directory so it's basically inside the AppModule. I added the ContactBoxComponent import to app.module.ts and put it in declarations list of AppModule. It didin't work so I googled my problem and added ContactBoxComponent to export list as well. Didn't help. I also tried putting ContactBoxComponent in CustomersAddComponent and then in another one (from different module) but I got an error saying there are multiple declarations.

What am I missing?

Aranha
  • 2,903
  • 3
  • 14
  • 29
  • 2
    Your folder structure isn't simple. It's confusing. I would suggest following Angular Style Guide (link not provided b/c they change) and use their folder structure suggestions and then make sure that you are using modules correctly. That's what this means. You are either not exporting or declaring your component in a module ingested by the app at some point. – Joshua Michael Calafell May 02 '19 at 17:08
  • 1
    I had this issue and solved it by including a component where it was not being included but where there was a component that included it. Point being... I read ALL of the below answers and tried lots of things before finding my solution... all good contributions so recommend reading more than one. HTH – Scala Enthusiast Jul 13 '21 at 16:14
  • If none of the answers worked, Just delete and re-create the 'contacts-box' component. – Iman Bahrampour Jan 20 '22 at 12:49

23 Answers23

437

These are the 5 steps I perform when I get such an error.

  • Are you sure the name is correct? (Also check the selector defined in the component)
  • Declare the component in a module?
  • If it is in another module, export the component?
  • If it is in another module, import that module?
  • Restart the cli?

When the error occurs during unit testing, make sure your declared the component or imported the module in TestBed.configureTestingModule

I also tried putting ContactBoxComponent in CustomersAddComponent and then in another one (from different module) but I got an error saying there are multiple declarations.

You can't declare a component twice. You should declare and export your component in a new separate module. Next you should import this new module in every module you want to use your component.

It is hard to tell when you should create new module and when you shouldn't. I usually create a new module for every component I reuse. When I have some components that I use almost everywhere I put them in a single module. When I have a component that I don't reuse I won't create a separate module until I need it somewhere else.

Though it might be tempting to put all you components in a single module, this is bad for the performance. While developing, a module has to recompile every time changes are made. The bigger the module (more components) the more time it takes. Making a small change to big module takes more time than making a small change in a small module.

Tim
  • 5,435
  • 7
  • 42
  • 62
Robin Dijkhof
  • 18,665
  • 11
  • 65
  • 116
  • 10
    Your steps didn't help me but maybe it's because I'm pretty new to Angular 2, so I'll answer them and perhaps we will figure the solution out together. I am sure the name is correct, I declared the component in AppModule, I exported the component in AppModule and restarted the cli. I also tried importing AppModule in my CustomersAddComponent but it resulted in Error: Maximum call stack size exceeded (I guess we don't import AppModule in Angular 2). – Aranha Jun 08 '17 at 08:28
  • 8
    You should declare and export your component in a sepperate module, Not in AppModule. Next you should import this new module in everymodule you wnat to use your component. – Robin Dijkhof Jun 08 '17 at 09:06
  • 2
    Okay, I get it now. The only question is: when I import the newly created module (say WidgetsModule) it would load aaaaaall the components declared inside, right? That's some overhead but maybe I'm misunderstanding something. I could of course create ContactsBoxModule but that's a lot as for one little component. Any hints? – Aranha Jun 08 '17 at 09:14
  • 5
    That is right. And it is hard to tell when you should create new module and when you shouldn't. I usually create a new module for every component I reuse. When I have some components that I use almost everywhere I put them in a single module. When I have a component that I don't reuse I won't create a separate module until I need it somewhere else. – Robin Dijkhof Jun 08 '17 at 09:23
  • In my case, component selector was different. – Rzassar Apr 27 '18 at 06:53
  • @RobinDijkhof Why we should not declare the reusable component inside the `AppModule` whenever its the root module and all the declarations inside it are available to the child modules? Though I am facing the same issue and component is not accessible in child modules, why we should create another module and import it again and again instead of a single declaration of the component in `AppModule`? – Rohit Sharma Sep 13 '18 at 12:45
  • @RohitSharma Yes would be posible. However, you could get some performance issues during development. While developing, a module has to recompile everytime changes are made. The bigger the module (more compontens) the more time it takes. Making a small change to big module takes more time than making a small change in a small module. – Robin Dijkhof Sep 13 '18 at 12:51
  • You can and must import modules mutiple times. If a module is imported by some someModule it isn't accesible by it's children. You must import it for it's children as well. – Robin Dijkhof Sep 13 '18 at 13:00
  • @RobinDijkhof I think the problem a lot of people have is when those "child" components need to use an exported component from the parent's module. What do you do then? – Ben Racicot Feb 18 '19 at 20:24
  • Substract it from the parent and put it in a new module. This is decribed in the first few comments. – Robin Dijkhof Feb 19 '19 at 08:11
  • In my case, I had the component declared in app.module but then created a separate module for it and forgot to delete the declaration in app.module! – adam0101 Mar 07 '19 at 00:24
  • 4
    `Restart the cli` worked for me. I don't know why this happened. – Vahid Najafi Mar 17 '19 at 12:22
  • Thanks. In my case, I forgot to export the component. – SUHAIL KC Feb 02 '20 at 13:25
  • In case of using component from another module, you have to export this component from that module file. ex. exports: @NgModule({ exports: [LazyTwoComponent], , Thanks , its working – Rajesh Pal Apr 26 '20 at 13:56
  • I had to restart VS Code – Michael Pearson May 14 '20 at 03:31
  • I am stuck on my case: I *import* 3rd party module (which in fact is just a set of exported declared classes) into my component A of module A. Component A is used by my app module (I need to, to be short). And voila - 3rd party module is reported as "module not found" when trying to compile! – Alexander Jul 29 '20 at 10:13
  • forgot npm install after adding components and a module.. should not develop when tired ;) – Julian Egner Aug 19 '20 at 16:23
  • I am using Angular 10 and it did not allow me to name with app- and this was the reason of my error . this helped me "also check the selector defined in the component". – MindRoasterMir Sep 17 '20 at 08:46
  • Don't forget to export the component when Its' declared in Its own module. Reference https://stackoverflow.com/questions/39477379/angular-2-cant-find-a-component-declared-in-my-feature-module – Neel Rathod Nov 10 '20 at 10:49
  • Thanks!! I am new to angular and was adding the component to the module import instead of declaration – Shahaf Shavit Jun 04 '21 at 16:44
  • Something missing here, you need to add all your modules to the `imports:[]` array in app.module.ts - I don't know why `generate module` does not do this automatically. – Chris Oct 12 '21 at 16:05
  • In my case i was forget to add to exports in the other module using this component. – Anas Mar 01 '22 at 11:06
  • In my case, it showed me the error on two components (which I correctly imported etc), but the actual problem was that I missed to import the parent component into the model. – MikhailRatner Mar 17 '22 at 09:17
43

I had a similar issue. It turned out that ng generate component (using CLI version 7.1.4) adds a declaration for the child component to the AppModule, but not to the TestBed module that emulates it.

The "Tour of Heroes" sample app contains a HeroesComponent with selector app-heroes. The app ran fine when served, but ng test produced this error message: 'app-heroes' is not a known element. Adding the HeroesComponent manually to the declarations in configureTestingModule (in app.component.spec.ts) eliminates this error.

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        HeroesComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  });
}
Jan Hettich
  • 9,146
  • 4
  • 35
  • 34
  • I had a similar experience working with the Book "Angular Up & Running" from Shyam Seshadri (ISBN: 978-1-491-99983-7) where a stock market example app is created. In the testing chapter I noticed the generated app.component.spec.ts test didn't clear because the tag app-stock-item wasn't found. Fix was to add StockItemComponent to the declarations similar to how you've added HeroesComponent in yours. Thans for helping us out! – hcpl May 06 '23 at 18:41
24

I just had the exact same issue. Before trying some of the solutions posted here, you might want to check if the component really doesn't work. For me, the error was shown in my IDE (WebStorm), but it turned out that the code worked perfectly when i ran it in the browser.

After I shut down the terminal (that was running ng serve) and restarted my IDE, the message stopped showing up.

harryvederci
  • 489
  • 4
  • 7
  • The problem is ide-specific. I have the same problem with webstorm. Webstorm is not informed for changes made with angular-cli so you must restart the IDE to make it 'see' any new components! – skiabox Jan 10 '18 at 14:20
  • 2
    I have the same problem with VS Code but with Ionic 2. In a page it works. In a component there is the error **ion-* is not a known element**. I've tried your suggestion to stop **ionic serve** and restarted the IDE, but nothing works. Do you know another solution for this? By the way - the code works anyway. – Sebastian Ortmann Jan 15 '18 at 11:30
  • 1
    Had the same issue with VSCode. After restarting the editor the message went away. – quicklikerabbit Jun 12 '20 at 00:17
18

A lot of answers/comments mention components defined in other modules, or that you have to import/declare the component (that you want to use in another component) in its/their containing module.

But in the simple case where you want to use component A from component B when both are defined in the same module, you have to declare both components in the containing module for B to see A, and not only A.

I.e. in my-module.module.ts

import { AComponent } from "./A/A.component";
import { BComponent } from "./B/B.component";

@NgModule({
  declarations: [
    AComponent,   // This is the one that we naturally think of adding ..
    BComponent,   // .. but forget this one and you get a "**'AComponent'** 
                  // is not a known element" error.
  ],
})
fcdt
  • 2,371
  • 5
  • 14
  • 26
Cedric
  • 183
  • 2
  • 6
8

I had the same problem with Angular CLI: 10.1.5 The code works fine, but the error was shown in the VScode v1.50

Resolved by killing the terminal (ng serve) and restarting VScode.

kingabdr
  • 588
  • 5
  • 12
5

This question may seem old and odd, but when I was trying to load a module(lazy loading) and getting the same error, I realized I was missing an exports clause for the component that shipped as a part of a larger module.

This Angular.io Link explains why: Components/Services inside a module, remains private(or protected) by default. To make them public, you have to export them.

Expanding on @Robin Djikof's answer with @live-love code sample, this is what was technically missing in my case(Angular 8):

@NgModule({
  declarations: [
    SomeOtherComponent,
    ProductListComponent
  ],
  imports: [
    DependantModule
  ],
  exports: [ProductListComponent] 
  //<- This line makes ProductListComponent available outside the module, 
  //while keeping SomeOtherComponent private to the module
})
export class SomeLargeModule { }
P.M
  • 2,880
  • 3
  • 43
  • 53
4

I was facing the same issue. In my case I have forgotten to declare Parent component in the app.module.ts

As a example if you are using <app-datapicker> selector in ToDayComponent template, you should declare both ToDayComponent and DatepickerComponent in the app.module.ts

3

I have the same issue width php storm version 2017.3. This fix it for me: intellij support forum

It was an error width @angular language service: https://www.npmjs.com/package/@angular/language-service

Milan
  • 444
  • 5
  • 11
3

In my case, my app had multiple layers of modules, so the module I was trying to import had to be added into the module parent that actually used it pages.module.ts, instead of app.module.ts.

Kof
  • 23,893
  • 9
  • 56
  • 81
2

Route modules (did not saw this as an answer)

First check: if you have declared- and exported the component inside its module, imported the module where you want to use it and named the component correctly inside the HTML.

Otherwise, you might miss a module inside your routing module:
When you have a routing module with a route that routes to a component from another module, it is important that you import that module within that route module. Otherwise the Angular CLI will show the error: component is not a known element.

For example

1) Having the following project structure:

├───core
│   └───sidebar
│           sidebar.component.ts
│           sidebar.module.ts
│
└───todos
    │   todos-routing.module.ts
    │   todos.module.ts
    │
    └───pages
            edit-todo.component.ts
            edit-todo.module.ts

2) Inside the todos-routing.module.ts you have a route to the edit.todo.component.ts (without importing its module):

  {
    path: 'edit-todo/:todoId',
    component: EditTodoComponent,
  },

The route will just work fine! However when importing the sidebar.module.ts inside the edit-todo.module.ts you will get an error: app-sidebar is not a known element.

Fix: Since you have added a route to the edit-todo.component.ts in step 2, you will have to add the edit-todo.module.ts as an import, after that the imported sidebar component will work!

Brampage
  • 6,014
  • 4
  • 33
  • 47
2

Sometimes even just restarting your IDE works!! Faced the same issue, resolved by restarting VS Code

Glitch07
  • 87
  • 11
1

I got the same issue, and it was happening because of different feature module included this component by mistake. When removed it from the other feature, it worked!

1

The problem in my case was missing component declaration in the module, but even after adding the declaration the error persisted. I had stop the server and rebuild the entire project in VS Code for the error to go away.

Eternal21
  • 4,190
  • 2
  • 48
  • 63
1

I know this is a long resolved problem, but in my case I had a different solution. It was actually a mistake I made that maybe you made as well and didn't fully notice. My mistake was that I accidentally placed a Module e.g., MatChipsModule, MatAutoCompleteModule, on the declarations section; the section that is composed only by components e.g., MainComponent, AboutComponent. This made all my other import unrecognizable.

1

I spent half day for resolving this problem. Problem was in imports. My HomeModule has homeComponent which includes in html . ProductComponent is part of ProductModule. And i added ProductModule in imports into HomeModule but forgot add HomeModule in imports into AppModule. After adding, problem disappeared

0

This convoluted framework is driving me nuts. Given that you defined the custom component in the the template of another component part of the SAME module, then you do not need to use exports in the module (e.g. app.module.ts). You simply need to specify the declaration in the @NgModule directive of the aforementioned module:

// app.module.ts

import { JsonInputComponent } from './json-input/json-input.component';

@NgModule({
  declarations: [
    AppComponent,
    JsonInputComponent
  ],
  ...

You do NOT need to import the JsonInputComponent (in this example) into AppComponent (in this example) to use the JsonInputComponent custom component in AppComponent template. You simply need to prefix the custom component with the module name of which both components have been defined (e.g. app):

<form [formGroup]="reactiveForm">
  <app-json-input formControlName="result"></app-json-input>
</form>

Notice app-json-input not json-input!

Demo here: https://github.com/lovefamilychildrenhappiness/AngularCustomComponentValidation

Daniel Viglione
  • 8,014
  • 9
  • 67
  • 101
0

I am beginning Angular and in my case, the issue was that I hadn't saved the file after adding the 'import' statement.

user637563
  • 346
  • 3
  • 15
0

Supposedly you have a component:

product-list.component.ts:

import { Component } from '@angular/core';
    
    @Component({
        selector: 'pm-products',  
        templateUrl: './product-list.component.html'
    })
    
    
    export class ProductListComponent {
      pageTitle: string = 'product list';
    }

And you get this error:

ERROR in src/app/app.component.ts:6:3 - error NG8001: 'pm-products' is not a known element:

  1. If 'pm-products' is an Angular component, then verify that it is part of this module.

app.component.ts:

import { Component } from "@angular/core";
@Component({
  selector: 'pm-root', // 'pm-root'
  template: `
  <div><h1>{{pageTitle}}</h1>
  <pm-products></pm-products> // not a known element ?
  </div>
  `
})
export class AppComponent {
  pageTitle: string = 'Acme Product Management';
}

Make sure you import the component:

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

// --> add this import (you can click on the light bulb in the squiggly line in VS Code)
import { ProductListComponent } from './products/product-list.component'; 

@NgModule({
  declarations: [
    AppComponent,
    ProductListComponent // --> Add this line here

  ],
  imports: [
    BrowserModule
  ],
  bootstrap: [AppComponent],


})
export class AppModule { }
live-love
  • 48,840
  • 22
  • 240
  • 204
0

While executing Angular's Getting Started Tutorial, I too received this error after using the Angular Generator to generate a new component named product-alerts with the tool stackblitz.com.

'app-product-alerts' is not a known element:

FINDING: Others have experienced it too in early August 2021. At the moment, it appears to be a bug in the StackBlitz IDE. https://github.com/angular/angular/issues/43020

Michael R
  • 1,547
  • 1
  • 19
  • 27
0

My situation was a bit different. I was getting this error message, but it was because my pages module didn't have a new page that I had generated.

My steps:

  1. Generate new page component
  2. Import existing components into the new page's module.ts file
  3. Use the <myapp-header></myapp-header> component selector in the HTML file of the new page

Got the error and got stuck here. The final step for me was:

  1. Import new page module into the pages.module.ts file.

Now it works as expected. The error message wasn't too helpful this time around.

SauerTrout
  • 471
  • 1
  • 8
  • 13
0

For my app pattern, once I declared my LandingPageComponent in the app.module.ts file, importing child modules into it worked.

I just started a new project and took for granted some of these patterns.

SauerTrout
  • 471
  • 1
  • 8
  • 13
0

I had a similar Problem, but none of the mentioned solutions worked. In the end i realized i have a routing problem:

I thought if i specify my component in the app-routing.module like so:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MainComponent } from './pages/main/main.component';

const routes: Routes = [
  {
    path: '', 
    component: MainComponent
  },
]

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

i would not have to import the MainModule in my AppModule, which is wrong since here only the component gets imported. Any other components declared in MainModule will not be visible which results in the error message you described.

Solution 1:
Import the declaring module
Solution 2:
Lazyload the component like so:

const routes: Routes = [
{
    path: '', loadChildren: () => import('path_to_your_module').then(m => m.MainModule)},
}

This works since the whole module gets imported here.

I realize you do not use routing in your example, just posting this for any other person that might use routing and stumbled across this question.

Tombalabomba
  • 181
  • 1
  • 7
0

In my situation this error ocurred after pulling some changes and it wasn't working because i did not run "npm install".

Sonrimos
  • 77
  • 2
  • 9