# Standalone Components in Angular

Preview

Standalone Components, as of version 14 of Angular, are in PREVIEW. In the future though, they might be the default way of developing Angular apps.

Standalone Components is a feature that deals with the boiletplate code that we have to currently write in a typical Angular app. Namely, it enables us to create components without dealing with the modules and all their declarations, imports, and so on. We can actually get rid of modules entirely, even the AppModule! That makes Angular a bit more similar to React or Vue.js, which do not use the module system and are much leaner to work with.

Not Just Components

Standalone Components is not only about components. It's also Standalone ...

  • ... Pipes
  • ... Directives

Standalone components can be mixed with the "classic" NgModule style.

# Example


 





@Component({
    standalone: true,
    selector: 'app-my-component',
    templateUrl: './my-component.component.html'
})
export class MyComponent {}

Standalone components can't be declared in any module. standalone: true makes it recognizable globally.

There are two ways to use standalone components in other components:

  • new, when the parent component is also standalone
  • "legacy", with NgModule

# Standalone Parent



 





@Component({
    standalone: true,
    imports: [ MyComponent ],
    selector: 'app-my-other-component',
    templateUrl: './my-other-component.component.html'
})
export class MyOtherComponent {}

This way is very similar to how we'd do it in Vue.js.

# Legacy Parent

Since standalone components can be mixed with NgModule-declared components, there's a way to use standalone components in such "legacy" components.

First, we need to import the standalone component in our parent component's module:







 




@NgModule({
    declarations: [
        MyOtherComponent
    ],
    imports: [
        BrowserModule
        MyComponent
    ]
})
export class AppModule {}

TIP

Previously, we'd have to put MyComponent in the declarations instead of imports (assuming we had just one module in our app).

Now, the legacy component can make use of MyComponent in its template, as it typically would in "legacy" NgModule-based world.

# Importing Modules

The standalone components may not only import other standalone components, but also whole modules! It is useful when our app uses some "legacy" entities that are exported by some module(s). To use these entities, our component has to import the module.

If standalone component is the only thing that uses the imported module, that module does not need to be imported in any other module, as it would typiclaly be the case.

# Standalone Root Component

We can get rid of modules entirely, including the main AppModule. Without that module though, we need a different way of bootstrapping our app with the AppComponent:

bootstrapApplication(AppComponent);

As a reminder, here's the "legacy" way:

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

# Dependency Injection

With modules being gone, we need another way of providing services globally. Well there is the @Injectable constructor, but it's not everyone's favorite to provide service from the service itself.

We can use the new bootstrapApplication and it's second parameter:

bootstrapApplication(AppComponent,
{
    providers: [ MyService ]
});

MyService will be available globally.

# Routing and Lazy Loading

Lazy loading with standalone components is doable, it requires us to use a new loadComponent function in our routes to load the component dynamically.

The previously used loadChildren function is still useful. Instead of loading a module, we can use it to load a file containing child routes.

Last Updated: 1/15/2023, 6:32:34 PM