Angular 14 introduces the standalone component—a component not part of any ngModule that can be used with either other standalone or module-based components. This new feature provides a simplified way to create an Angular application without having to make custom Angular modules. In this article, we will explore what standalone components are, how to create and use them, and how they can enhance your Angular application.
What Is a Standalone Component?
A standalone component is a type of component which is not part of any Angular module. Prior to Angular 14, when creating a component, it was necessary to pass it inside the declarations array of a module. If this step was skipped, Angular would throw an error and not compile. However, with the introduction of Angular 14, it is now possible to create a component that is not part of any ngModule, and this component is known as a standalone component.
Besides standalone components, Angular 14 also allows for the creation of standalone directives and pipes. These standalone elements can be used with module-based components, other standalone components, and even in routes and lazy loading.
Is Creating a Standalone Component Feasible?
To create a standalone component, simply use the @Component decorator as you would with any other component, but do not include it in the declarations array of any module. Here’s an example of a basic standalone component:
@Component({
selector: 'app-standalone',
template: 'This is a standalone component'
})
export class StandaloneComponent
As you can see, there is no reference to any module in the code above. This is what makes it a standalone component.
What are the Dependencies in a Standalone Component?
Just like any other component, standalone components can have dependencies. However, since they are not part of any module, they cannot use the @NgModule decorator to declare their dependencies. Instead, they can use the @Injectabledecorator to inject dependencies into the component’s constructor. Here’s an example:
@Injectable()
export class DataService {
// data service logic
}
@Component({
selector: 'app-standalone',
template: 'This is a standalone component'
})
export class StandaloneComponent {
constructor(private dataService: DataService)
}
Using a Standalone Component
You can use a standalone component, directive or pipe in either of two ways:
- Inside another standalone component;
- Inside a module.
For both the options, pass it inside the imports array, and also keep in mind that you don’t pass standalone components in the declaration array of the modules.
So to use it inside AppComponent, which is part of AppModule, you can pass it to the imports array as shown below:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
LoginComponent
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
JavaScript
Now you can use it on the AppComponent as below:
<h1>App</h1>
<app-login></app-login>
HTML
You can use a standalone component in another standalone component by passing it to the imports property of that standalone component as shown below:
@Component({
selector: 'app-product',
standalone: true,
imports: [CommonModule, LoginComponent],
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
Is Bootstrapping a Standalone Component?
One way to use a standalone component is by bootstrapping it in the main.ts file of your application. This allows the component to be rendered on the page without being declared in any module. Here’s an example:
import from '@angular/platform-browser-dynamic';
import from './app/standalone.component';
platformBrowserDynamic().bootstrapModule(StandaloneComponent);
Is Routing Possible with a Standalone Component?
Standalone components can also be used in routing. To do this, you need to create a route for the component in the app-routing.module.ts file and then add it to the declarations array of the AppModule. Here’s an example:
const routes: Routes = [
];
@NgModule({
declarations: [StandaloneComponent],
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule
Adding Routes
To add additional child routes to a standalone component, you can use the children property in the route configuration. Here’s an example:
const routes: Routes = [
{
path: 'standalone',
component: StandaloneComponent,
children: [
,
]
}
];
Run the Application
To run the application with a standalone component, you can use the ng serve command as usual. However, since the standalone component is not declared in any module, it will not be included in the build process. To include it, you can use the –include flag when running the command. Here’s an example:
ng serve --include app/standalone.component
Lazy Loading a Standalone Component
Lazy loading allows for the loading of a component only when it is needed, reducing the initial load time of the application. This feature can also be used with standalone components by creating a separate module for the component and using the loadChildren property in the route configuration. Here’s an example:
const routes: Routes = [
{
path: 'lazy',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}
];
Lazily Loading Additional Child Routes
To lazily load additional child routes for a standalone component, you can use the children property in the route configuration, just like with regular routing. Here’s an example:
const routes: Routes = [
{
path: 'lazy',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule),
children: [
,
]
}
];
Configuring Dependency Injection
Standalone components can also have their own dependency injection configuration. This can be done by creating a separate module for the component and using the providers property to declare the dependencies. Here’s an example:
@NgModule({
declarations: [StandaloneComponent],
providers: [DataService]
})
export class StandaloneModule
Wrap-up
In summary, standalone components are a new feature introduced in Angular 14 that allows for the creation of components without having to declare them in any module. They can be used with module-based components, other standalone components, and even in routes and lazy loading. They also have their own dependency injection configuration, making them a powerful tool for building Angular applications.