cbutler
cbutler

Reputation: 933

Angular Uncaught Error: Template parse errors: is not a known element

I am trying to use babel standalone inside a react app to transpile Angular TypeScript. The transpiling does "work" however I get an error when I try to import a component and use it's selector inside the template of another component.

This is the error I get:

Uncaught Error: Template parse errors:
'search-bar' is not a known element:
1. If 'search-bar' is an Angular component, then verify that it is part of this module.
2. If 'search-bar' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

SearchBar Component (user code):

// ng is on the window object
const { Component, NgModule, Output, EventEmitter } = ng.core;
const { CommonModule } = ng.common;

@Component({
  selector: 'search-bar',
  template: `<div>Search Bar</div>`,
})
@NgModule({
  declarations: [SearchBar],
  exports: [SearchBar]
})
class SearchBar {}

export default SearchBar;

App Component (user code):

const { Component, NgModule, VERSION } = ng.core;
const { CommonModule } = ng.common;

// Note: The online editor does not need a path to the component :)
import SearchBar from 'SearchBar.ts';

@NgModule({
  imports: [
    CommonModule,
    SearchBar,
  ],
  declarations: [AppComponent, SearchBar],
})
@Component({
  selector: 'my-app',
  template: `<search-bar></search-bar>`
})
export default class AppComponent {

}

Please note, I am creating an online code editor so yes I need to use babel standalone. Here is my babel config for typescript:

(from my react app)

const TS_OPTIONS = {
  presets: [
    ['typescript', { allExtensions: true }],
    ['es2017', { 'modules': false }],
  ],
  plugins: [
    ["proposal-decorators", { "legacy": true }],
    ["proposal-class-properties", { "loose" : true }],
    'transform-modules-commonjs',
  ],
};

version of Babel:

https://unpkg.com/@babel/[email protected]/babel.min.js

My transpile function (simplified, also from my react app):

export default function transpile(myCode) {
  const { code } = Babel.transform(myCode, TS_OPTIONS);

  return myCode;
}

What am I missing?

Upvotes: 2

Views: 2192

Answers (2)

cbutler
cbutler

Reputation: 933

Somewhere along the way I made a mess of things and CodeMonkey rightly pointed out that I should not have NgModule in my components. I will credit him with the answer but just for completeness in case someone wants to see a working example. Note that there is some syntax specific to my online code editor (such as there being no need for a file path when importing components).

Main Component with Module:

// main.ts
// contains my module
const { Component, VERSION } = ng.core;
const { BrowserModule } = ng.platformBrowser;
const { NgModule } = ng.core;
const { CommonModule } = ng.common;

import AppComponent from 'App.ts';
import SearchBarComponent from 'SearchBar.ts';

@NgModule({
  imports: [
    BrowserModule,
    CommonModule,
  ],
  declarations: [AppComponent, SearchBarComponent],
  bootstrap: [AppComponent],
  providers: []
})
class AppModule {}

const { platformBrowserDynamic } = ng.platformBrowserDynamic;

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

App Component:

// App.ts
const { Component } = ng.core;

@Component({
  selector: 'my-app',
  template: `
  <h1 [innerHTML]="title"></h1>
  <search-bar></search-bar>`
})
export default class AppComponent {
  title;

  constructor() {}

  ngOnInit() {
    this.title= "Hello World!";
  }
}

SearchBar Component:

// SearchBar.ts
const { Component } = ng.core;

@Component({
  selector: 'search-bar',
  template: `<h1>Search Bar</h1>`
})
export default class SearchBarComponent {}

Upvotes: 1

CodeMonkey
CodeMonkey

Reputation: 3331

My first thought looking at this code is that I have not come across a class that is both and module and a component, my feeling is that they need to be two separate classes.

// ng is on the window object
const { Component, NgModule, Output, EventEmitter } = ng.core;

@Component({
  selector: 'search-bar',
  template: `<div>Search Bar</div>`,
})
export class SearchBar {}

@NgModule({
  declarations: [SearchBar],
  exports: [SearchBar]
})
export class SearchModule {}

Do you have any examples of dual purpose classes working anywhere else?

Upvotes: 0

Related Questions