2

I created basic Angular project on StackBlitz, and want to add my component. I right-click on src folder, Angular Generator > Component > test, which created folder 'test' with test component. But, when I try to add this component to my-app component template, I'm getting error:

Error in src/main.ts (15:5)
'app-test' is not a known element:
1. If 'app-test' is an Angular component, then verify that it is included in the '@Component.imports' of this component.
2. If 'app-test' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@Component.schemas' of this component to suppress this message.

verify it is included in the imports

If I go further and add import, then I get another error:

Error in src/main.ts (10:27)
The component 'TestComponent' appears in 'imports', but is not standalone and cannot be imported directly. It must be imported via an NgModule.

error: component is not standalone

So how to properly add component(s) to my angular project on StackBlitz? Project is here.

sam sergiy klok
  • 526
  • 7
  • 17

2 Answers2

7

First, please note that using standalone components is not the new Angular 15 default. Generate a new app with ng new and you'll find the expected module. The source of your troubles, is that StackBlitz decided to change their new app template in a way that harms the experience.

Using standalone components will actually complicate your life in a real application, but I digress.

You have two options to get your StackBlitz app working.

The first, as Harshit's answer shows partially, you can use standalone components throughout. It's the fewest changes you'll need, but quickly becomes onerous as your list of components grows. And if you're planning to copy the component to your app, you'll have to change it all back. Anyway, here's how:

Once you've generated a new component, add standalone: true to its @Component decorator.

@Component({
  standalone: true, <-- This is new
  selector: 'my-component',
  templateUrl: './my.component.html',
  styleUrls: ['./my.component.css'],
})
export class MyComponent implements OnInit {

Then, in every component that uses MyComponent, add it to that component's import clause:

@Component({
  selector: 'my-app',
  standalone: true,
  imports: [CommonModule, MyComponent], <-- This is changed
  template: `
    <h1>Hello from {{name}}!</h1>
    <my-component></my-component>
  `,
})
export class App {

The alternative is to convert the new StackBlitz app to use a module. This is better, but more work.

  1. Generate a new module, named AppModule.
  2. Generate a new component, named AppComponent.
  3. Replace the contents of main.ts with the following:
import 'zone.js/dist/zone';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';

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

At this point, StackBlitz goes nuts and tells you:

NG0400: A platform with a different configuration has been created.

To get rid of it, you need to save and reload the page.

  1. In app.module.ts, import your new component, bootstrap it, and import BrowserModule. In short, your @NgModule decorator should look like this:
@NgModule({
  imports: [CommonModule, BrowserModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
  1. Finally, change your component's selector to match the default in index.html. Normally, that's <my-app></my-app>, so you'll change your selector in app.component.ts to my-app:
@Component({
  selector: 'my-app', <-- This is changed
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})

Et voila! In five onerous steps, you can get StackBlitz back to a reasonable default. If you think that's daft, please let StackBlitz know on the GitHub issue.

Cobus Kruger
  • 8,338
  • 3
  • 61
  • 106
1

Read the error: The component 'TestComponent' appears in 'imports', but is **not standalone** and cannot be imported directly.

add standalone: true in your test.component.ts like below and then try to import.

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

@Component({
  standalone: true,
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css'],
})
export class TestComponent implements OnInit {
  constructor() {}

  ngOnInit() {}
}

Reference

Harshit T
  • 786
  • 4
  • 11
  • 1
    Component was generated, so why StackBlitz have default settings like so? My question is not how to fight and fix these issues, but how to properly add/generate components at StackBlitz, so such issues will not appear.. – sam sergiy klok Feb 26 '23 at 18:53
  • 1
    I removed standalone and got next error: Error in src/main.ts (10:12) 'imports' is only valid on a component that is standalone. ... So I'm chasing error after error. – sam sergiy klok Feb 26 '23 at 19:01
  • This is the standard actually. In the recent versions of angular they have introduced standalone components, and it is stable in v15+, that’s why stackblitz follows it because the codebase is light weight and blazing fast. Maybe they have written the logic to generate the new component in generic way, so that majority of older blitz do not fail. But the new ones can work easily if standalone property is added. – Harshit T Feb 27 '23 at 01:02
  • 1
    If you do not want standalone components, you will have to introduce modules for dependencies management (imports/exports). You can refer to this link for the reference: https://angular.io/generated/live-examples/getting-started-v0/stackblitz.html – Harshit T Feb 27 '23 at 01:05