To create a custom decorator in Angular, you define a function that returns a function which is applied to the target. For example:
function LogClass(target: Function) {
console.log("Class:", target);
}
@LogClass
class ExampleClass {}
Angular Guards are interfaces that allow you to control access to routes. They are implemented by creating classes that implement one or more of the guard interfaces:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(): boolean {
const isLoggedIn = /* logic to check if the user is logged in */;
if (isLoggedIn) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
You can create dynamic forms using FormBuilder
and FormGroup
. Here's an example:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-dynamic-form',
template: \`
\`
})
export class DynamicFormComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: [''],
age: ['']
});
}
}
Angular's default change detection strategy is CheckAlways
, where Angular checks all components to see if they need to be updated. You can use the OnPush
strategy to optimize performance, which only checks the component when its inputs change or when an event occurs:
import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
selector: 'app-on-push',
templateUrl: './on-push.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class OnPushComponent {
// Component logic
}
State management in Angular can be handled using libraries like NgRx
or Akita
. For example, using NgRx involves creating actions, reducers, and selectors:
import { createAction, props } from '@ngrx/store';
export const loadItems = createAction('[Items Page] Load Items');
export const loadItemsSuccess = createAction('[Items API] Items Loaded Success', props<{ items: any[] }>());
import { createReducer, on } from '@ngrx/store';
export const initialState = [];
const _itemsReducer = createReducer(
initialState,
on(loadItemsSuccess, (state, { items }) => [...items])
);
export function itemsReducer(state, action) {
return _itemsReducer(state, action);
}
Dependency Injection (DI) in Angular allows you to inject dependencies (services) into components and other services. You can use it by defining a service and then injecting it into a component:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
// Service logic
}
import { Component } from '@angular/core';
import { MyService } from './my.service';
@Component({
selector: 'app-example',
template: \`Example component
\`
})
export class ExampleComponent {
constructor(private myService: MyService) {}
}
The HttpClient
module is used to make HTTP requests. Here's an example of making a GET request:
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
@Component({
selector: 'app-api',
template: \`Data: {{ data | json }}
\`
})
export class ApiComponent {
data: any;
constructor(private http: HttpClient) {
this.http.get('https://api.example.com/data')
.subscribe(response => {
this.data = response;
});
}
}
Performance can be optimized using techniques such as lazy loading, trackBy in ngFor, and OnPush change detection strategy:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
{{ item.name }}
trackById(index: number, item: any): number {
return item.id;
}
Reactive Forms provide a model-driven approach to handle form inputs. They offer advantages like better scalability, easier unit testing, and more control over form validation:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
template: \`
\`
})
export class ReactiveFormComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: ['', Validators.required],
email: ['', [Validators.required, Validators.email]]
});
}
onSubmit() {
console.log(this.form.value);
}
}
To handle routes with parameters, define parameters in the route configuration and access them in the component:
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-route-param',
template: \`Param: {{ id }}
\`
})
export class RouteParamComponent implements OnInit {
id: string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.paramMap.subscribe(params => {
this.id = params.get('id');
});
}
}
NgZone
allows you to run code inside or outside Angular's change detection. This is useful for optimizing performance:
import { NgZone } from '@angular/core';
@Component({
selector: 'app-ngzone',
template: \`NgZone example
\`
})
export class NgZoneComponent {
constructor(private ngZone: NgZone) {
this.ngZone.runOutsideAngular(() => {
// Code that does not trigger change detection
});
}
}
Create a library using Angular CLI and then include it in your application:
ng generate library my-lib
ng build my-lib
// In your application module
import { MyLibModule } from 'my-lib';
@NgModule({
imports: [MyLibModule]
})
export class AppModule { }
Angular Universal is used for server-side rendering (SSR). It allows rendering Angular applications on the server before sending them to the client:
ng add @nguniversal/express-engine
// server.ts
import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '@nguniversal/express-engine';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import { AppServerModule } from './src/main.server';
const app = express();
app.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
providers: [provideModuleMap(LAZY_MODULE_MAP)]
}));
Custom pipes are created by implementing the PipeTransform
interface:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customPipe'
})
export class CustomPipe implements PipeTransform {
transform(value: string, ...args: any[]): string {
return value.toUpperCase();
}
}
Angular provides several built-in validators for forms:
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-validators',
template: \`
\`
})
export class ValidatorsComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6)]]
});
}
}
Content projection allows you to pass content into a component's template. Use the <ng-content>
directive:
import { Component } from '@angular/core';
@Component({
selector: 'app-content-projection',
template: \`
\`
})
export class ContentProjectionComponent {}
Feature modules can be lazy-loaded by configuring routes with loadChildren
:
const routes: Routes = [
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];
Observables are used to handle asynchronous data. Use the subscribe
method to react to data changes:
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { DataService } from './data.service';
@Component({
selector: 'app-observable',
template: \`Data: {{ data | json }}
\`
})
export class ObservableComponent implements OnInit {
data$: Observable;
constructor(private dataService: DataService) {}
ngOnInit() {
this.data$ = this.dataService.getData();
}
}
ViewChild
allows you to access a child component or element in your template:
import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: \` \`
})
export class ParentComponent {
@ViewChild('childRef') childComponent: ChildComponent;
ngAfterViewInit() {
console.log(this.childComponent);
}
}
Lifecycle hooks are methods in Angular that allow you to tap into key moments of a component's lifecycle:
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-lifecycle',
template: \`Lifecycle hooks example
\`
})
export class LifecycleComponent implements OnInit, OnDestroy {
ngOnInit() {
console.log('Component Initialized');
}
ngOnDestroy() {
console.log('Component Destroyed');
}
}
Custom validators are used to add validation logic to form controls. Implement a custom validator by creating a function that returns either null or an object indicating the validation error:
import { AbstractControl, ValidatorFn } from '@angular/forms';
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} | null => {
const forbidden = nameRe.test(control.value);
return forbidden ? { 'forbiddenName': { value: control.value } } : null;
};
}
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-custom-validator',
template: \`
\`
})
export class CustomValidatorComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: ['', [forbiddenNameValidator(/admin/)]]
});
}
}
To provide multiple instances of a service, use different providers with a unique token:
import { Injectable, InjectionToken } from '@angular/core';
export const MY_SERVICE_TOKEN = new InjectionToken('MyService');
@Injectable()
export class MyService {
constructor() {}
}
@NgModule({
providers: [
{ provide: MY_SERVICE_TOKEN, useClass: MyService }
]
})
export class AppModule { }
Use an HTTP interceptor to catch and handle HTTP errors:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler) {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
console.error('HTTP Error:', error);
return throwError(error);
})
);
}
}
Define child routes within a parent route configuration:
const routes: Routes = [
{
path: 'parent',
component: ParentComponent,
children: [
{ path: 'child1', component: Child1Component },
{ path: 'child2', component: Child2Component }
]
}
];
NgRx Effects allow you to handle side effects in your application. Create effects to listen for actions and perform tasks like HTTP requests:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { MyService } from './my.service';
import { loadItems, loadItemsSuccess } from './actions';
import { switchMap } from 'rxjs/operators';
@Injectable()
export class MyEffects {
loadItems$ = createEffect(() =>
this.actions$.pipe(
ofType(loadItems),
switchMap(() => this.myService.getItems()
.pipe(map(items => loadItemsSuccess({ items })))
)
)
);
constructor(
private actions$: Actions,
private myService: MyService
) {}
}
Custom directives are used to extend HTML behavior. Create a directive by defining a class and using the @Directive
decorator:
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.removeStyle(this.el.nativeElement, 'backgroundColor');
}
}
Angular provides different encapsulation strategies for component styles. Use ViewEncapsulation
to control this:
import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'app-encapsulation', template: \`
Encapsulation example
\`, styles: [\` p { color: red; } \`], encapsulation: ViewEncapsulation.None }) export class EncapsulationComponent {}
Use the loadChildren
property in route configurations to lazy-load modules:
const routes: Routes = [
{ path: 'lazy', loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) }
];
ChangeDetectorRef
provides methods to manually trigger change detection in a component:
import { ChangeDetectorRef, Component } from '@angular/core'; @Component({ selector: 'app-change-detection', template: \`
Change detection example
\` }) export class ChangeDetectionComponent { constructor(private cdr: ChangeDetectorRef) {} detectChanges() { this.cdr.detectChanges(); } }
Renderer2
is used to safely manipulate the DOM in Angular. Here’s an example of adding a class to an element:
import { Component, ElementRef, Renderer2 } from '@angular/core'; @Component({ selector: 'app-renderer', template: \`
Renderer2 Example
\` }) export class RendererComponent { constructor(private el: ElementRef, private renderer: Renderer2) {} ngAfterViewInit() { const div = this.el.nativeElement.querySelector('div'); this.renderer.addClass(div, 'highlight'); } }
AsyncPipe
allows you to subscribe to observables directly in the template:
import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { DataService } from './data.service'; @Component({ selector: 'app-async-pipe', template: \`
Data: {{ data$ | async | json }}
\` }) export class AsyncPipeComponent implements OnInit { data$: Observable
; constructor(private dataService: DataService) {} ngOnInit() { this.data$ = this.dataService.getData(); } }
ChangeDetectionStrategy
controls how Angular checks for changes in a component. Use ChangeDetectionStrategy.OnPush
to optimize performance:
import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'app-change-detection-strategy', template: \`
Change Detection Strategy Example
\`, changeDetection: ChangeDetectionStrategy.OnPush }) export class ChangeDetectionStrategyComponent {}
HostBinding
and HostListener
are used to bind properties and listen to events on the host element:
import { Component, HostBinding, HostListener } from '@angular/core'; @Component({ selector: 'app-host', template: \`
Host Binding and Listener Example
\` }) export class HostComponent { @HostBinding('class.highlight') isHighlighted = true; @HostListener('click') onClick() { this.isHighlighted = !this.isHighlighted; } }
ngOnChanges
is called when an input property value changes:
import { Component, OnChanges, SimpleChanges, Input } from '@angular/core'; @Component({ selector: 'app-on-changes', template: \`
On Changes Example
\` }) export class OnChangesComponent implements OnChanges { @Input() data: any; ngOnChanges(changes: SimpleChanges) { console.log('Changes:', changes); } }
ng-container
and ng-template
are used to manage templates and control the rendering:
Content to render
import { Component } from '@angular/core'; @Component({ selector: 'app-container', template: \`
Content is visible
Content is hidden
\` }) export class ContainerComponent { showContent = true; }
Manage environment configurations using environment files:
// environment.ts
export const environment = {
production: false,
apiUrl: 'http://localhost:3000'
};
// environment.prod.ts
export const environment = {
production: true,
apiUrl: 'https://api.example.com'
};
Custom structural directives are created using the *ngIf
and *ngFor
syntax:
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appMyDirective]'
})
export class MyDirective {
constructor(private templateRef: TemplateRef, private viewContainer: ViewContainerRef) {}
@Input() set appMyDirective(condition: boolean) {
this.viewContainer.clear();
if (condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
}
Global error handling is configured using an error handler class:
import { Injectable, ErrorHandler } from '@angular/core';
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
handleError(error: any) {
console.error('Global error:', error);
}
}
@NgModule({
providers: [{ provide: ErrorHandler, useClass: GlobalErrorHandler }]
})
export class AppModule { }
Internationalization is handled using the Angular i18n package:
ng add @angular/localize // app.component.html
Hello
// Extract messages ng extract-i18n // Translate and build for a specific locale ng build --localize
Renderer2
can be used to dynamically create and manipulate components:
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
@Component({
selector: 'app-dynamic',
template: \` \`
})
export class DynamicComponentLoader {
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) {}
loadComponent() {
const factory = this.resolver.resolveComponentFactory(DynamicComponent);
this.container.clear();
this.container.createComponent(factory);
}
}
Custom pipes are used to transform data in the template. Create a pipe by defining a class and using the @Pipe
decorator:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customPipe'
})
export class CustomPipe implements PipeTransform {
transform(value: string, ...args: any[]): string {
return value.toUpperCase();
}
}
ChangeDetectorRef
can be used to manually control change detection, such as when you need to update the view outside of Angular's default change detection cycle:
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-manual-change', template: \`
{{ data }}
\` }) export class ManualChangeComponent { data = 'Initial data'; constructor(private cdr: ChangeDetectorRef) {} updateData() { this.data = 'Updated data'; this.cdr.detectChanges(); } }
Reactive forms allow for more complex validation logic. Here’s how to create a form with custom validators:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
template: \`
\`
})
export class ReactiveFormComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
username: ['', [this.forbiddenNameValidator(/admin/)]]
});
}
forbiddenNameValidator(nameRe: RegExp) {
return (control: AbstractControl): {[key: string]: any} | null => {
const forbidden = nameRe.test(control.value);
return forbidden ? { 'forbiddenName': { value: control.value } } : null;
};
}
onSubmit() {
console.log(this.form.value);
}
}
Use Angular's ComponentFactoryResolver
to dynamically load components:
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
@Component({
selector: 'app-dynamic-loader',
template: \` \`
})
export class DynamicLoaderComponent {
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) {}
loadComponent() {
const factory = this.resolver.resolveComponentFactory(DynamicComponent);
this.container.clear();
this.container.createComponent(factory);
}
}
Lazy loading modules allows for more efficient loading of Angular applications. Define a lazy-loaded module in your routing configuration:
const routes: Routes = [
{
path: 'lazy',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}
];
NgRx provides a way to manage state in Angular applications using a store. Define actions, reducers, and effects:
import { createAction, createReducer, on } from '@ngrx/store';
// Actions
export const loadItems = createAction('[Item] Load Items');
export const loadItemsSuccess = createAction('[Item] Load Items Success', (items: any[]) => ({ items }));
// Reducer
export const initialState = [];
const _itemsReducer = createReducer(
initialState,
on(loadItemsSuccess, (state, { items }) => [...items])
);
export function itemsReducer(state, action) {
return _itemsReducer(state, action);
}
Structural directives change the structure of the DOM. Create a custom structural directive like this:
import { Directive, TemplateRef, ViewContainerRef, Input } from '@angular/core';
@Directive({
selector: '[appUnless]'
})
export class UnlessDirective {
constructor(private templateRef: TemplateRef, private viewContainer: ViewContainerRef) {}
@Input() set appUnless(condition: boolean) {
if (!condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
}
HostListener
can be used to listen to events on the host element of a component:
import { Component, HostListener } from '@angular/core'; @Component({ selector: 'app-host-listener', template: \`
Host Listener Example
\` }) export class HostListenerComponent { @HostListener('click', ['$event']) onClick(event: Event) { console.log('Host element clicked:', event); } }
ng-content
allows you to project content into a component:
import { Component } from '@angular/core';
@Component({
selector: 'app-content',
template: \` \`
})
export class ContentComponent {}
@ContentChild
and @ContentChildren
are used to access content projected into a component:
import { Component, ContentChild, ContentChildren, QueryList } from '@angular/core';
@Component({
selector: 'app-content-query',
template: \` \`
})
export class ContentQueryComponent {
@ContentChild('contentRef') contentChild: ElementRef;
@ContentChildren('contentRef') contentChildren: QueryList;
}
Custom decorators can be used to add metadata to classes or methods:
import { createDecorator } from '@angular/core';
export function CustomDecorator(message: string) {
return createDecorator((target: Function) => {
target.prototype.customMessage = message;
});
}
@CustomDecorator('Hello World')
export class CustomClass {
customMessage: string;
}
Dependency injection scopes can be controlled using the providedIn
property:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Singleton scope
})
export class MyService {}
@Injectable({
providedIn: 'any' // Scoped to any module or component
})
export class ScopedService {}
HTTP interceptors can be used to modify requests and responses globally:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
const authReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer my-token')
});
return next.handle(authReq);
}
}
Router guards can be used to protect routes based on conditions:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(): Observable | Promise | boolean {
const isAuthenticated = false; // Implement your authentication check here
if (!isAuthenticated) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}
NgModule
helps in organizing an application into cohesive blocks of functionality:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { FeatureModule } from './feature/feature.module';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
FeatureModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
Custom validators can be created and used in reactive forms:
import { AbstractControl, ValidatorFn } from '@angular/forms';
export function passwordMatchValidator(): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} | null => {
const password = control.get('password');
const confirmPassword = control.get('confirmPassword');
return password && confirmPassword && password.value !== confirmPassword.value
? { 'mismatch': true }
: null;
};
}
@ViewChild
and @ViewChildren
are used to query and access elements or directives in the component's view:
import { Component, ViewChild, ViewChildren, QueryList } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: \`
\`
})
export class ParentComponent {
@ViewChild('child') child: ChildComponent;
@ViewChildren('children') children: QueryList;
}
Lazy loading modules with route parameters involves passing parameters to the route and configuring the module accordingly:
const routes: Routes = [
{
path: 'lazy/:id',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}
];
Renderer2
is used for safe and compatible DOM manipulation:
import { Component, Renderer2, ElementRef } from '@angular/core'; @Component({ selector: 'app-renderer', template: \`
Content
\` }) export class RendererComponent { constructor(private renderer: Renderer2, private el: ElementRef) {} changeColor() { this.renderer.setStyle(this.el.nativeElement.querySelector('div'), 'color', 'red'); } }
ngOnInit
is called after the component is initialized, while ngAfterViewInit
is called after the view has been fully initialized:
import { Component, OnInit, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-lifecycle', template: \`
Lifecycle Hooks Example
\` }) export class LifecycleComponent implements OnInit, AfterViewInit { ngOnInit() { console.log('OnInit called'); } ngAfterViewInit() { console.log('AfterViewInit called'); } }
Feature modules help to organize an Angular application into cohesive blocks. Here's how to set up a feature module:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
import { FeatureRoutingModule } from './feature-routing.module';
@NgModule({
declarations: [FeatureComponent],
imports: [
CommonModule,
FeatureRoutingModule
]
})
export class FeatureModule { }
Custom directives are used to extend the behavior of elements. Here’s an example of a custom directive:
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'transparent');
}
}
When you need to provide multiple instances or configurations of a service, you can use multi-provider tokens:
import { InjectionToken, Injectable, Inject } from '@angular/core';
export const CONFIG = new InjectionToken('app.config');
@Injectable({
providedIn: 'root'
})
export class ConfigService {
constructor(@Inject(CONFIG) private config: string[]) {}
}
// In a module
@NgModule({
providers: [
{ provide: CONFIG, useValue: ['config1', 'config2'], multi: true }
]
})
export class AppModule { }
To optimize performance, you can use techniques like lazy loading, Ahead-of-Time (AOT) compilation, and change detection strategies:
import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
selector: 'app-performance',
templateUrl: './performance.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PerformanceComponent {}
Dynamic forms are built based on data received at runtime. Use Angular’s reactive forms to create dynamic controls:
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
@Component({
selector: 'app-dynamic-form',
template: \`
\`
})
export class DynamicFormComponent implements OnInit {
form: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.form = this.fb.group({
items: this.fb.array([this.fb.control('')])
});
}
get items() {
return this.form.get('items') as FormArray;
}
addItem() {
this.items.push(this.fb.control(''));
}
}
Lazy load a module with nested routes by defining child routes in the lazy-loaded module:
const routes: Routes = [
{
path: 'lazy',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule),
children: [
{ path: 'child', component: ChildComponent }
]
}
];
NgZone
helps to execute code outside Angular's change detection:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-ngzone', template: \`
NgZone Example
\` }) export class NgZoneComponent { constructor(private ngZone: NgZone) { this.ngZone.runOutsideAngular(() => { // Code running outside Angular's zone }); } }
Angular Universal allows you to perform server-side rendering to improve performance and SEO. Install Angular Universal and configure it:
ng add @nguniversal/express-engine
// Configure server.ts and other settings
Handle route and query parameters in Angular components:
import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-route', template: \`
Route Parameter: {{ param }}
\` }) export class RouteComponent implements OnInit { param: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.paramMap.subscribe(params => { this.param = params.get('id'); }); this.route.queryParams.subscribe(queryParams => { console.log(queryParams); }); } }
Create custom elements with Angular and use them in other applications:
import { Component, NgModule } from '@angular/core'; import { createCustomElement } from '@angular/elements'; import { BrowserModule } from '@angular/platform-browser'; import { Injector } from '@angular/core'; @Component({ selector: 'app-custom-element', template: \`
Custom Element
\` }) export class CustomElementComponent {} @NgModule({ declarations: [CustomElementComponent], imports: [BrowserModule], entryComponents: [CustomElementComponent] }) export class AppModule { constructor(private injector: Injector) { const el = createCustomElement(CustomElementComponent, { injector }); customElements.define('custom-element', el); } ngDoBootstrap() {} }
Use HttpClient
for advanced HTTP operations like interceptors, retries, and request caching:
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { catchError, retry } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private http: HttpClient) {}
getData() {
return this.http.get('https://api.example.com/data', {
headers: new HttpHeaders({
'Authorization': 'Bearer my-token'
})
}).pipe(
retry(3),
catchError(this.handleError)
);
}
private handleError(error: any) {
console.error('An error occurred', error);
return throwError(error);
}
}
Internationalization and localization involve translating your application into different languages:
ng add @angular/localize
// Use i18n attributes in templates
// Configure locales and translations
Renderer2
provides a way to safely interact with the DOM:
import { Component, Renderer2, ElementRef } from '@angular/core'; @Component({ selector: 'app-renderer2', template: \`
Renderer2 Example
\` }) export class Renderer2Component { constructor(private renderer: Renderer2, private el: ElementRef) { this.renderer.setStyle(this.el.nativeElement, 'color', 'blue'); } }
Use Angular's Animation API to create complex animations:
import { trigger, transition, style, animate } from '@angular/animations'; @Component({ selector: 'app-animation', template: \`
Content
\`, animations: [ trigger('fadeInOut', [ transition(':enter', [ style({ opacity: 0 }), animate('1s', style({ opacity: 1 })) ]), transition(':leave', [ animate('1s', style({ opacity: 0 })) ]) ]) ] }) export class AnimationComponent { state = 'in'; }
Optimize performance by using ChangeDetectionStrategy.OnPush
:
import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'app-optimization', template: \`
Optimization Example
\`, changeDetection: ChangeDetectionStrategy.OnPush }) export class OptimizationComponent {}
Use @ContentChild
and @ContentChildren
to query and access projected content:
import { Component, ContentChild, ContentChildren, QueryList } from '@angular/core';
import { ContentComponent } from './content.component';
@Component({
selector: 'app-parent',
template: \` \`
})
export class ParentComponent {
@ContentChild(ContentComponent) content: ContentComponent;
@ContentChildren(ContentComponent) contentChildren: QueryList;
}
Use @HostListener
to listen to events on the host element and @HostBinding
to bind properties:
import { Component, HostListener, HostBinding } from '@angular/core'; @Component({ selector: 'app-host', template: \`
Host Binding and Listener Example
\` }) export class HostComponent { @HostBinding('class.active') isActive = true; @HostListener('click') onClick() { this.isActive = !this.isActive; } }
NgModel
enables two-way data binding in Angular forms:
import { Component } from '@angular/core'; @Component({ selector: 'app-model', template: \`
Value: {{ value }}
\` }) export class ModelComponent { value = ''; }
Global error handling can be configured with HTTP interceptors:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
return next.handle(req).pipe(
catchError(error => {
console.error('An error occurred', error);
return throwError(error);
})
);
}
}
Set up a service worker to enable PWA features:
ng add @angular/pwa
// Configure ngsw-config.json for caching strategies
Dynamic component loading allows you to load components at runtime. Use ComponentFactoryResolver
:
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
@Component({
selector: 'app-dynamic-loader',
template: \` \`
})
export class DynamicLoaderComponent {
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private cfr: ComponentFactoryResolver) {}
loadComponent() {
const factory = this.cfr.resolveComponentFactory(DynamicComponent);
this.container.createComponent(factory);
}
}
@Inject
is used for dependency injection with tokens, while @Optional
allows you to handle missing dependencies:
import { Injectable, Inject, Optional } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Inject('TOKEN') @Optional() private token: string) {
if (!token) {
console.log('No token provided');
}
}
}
@ViewChild
with static
or dynamic
allows you to control when the view query is resolved:
import { Component, ViewChild, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-viewchild', template: \`
Text
\` }) export class ViewChildComponent implements AfterViewInit { @ViewChild('paragraph', { static: true }) paragraph; ngAfterViewInit() { console.log(this.paragraph.nativeElement.textContent); } }
NgRx provides a way to manage state in Angular applications using Redux principles. Set up actions, reducers, and effects:
import { createAction, props } from '@ngrx/store';
export const loadItems = createAction('[Items Page] Load Items');
export const loadItemsSuccess = createAction('[Items API] Load Items Success', props<{ items: any[] }>());
export const loadItemsFailure = createAction('[Items API] Load Items Failure', props<{ error: any }>());
Configure lazy-loaded modules in your app's routing module:
const routes: Routes = [
{
path: 'feature',
loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
}
];
Create custom validators for reactive forms:
import { AbstractControl, ValidatorFn } from '@angular/forms';
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const forbidden = nameRe.test(control.value);
return forbidden ? { 'forbiddenName': { value: control.value } } : null;
};
}
// Usage in a form
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-custom-validation',
template: \`
\`
})
export class CustomValidationComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: ['', [forbiddenNameValidator(/admin/)]]
});
}
}
Use @ContentChildren
to query multiple projected elements:
import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { ContentComponent } from './content.component';
@Component({
selector: 'app-parent',
template: \` \`
})
export class ParentComponent implements AfterContentInit {
@ContentChildren(ContentComponent) contentComponents: QueryList;
ngAfterContentInit() {
this.contentComponents.forEach(component => {
console.log(component.someProperty);
});
}
}
Router guards help manage navigation based on conditions like authentication:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(): boolean {
const isAuthenticated = false; // Replace with real authentication check
if (!isAuthenticated) {
this.router.navigate(['/login']);
}
return isAuthenticated;
}
}
Control component styles encapsulation with @ViewEncapsulation
:
import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'app-encapsulation', template: \`
Encapsulation Example
\`, styles: [\` p { color: red; } \`], encapsulation: ViewEncapsulation.None }) export class EncapsulationComponent {}
Use @HostListener
to listen to events like click or hover:
import { Component, HostListener } from '@angular/core'; @Component({ selector: 'app-host-listener', template: \`
Host Listener Example
\` }) export class HostListenerComponent { @HostListener('click', ['$event']) onClick(event: Event) { console.log('Element clicked', event); } }
@HostBinding
allows you to bind properties like classes or styles:
import { Component, HostBinding } from '@angular/core'; @Component({ selector: 'app-host-binding', template: \`
Host Binding Example
\` }) export class HostBindingComponent { @HostBinding('class.active') isActive = true; }
Use @Injectable
with providedIn to control hierarchical injection:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Hierarchical injectors are created with this configuration
})
export class MyService {}
Factory providers allow custom instantiation of services:
import { NgModule } from '@angular/core';
export function myServiceFactory() {
return new MyService();
}
@NgModule({
providers: [
{ provide: MyService, useFactory: myServiceFactory }
]
})
export class AppModule {}
Inject values using tokens and @Inject
:
import { Injectable, InjectionToken, Inject } from '@angular/core';
export const MY_TOKEN = new InjectionToken('MyToken');
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Inject(MY_TOKEN) private token: string) {}
}
Use HTTP interceptors to modify requests and responses:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
const authReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer token')
});
return next.handle(authReq);
}
}
Configure application-wide services in @NgModule
:
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { MyService } from './my.service';
@NgModule({
declarations: [AppComponent],
imports: [],
providers: [MyService],
bootstrap: [AppComponent]
})
export class AppModule {}
Access child components with @ViewChild
:
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: \` \`
})
export class ParentComponent implements AfterViewInit {
@ViewChild(ChildComponent) childComponent: ChildComponent;
ngAfterViewInit() {
console.log(this.childComponent.someMethod());
}
}
Use ChangeDetectorRef
for manual change detection:
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-manual-detection', template: \`
Manual Detection Example
\` }) export class ManualDetectionComponent { constructor(private cdr: ChangeDetectorRef) {} triggerChangeDetection() { this.cdr.detectChanges(); } }
Define feature modules and configure lazy loading in @NgModule
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: 'feature',
loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Manage hierarchical dependencies with @Injectable
:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // or 'platform' or 'any'
})
export class MyService {}
Define custom directives to extend HTML behavior:
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.removeStyle(this.el.nativeElement, 'backgroundColor');
}
}
Create custom pipes to transform data in templates:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'reverse'
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Use @Input
to pass data from parent to child, and @Output
to emit events from child to parent:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: \`\`
})
export class ChildComponent {
@Input() data: string;
@Output() notify = new EventEmitter();
notifyParent() {
this.notify.emit('Message from child');
}
}
@Component({
selector: 'app-parent',
template: \` \`
})
export class ParentComponent {
parentData = 'Data from parent';
onNotify(message: string) {
console.log(message);
}
}
Configure lazy-loaded modules and route guards in your routing module:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from './auth.guard';
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
canActivate: [AuthGuard]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Provide services at different levels using @NgModule
:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyService } from './my.service';
@NgModule({
imports: [CommonModule],
providers: [MyService]
})
export class FeatureModule {}
Listen to DOM events using @HostListener
:
import { Component, HostListener } from '@angular/core'; @Component({ selector: 'app-host-listener', template: \`
Click me!
\` }) export class HostListenerComponent { @HostListener('click', ['$event']) onClick(event: Event) { console.log('Element clicked:', event); } }
Use @ContentChild
and @ContentChildren
to query projected content:
import { Component, ContentChild, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { ContentComponent } from './content.component';
@Component({
selector: 'app-container',
template: \` \`
})
export class ContainerComponent implements AfterContentInit {
@ContentChild(ContentComponent) contentChild: ContentComponent;
@ContentChildren(ContentComponent) contentChildren: QueryList;
ngAfterContentInit() {
console.log(this.contentChild);
this.contentChildren.forEach(child => console.log(child));
}
}
Load components dynamically using ComponentFactoryResolver
:
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
@Component({
selector: 'app-dynamic',
template: \` \`
})
export class DynamicComponentLoader {
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private cfr: ComponentFactoryResolver) {}
loadComponent() {
const factory = this.cfr.resolveComponentFactory(DynamicComponent);
this.container.createComponent(factory);
}
}
Optimize performance using ChangeDetectionStrategy.OnPush
:
import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app-optimization', template: \`
Change Detection Strategy
\`, changeDetection: ChangeDetectionStrategy.OnPush }) export class OptimizationComponent {}
Control change detection with NgZone
:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-ngzone', template: \`
NgZone Example
\` }) export class NgZoneComponent { constructor(private ngZone: NgZone) { this.ngZone.runOutsideAngular(() => { setTimeout(() => { this.ngZone.run(() => console.log('Change detection triggered')); }, 1000); }); } }
Make HTTP requests using HttpClient
:
import { HttpClient } from '@angular/common/http'; import { Component } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'app-http', template: \`
HTTP Request Example
\` }) export class HttpComponent { constructor(private http: HttpClient) {} getData(): Observable
{ return this.http.get('https://api.example.com/data'); } }
Define service providers at different levels:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Service provided at the root level
})
export class MyService {}
Configure third-party library providers in @NgModule
:
import { NgModule } from '@angular/core';
import { SomeLibraryModule, SomeService } from 'some-library';
@NgModule({
imports: [SomeLibraryModule],
providers: [SomeService]
})
export class AppModule {}
Access route and query parameters using Router
:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-route', template: \`
Route Example
\` }) export class RouteComponent implements OnInit { constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.paramMap.subscribe(params => { const id = params.get('id'); console.log('Route parameter id:', id); }); this.route.queryParamMap.subscribe(params => { const filter = params.get('filter'); console.log('Query parameter filter:', filter); }); } }
Create structural directives to manipulate DOM layout:
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appUnless]'
})
export class UnlessDirective {
constructor(private templateRef: TemplateRef, private vcr: ViewContainerRef) {}
set appUnless(condition: boolean) {
if (!condition) {
this.vcr.createEmbeddedView(this.templateRef);
} else {
this.vcr.clear();
}
}
}
Control view encapsulation with encapsulation
property:
import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'app-encapsulation', template: \`
View Encapsulation Example
\`, encapsulation: ViewEncapsulation.None // or Emulated, Native }) export class EncapsulationComponent {}
Define root and feature modules in your application:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { FeatureModule } from './feature/feature.module';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FeatureModule],
bootstrap: [AppComponent]
})
export class AppModule {}
Configure providers and imports in feature modules:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
import { FeatureService } from './feature.service';
@NgModule({
declarations: [FeatureComponent],
imports: [CommonModule],
providers: [FeatureService]
})
export class FeatureModule {}
Manage hierarchical dependencies using @Injectable
:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // or 'platform', 'any'
})
export class HierarchicalService {}
Combine ChangeDetectorRef
and NgZone
to control change detection:
import { Component, ChangeDetectorRef, NgZone } from '@angular/core'; @Component({ selector: 'app-change-detection', template: \`
Change Detection Example
\` }) export class ChangeDetectionComponent { constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) {} triggerChangeDetection() { this.ngZone.run(() => this.cdr.detectChanges()); } }
Use @Inject
to specify the token for dependency injection:
import { Injectable, Inject } from '@angular/core';
import { MY_TOKEN } from './tokens';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Inject(MY_TOKEN) private myValue: string) {}
}
Use @Optional
to inject dependencies that may or may not be provided:
import { Injectable, Optional } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Optional() private optionalDependency?: SomeService) {}
}
Implement ngAfterViewInit
to perform actions after the component's view has been initialized:
import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-after-view', template: \`
Content
\` }) export class AfterViewComponent implements AfterViewInit { @ViewChild('pElement') pElement: ElementRef; ngAfterViewInit() { console.log(this.pElement.nativeElement.textContent); } }
Use ngOnChanges
to react to changes in input properties:
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; @Component({ selector: 'app-on-changes', template: \`
{{inputProp}}
\` }) export class OnChangesComponent implements OnChanges { @Input() inputProp: string; ngOnChanges(changes: SimpleChanges) { console.log('Changes:', changes); } }
Implement ngDoCheck
to customize change detection behavior:
import { Component, DoCheck } from '@angular/core'; @Component({ selector: 'app-do-check', template: \`
Custom Change Detection
\` }) export class DoCheckComponent implements DoCheck { ngDoCheck() { console.log('Custom change detection'); } }
Initialize data using ngOnInit
:
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-on-init', template: \`
Initialized Data: {{data}}
\` }) export class OnInitComponent implements OnInit { data: string; ngOnInit() { this.data = 'Initial Data'; } }
Use ngOnDestroy
to perform cleanup tasks:
import { Component, OnDestroy } from '@angular/core'; @Component({ selector: 'app-on-destroy', template: \`
Cleanup Example
\` }) export class OnDestroyComponent implements OnDestroy { ngOnDestroy() { console.log('Cleanup tasks'); } }
Access child components or DOM elements using @ViewChild
:
import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
selector: 'app-view-child',
template: \`\`
})
export class ViewChildComponent {
@ViewChild('inputElement') inputElement: ElementRef;
ngAfterViewInit() {
this.inputElement.nativeElement.focus();
}
}
Query projected content using @ContentChild
:
import { Component, ContentChild, AfterContentInit } from '@angular/core';
import { ContentComponent } from './content.component';
@Component({
selector: 'app-content-child',
template: \` \`
})
export class ContentChildComponent implements AfterContentInit {
@ContentChild(ContentComponent) contentChild: ContentComponent;
ngAfterContentInit() {
console.log(this.contentChild);
}
}
Query multiple elements or components using @ViewChildren
and @ContentChildren
:
import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-view-children',
template: \` \`
})
export class ViewChildrenComponent implements AfterViewInit {
@ViewChildren(ChildComponent) children: QueryList;
ngAfterViewInit() {
this.children.forEach(child => console.log(child));
}
}
Use @HostBinding
to bind properties to the host element:
import { Directive, HostBinding } from '@angular/core';
@Directive({
selector: '[appHostBinding]'
})
export class HostBindingDirective {
@HostBinding('class.highlight') isHighlighted = true;
}
Listen to events on the host element using @HostListener
:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appHostListener]'
})
export class HostListenerDirective {
@HostListener('mouseenter') onMouseEnter() {
console.log('Mouse entered');
}
}
Create a custom pipe to transform data:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customPipe'
})
export class CustomPipe implements PipeTransform {
transform(value: string): string {
return value.toUpperCase();
}
}
Use NgZone
to control change detection:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-ng-zone', template: \`
NgZone Example
\` }) export class NgZoneComponent { constructor(private ngZone: NgZone) {} runOutsideAngular() { this.ngZone.runOutsideAngular(() => { // Code that doesn't trigger change detection }); } runInsideAngular() { this.ngZone.run(() => { // Code that triggers change detection }); } }
Use Renderer2
for DOM manipulation:
import { Component, Renderer2, ElementRef } from '@angular/core'; @Component({ selector: 'app-renderer', template: \`
Renderer2 Example
\` }) export class RendererComponent { constructor(private renderer: Renderer2, private el: ElementRef) {} ngAfterViewInit() { this.renderer.setStyle(this.el.nativeElement.querySelector('p'), 'color', 'blue'); } }
Manually trigger change detection using ChangeDetectorRef
:
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-change-detector', template: \`
Change Detection Example
\` }) export class ChangeDetectorComponent { constructor(private cdr: ChangeDetectorRef) {} triggerChangeDetection() { this.cdr.detectChanges(); } }
Implement HttpInterceptor
to intercept HTTP requests and responses:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
const authReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer token')
});
return next.handle(authReq);
}
}
Configure a module with custom providers using @NgModule
:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyComponent } from './my-component.component';
import { MyService } from './my-service.service';
@NgModule({
declarations: [MyComponent],
imports: [CommonModule],
providers: [
{ provide: MyService, useClass: MyCustomService }
]
})
export class MyModule {}
Bind parent data to child components using @Input
:
import { Component, Input } from '@angular/core'; @Component({ selector: 'app-child', template: \`
{{parentData}}
\` }) export class ChildComponent { @Input() parentData: string; } @Component({ selector: 'app-parent', template: \`
\` }) export class ParentComponent { data = 'Data from parent'; }
Emit events from child to parent using @Output
:
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: \`\`
})
export class ChildComponent {
@Output() notify: EventEmitter = new EventEmitter();
notifyParent() {
this.notify.emit('Message from child');
}
}
@Component({
selector: 'app-parent',
template: \` \`
})
export class ParentComponent {
receiveMessage(message: string) {
console.log(message);
}
}
Bind host properties using @HostBinding
:
import { Directive, HostBinding } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@HostBinding('style.backgroundColor') backgroundColor = 'yellow';
}
Listen to host events using @HostListener
:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appHover]'
})
export class HoverDirective {
@HostListener('mouseenter') onMouseEnter() {
console.log('Mouse entered');
}
@HostListener('mouseleave') onMouseLeave() {
console.log('Mouse left');
}
}
Optimize performance using ChangeDetectionStrategy
:
import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app-optimized', template: \`
Optimized Change Detection
\`, changeDetection: ChangeDetectionStrategy.OnPush }) export class OptimizedComponent {}
Manually trigger change detection using ChangeDetectorRef
:
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-manual-detection', template: \`
Manual Change Detection
\` }) export class ManualDetectionComponent { constructor(private cdr: ChangeDetectorRef) {} triggerChangeDetection() { this.cdr.detectChanges(); } }
Safely manipulate the DOM using Renderer2
:
import { Component, Renderer2, ElementRef } from '@angular/core'; @Component({ selector: 'app-dom-manipulation', template: \`
DOM Manipulation Example
\` }) export class DomManipulationComponent { constructor(private renderer: Renderer2, private el: ElementRef) {} ngAfterViewInit() { this.renderer.setStyle(this.el.nativeElement.querySelector('p'), 'color', 'blue'); } }
Modify HTTP requests and responses using HttpInterceptor
:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class MyInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
const modifiedReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer your-token')
});
return next.handle(modifiedReq);
}
}
Run code inside or outside change detection using NgZone
:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-ng-zone', template: \`
NgZone Example
\` }) export class NgZoneComponent { constructor(private ngZone: NgZone) {} runOutsideAngular() { this.ngZone.runOutsideAngular(() => { // Code not affecting Angular change detection }); } runInsideAngular() { this.ngZone.run(() => { // Code affecting Angular change detection }); } }
Set up routing with lazy-loaded modules using NgModule
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: 'feature',
loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Define custom template and styles using @Component
:
import { Component } from '@angular/core'; @Component({ selector: 'app-custom', template: \`
Custom Template
\`, styles: [\`p { color: red; } \`] }) export class CustomComponent {}
Configure dependency injection in services using @Injectable
:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() {}
}
Manage dynamic forms using FormArray
:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
@Component({
selector: 'app-dynamic-form',
template: \`
\`
})
export class DynamicFormComponent {
form: FormGroup;
get items() {
return this.form.get('items') as FormArray;
}
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
items: this.fb.array([])
});
}
addItem() {
this.items.push(this.fb.control(''));
}
}
Access route parameters using ActivatedRoute
:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-route-params', template: \`
Route Parameter: {{ id }}
\` }) export class RouteParamsComponent implements OnInit { id: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.paramMap.subscribe(params => { this.id = params.get('id'); }); } }
Navigate programmatically using Router
:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-navigation',
template: \`\`
})
export class NavigationComponent {
constructor(private router: Router) {}
navigate() {
this.router.navigate(['/path']);
}
}
Provide a singleton service across the application using @NgModule
:
import { NgModule } from '@angular/core';
import { MyService } from './my-service.service';
@NgModule({
providers: [MyService]
})
export class AppModule {}
Handle HTTP operations using HttpClient
:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable {
return this.http.get('https://api.example.com/data');
}
}
Handle asynchronous data using AsyncPipe
:
import { Component } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'app-async-pipe', template: \`
{{ data$ | async }}
\` }) export class AsyncPipeComponent { data$: Observable
= new Observable(observer => { observer.next('Asynchronous Data'); observer.complete(); }); }
Access child components or directives using @ViewChild
:
import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: \` \`
})
export class ParentComponent {
@ViewChild(ChildComponent) child: ChildComponent;
ngAfterViewInit() {
console.log(this.child.someProperty);
}
}
Get a reference to a DOM element using @ViewChild
:
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-view-child', template: \`
Content
\` }) export class ViewChildComponent implements AfterViewInit { @ViewChild('myDiv') div: ElementRef; ngAfterViewInit() { console.log(this.div.nativeElement.textContent); } }
Access projected content using @ContentChild
:
import { Component, ContentChild, AfterContentInit, ElementRef } from '@angular/core';
@Component({
selector: 'app-content-child',
template: \` \`
})
export class ContentChildComponent implements AfterContentInit {
@ContentChild('projectedContent') content: ElementRef;
ngAfterContentInit() {
console.log(this.content.nativeElement.textContent);
}
}
Create a custom directive using @Directive
:
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'transparent');
}
}
Perform a POST request using HttpClient
:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private http: HttpClient) {}
postData(data: any): Observable {
return this.http.post('https://api.example.com/data', data);
}
}
Navigate with query parameters using Router
:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-query-params',
template: \`\`
})
export class QueryParamsComponent {
constructor(private router: Router) {}
navigate() {
this.router.navigate(['/path'], { queryParams: { page: 1, sort: 'asc' } });
}
}
Retrieve query parameters using ActivatedRoute
:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-query-params', template: \`
Page: {{ page }}, Sort: {{ sort }}
\` }) export class QueryParamsComponent implements OnInit { page: number; sort: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.queryParams.subscribe(params => { this.page = +params['page']; this.sort = params['sort']; }); } }
Create conditional templates using ng-template
:
<ng-container *ngIf="isVisible; else noContent">
<p>Content is visible</p>
</ng-container>
<ng-template #noContent>
<p>Content is hidden</p>
</ng-template>
Use ngIf
and ngFor
together:
<div *ngIf="items.length > 0">
<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>
</div>
Display content based on a variable using NgSwitch
:
<div [ngSwitch]="value">
<p *ngSwitchCase="'one'">One</p>
<p *ngSwitchCase="'two'">Two</p>
<p *ngSwitchDefault>Default</p>
</div>
Apply styles conditionally using ngStyle
:
<div [ngStyle]="{ 'background-color': isActive ? 'yellow' : 'transparent' }">
Conditional Styling
</div>
Add or remove classes dynamically using ngClass
:
<div [ngClass]="{ 'active': isActive, 'disabled': !isActive }">
Dynamic Classes
</div>
Manage individual form inputs using FormControl
:
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-form-control',
template: \`
<input [formControl]="control" />
<p>Value: {{ control.value }}</p>
\`
})
export class FormControlComponent {
control = new FormControl('');
}
Create a form with nested controls using FormBuilder
:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-nested-form',
template: \`
<form [formGroup]="form">
<div formGroupName="address">
<input formControlName="street" />
<input formControlName="city" />
</div>
</form>
\`
})
export class NestedFormComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
address: this.fb.group({
street: '',
city: ''
})
});
}
}
Group form controls using FormGroup
:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-form-group',
template: \`
<form [formGroup]="form">
<input formControlName="name" />
<input formControlName="email" />
</form>
\`
})
export class FormGroupComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: '',
email: ''
});
}
}
Work with form controls using AbstractControl
:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, AbstractControl } from '@angular/forms';
@Component({
selector: 'app-abstract-control',
template: \`
<form [formGroup]="form">
<input [formControl]="nameControl" />
</form>
\`
})
export class AbstractControlComponent {
form: FormGroup;
get nameControl(): AbstractControl {
return this.form.get('name');
}
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: ''
});
}
}
Create custom validators for form controls:
import { AbstractControl, ValidatorFn } from '@angular/forms';
export function forbiddenNameValidator(name: string): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const forbidden = control.value === name;
return forbidden ? { 'forbiddenName': { value: control.value } } : null;
};
}
Manually trigger change detection using ChangeDetectorRef
:
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-manual-detection', template: \`
Manual Detection
\` }) export class ManualDetectionComponent { constructor(private cdr: ChangeDetectorRef) {} triggerChangeDetection() { this.cdr.detectChanges(); } }
Optimize performance using OnPush
change detection strategy:
import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app-on-push', template: \`
OnPush Strategy
\`, changeDetection: ChangeDetectionStrategy.OnPush }) export class OnPushComponent {}
Load components dynamically using ComponentFactoryResolver
:
import { Component, ComponentFactoryResolver, ViewContainerRef, OnInit } from '@angular/core';
@Component({
selector: 'app-dynamic',
template: \` \`
})
export class DynamicComponent implements OnInit {
constructor(private cfr: ComponentFactoryResolver, private vcr: ViewContainerRef) {}
ngOnInit() {
const factory = this.cfr.resolveComponentFactory(SomeComponent);
this.vcr.createComponent(factory);
}
}
Configure a feature module with lazy loading using NgModule
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FeatureComponent } from './feature.component';
const routes: Routes = [
{ path: '', component: FeatureComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class FeatureModule {}
Manipulate the DOM using Renderer2
:
import { Component, Renderer2, ElementRef } from '@angular/core'; @Component({ selector: 'app-renderer', template: \`
Content
\` }) export class RendererComponent { constructor(private renderer: Renderer2, private el: ElementRef) {} changeBackgroundColor() { this.renderer.setStyle(this.el.nativeElement.querySelector('div'), 'backgroundColor', 'blue'); } }
Handle HTTP requests and responses using HttpInterceptor
:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
const clonedRequest = req.clone({
headers: req.headers.set('Authorization', 'Bearer your-token')
});
return next.handle(clonedRequest);
}
}
Provide services using hierarchical injectors:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Service provided at root level
})
export class SharedService {
constructor() {}
}
Implement route guards for authentication using Router
:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(): Observable | Promise | boolean {
const isAuthenticated = false; // Replace with real authentication check
if (!isAuthenticated) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}
Manually check for changes using ChangeDetectorRef
:
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-detection', template: \`
Manual Change Detection
\` }) export class DetectionComponent { constructor(private cdr: ChangeDetectorRef) {} triggerCheck() { this.cdr.detectChanges(); } }
Run code outside the Angular zone using NgZone
:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-ng-zone', template: \`
NgZone Example
\` }) export class NgZoneComponent { constructor(private ngZone: NgZone) {} runOutsideAngular() { this.ngZone.runOutsideAngular(() => { // Code here won't trigger Angular change detection }); } }
Inject dependencies using @Inject
:
import { Injectable, Inject } from '@angular/core';
const TOKEN = 'my-token';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Inject(TOKEN) private token: string) {}
}
Listen to DOM events using @HostListener
:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appHostListener]'
})
export class HostListenerDirective {
@HostListener('click', ['$event'])
onClick(event: Event) {
console.log('Element clicked', event);
}
}
Bind properties to the host element using @HostBinding
:
import { Directive, HostBinding } from '@angular/core';
@Directive({
selector: '[appHostBinding]'
})
export class HostBindingDirective {
@HostBinding('attr.aria-label') ariaLabel = 'Host Element';
}
Use ng-container
to avoid adding extra elements:
<ng-container *ngIf="isVisible">
<p>This will be displayed if isVisible is true</p>
</ng-container>
Get references to multiple DOM elements using @ViewChildren
:
import { Component, QueryList, ViewChildren, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-view-children', template: \`
Item {{ i }}
\` }) export class ViewChildrenComponent implements AfterViewInit { @ViewChildren('item') items: QueryList
; ngAfterViewInit() { this.items.forEach(item => console.log(item.nativeElement.textContent)); } }
Get references to multiple projected content elements using @ContentChildren
:
import { Component, ContentChildren, QueryList, AfterContentInit, ElementRef } from '@angular/core';
@Component({
selector: 'app-content-children',
template: \` \`
})
export class ContentChildrenComponent implements AfterContentInit {
@ContentChildren('contentItem') contentItems: QueryList;
ngAfterContentInit() {
this.contentItems.forEach(item => console.log(item.nativeElement.textContent));
}
}
Pass data between components using @Input
and @Output
:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: \`\`
})
export class ChildComponent {
@Input() parentData: string;
@Output() messageEvent = new EventEmitter();
sendMessage() {
this.messageEvent.emit('Message from child');
}
}
@Component({
selector: 'app-parent',
template: \`
<app-child [parentData]="data" (messageEvent)="receiveMessage($event)"></app-child>
\`
})
export class ParentComponent {
data = 'Data from parent';
receiveMessage(message: string) {
console.log(message);
}
}
Get a reference to a child component or DOM element using @ViewChild
:
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-view-child', template: \`
Child Div
\` }) export class ViewChildComponent implements AfterViewInit { @ViewChild('myDiv') myDiv: ElementRef; ngAfterViewInit() { console.log(this.myDiv.nativeElement.textContent); } }
Manage change detection behavior using ChangeDetectionStrategy
:
import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app-change-detection', template: \`
Change Detection Strategy
\`, changeDetection: ChangeDetectionStrategy.OnPush }) export class ChangeDetectionComponent {}
Use ngIf
and ngFor
directives to conditionally display and iterate over elements:
<div *ngIf="isVisible">
<div *ngFor="let item of items">{{ item }}</div>
</div>
Define reusable template blocks using ng-template
:
<ng-template #myTemplate>
<p>Reusable Content</p>
</ng-template>
<ng-container *ngTemplateOutlet="myTemplate"></ng-container>
Project content into a component using ContentProjection
:
import { Component } from '@angular/core';
@Component({
selector: 'app-content-projection',
template: \`
<ng-content></ng-content>
\`
})
export class ContentProjectionComponent {}
Provide different instances of a service using Dependency Injection
:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() {}
}
@Injectable({
providedIn: 'root',
useClass: DifferentService
})
export class AlternativeService {}
Handle child routes using Router
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ParentComponent } from './parent.component';
import { ChildComponent } from './child.component';
const routes: Routes = [
{
path: 'parent',
component: ParentComponent,
children: [
{ path: 'child', component: ChildComponent }
]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Configure lazy-loaded modules using NgModule
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CommonModule } from '@angular/common';
import { LazyModule } from './lazy/lazy.module';
const routes: Routes = [
{
path: 'lazy',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes), CommonModule],
exports: [RouterModule]
})
export class AppRoutingModule {}
Control style encapsulation using @ViewEncapsulation
:
import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'app-encapsulation', template: \`
Style Encapsulation
\`, styles: [\` p { color: blue; } \`], encapsulation: ViewEncapsulation.None // No encapsulation }) export class EncapsulationComponent {}
Import and use third-party libraries in NgModule
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; // Example third-party library
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
NgbModule // Import third-party module
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
Make HTTP requests and handle responses using HttpClient
:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private http: HttpClient) {}
getData(): Observable {
return this.http.get('https://api.example.com/data');
}
}
Manage dynamic forms using FormArray
:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
@Component({
selector: 'app-dynamic-form',
template: \`
\`
})
export class DynamicFormComponent {
form: FormGroup;
get items(): FormArray {
return this.form.get('items') as FormArray;
}
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
items: this.fb.array([])
});
}
addItem() {
this.items.push(this.fb.control(''));
}
}
Create custom pipes using @Pipe
:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customPipe'
})
export class CustomPipe implements PipeTransform {
transform(value: string): string {
return value.toUpperCase();
}
}
Trigger change detection manually using ChangeDetectorRef
:
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-change-detection', template: \`
Change Detection
\` }) export class ChangeDetectionComponent { constructor(private cdr: ChangeDetectorRef) {} updateView() { this.cdr.detectChanges(); // Manually trigger change detection } }
Listen to host element events using @HostListener
:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appHostListener]'
})
export class HostListenerDirective {
@HostListener('click', ['$event'])
onClick(event: Event) {
console.log('Host element clicked:', event);
}
}
Get a reference to a child component using @ViewChild
:
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: \` \`
})
export class ParentComponent implements AfterViewInit {
@ViewChild(ChildComponent) childComponent: ChildComponent;
ngAfterViewInit() {
console.log(this.childComponent);
}
}
Get references to multiple projected content elements using @ContentChildren
:
import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
@Component({
selector: 'app-content',
template: \`
<ng-content></ng-content>
\`
})
export class ContentComponent implements AfterContentInit {
@ContentChildren('contentItem') contentItems: QueryList;
ngAfterContentInit() {
this.contentItems.forEach(item => console.log(item.nativeElement.textContent));
}
}
Execute code outside Angular's change detection using NgZone
:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-ng-zone', template: \`
NgZone Example
\` }) export class NgZoneComponent { constructor(private ngZone: NgZone) { this.ngZone.runOutsideAngular(() => { // Code here runs outside Angular's change detection }); } }
Inject services with different configurations using @Inject
:
import { Injectable, Inject } from '@angular/core';
import { APP_CONFIG, AppConfig } from './app-config';
@Injectable({
providedIn: 'root'
})
export class ConfigService {
constructor(@Inject(APP_CONFIG) private config: AppConfig) {}
getConfig() {
return this.config;
}
}
Handle route guards using Router
:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(): boolean {
const isAuthenticated = false; // Replace with actual authentication check
if (!isAuthenticated) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}
Manipulate DOM elements safely using Renderer2
:
import { Component, Renderer2, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-renderer', template: \`
Content
\` }) export class RendererComponent implements AfterViewInit { constructor(private renderer: Renderer2, private el: ElementRef) {} ngAfterViewInit() { const div = this.el.nativeElement.querySelector('div'); this.renderer.setStyle(div, 'color', 'red'); } }
Modify HTTP requests and responses using HttpInterceptor
:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
const clonedRequest = req.clone({
setHeaders: {
Authorization: 'Bearer your-token'
}
});
return next.handle(clonedRequest);
}
}
Listen to DOM events using Renderer2
:
import { Component, Renderer2, ElementRef, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-event-listener',
template: \`\`
})
export class EventListenerComponent implements AfterViewInit {
constructor(private renderer: Renderer2, private el: ElementRef) {}
ngAfterViewInit() {
const button = this.el.nativeElement.querySelector('button');
this.renderer.listen(button, 'click', () => {
console.log('Button clicked!');
});
}
}
Handle file uploads using HttpClient
:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class FileUploadService {
constructor(private http: HttpClient) {}
uploadFile(file: File): Observable {
const formData = new FormData();
formData.append('file', file);
return this.http.post('https://api.example.com/upload', formData);
}
}
Bind properties to host elements using @HostBinding
:
import { Directive, HostBinding } from '@angular/core';
@Directive({
selector: '[appHostBinding]'
})
export class HostBindingDirective {
@HostBinding('attr.role') role = 'button';
}
Get references to projected content using @ContentChildren
:
import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
@Component({
selector: 'app-content',
template: \`
<ng-content select="[contentItem]" *ngFor="let item of contentItems"></ng-content>
\`
})
export class ContentComponent implements AfterContentInit {
@ContentChildren('contentItem') contentItems: QueryList;
ngAfterContentInit() {
this.contentItems.forEach(item => console.log(item.nativeElement.textContent));
}
}
Add and remove CSS classes conditionally using Renderer2
:
import { Component, Renderer2, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-css-class', template: \`
Content
\` }) export class CssClassComponent implements AfterViewInit { constructor(private renderer: Renderer2, private el: ElementRef) {} ngAfterViewInit() { const div = this.el.nativeElement.querySelector('div'); this.renderer.addClass(div, 'active'); this.renderer.removeClass(div, 'inactive'); } }
Handle asynchronous operations using RxJS
operators:
import { Component } from '@angular/core'; import { of } from 'rxjs'; import { delay, map } from 'rxjs/operators'; @Component({ selector: 'app-rxjs', template: \`
Check console for RxJS example
\` }) export class RxjsComponent { constructor() { of('Hello, World!') .pipe( delay(1000), map(message => message.toUpperCase()) ) .subscribe(result => console.log(result)); } }
Pass data between components using @Input
and @Output
:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: \`
\`
})
export class ChildComponent {
@Input() childData: string;
@Output() notify: EventEmitter = new EventEmitter();
notifyParent() {
this.notify.emit('Hello from Child');
}
}
@Component({
selector: 'app-parent',
template: \`
<app-child [childData]="parentData" (notify)="onNotify($event)"></app-child>
\`
})
export class ParentComponent {
parentData = 'Data from Parent';
onNotify(message: string) {
console.log(message);
}
}
Implement route and query parameter handling using Router
:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-details', template: \`
ID: {{ id }} | Filter: {{ filter }}
\` }) export class DetailsComponent implements OnInit { id: string; filter: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.paramMap.subscribe(params => { this.id = params.get('id'); }); this.route.queryParamMap.subscribe(queryParams => { this.filter = queryParams.get('filter'); }); } }
Interact with the DOM safely using Renderer2
:
import { Component, Renderer2, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-renderer', template: \`
Content
\` }) export class RendererComponent implements AfterViewInit { constructor(private renderer: Renderer2, private el: ElementRef) {} ngAfterViewInit() { const div = this.el.nativeElement.querySelector('div'); this.renderer.setStyle(div, 'color', 'green'); } }
Optimize change detection using ChangeDetectionStrategy
:
import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app-optimization', template: \`
Optimized Change Detection
\`, changeDetection: ChangeDetectionStrategy.OnPush }) export class OptimizationComponent {}
Load components dynamically using ComponentFactoryResolver
:
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef, OnInit } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
@Component({
selector: 'app-dynamic',
template: \` \`
})
export class DynamicComponentLoader implements OnInit {
@ViewChild('dynamicContainer', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) {}
ngOnInit() {
const factory = this.resolver.resolveComponentFactory(DynamicComponent);
this.container.createComponent(factory);
}
}
Provide services in a module using Dependency Injection
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ApiService } from './api.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [ApiService], // Provide service in module
bootstrap: [AppComponent]
})
export class AppModule {}
Implement nested routes using Router
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ParentComponent } from './parent.component';
import { ChildComponent } from './child.component';
const routes: Routes = [
{
path: 'parent',
component: ParentComponent,
children: [
{ path: 'child', component: ChildComponent }
]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Configure providers for different environments in NgModule
:
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { environment } from '../environments/environment';
export function initializeApp() {
return (): Promise => {
// Initialize app based on environment
return new Promise((resolve, reject) => {
// Initialization logic here
resolve(true);
});
};
}
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
{ provide: APP_INITIALIZER, useFactory: initializeApp, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule {}
Create services with different scopes using @Injectable
:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Singleton service
})
export class SingletonService {}
@Injectable({
providedIn: 'any' // Scoped service
})
export class ScopedService {}
Access child components or DOM elements using @ViewChild
:
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-view-child', template: \`
Content
\` }) export class ViewChildComponent implements AfterViewInit { @ViewChild('myDiv') myDiv: ElementRef; ngAfterViewInit() { console.log(this.myDiv.nativeElement.textContent); } }
Access projected content using @ContentChild
:
import { Component, ContentChild, ElementRef, AfterContentInit } from '@angular/core';
@Component({
selector: 'app-content-child',
template: \` \`
})
export class ContentChildComponent implements AfterContentInit {
@ContentChild('content') content: ElementRef;
ngAfterContentInit() {
console.log(this.content.nativeElement.textContent);
}
}
Trigger change detection manually using ChangeDetectorRef
:
import { Component, ChangeDetectorRef, OnInit } from '@angular/core'; @Component({ selector: 'app-change-detector', template: \`
Manual Change Detection
\` }) export class ChangeDetectorComponent implements OnInit { constructor(private cdRef: ChangeDetectorRef) {} ngOnInit() { this.cdRef.detectChanges(); // Manually trigger change detection } }
Create reactive forms using FormBuilder
:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
template: \`
\`
})
export class ReactiveFormComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: ['']
});
}
onSubmit() {
console.log(this.form.value);
}
}
Handle file downloads using HttpClient
:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { saveAs } from 'file-saver';
@Injectable({
providedIn: 'root'
})
export class FileDownloadService {
constructor(private http: HttpClient) {}
downloadFile(): Observable {
return this.http.get('https://api.example.com/download', { responseType: 'blob' });
}
saveFile() {
this.downloadFile().subscribe(blob => {
saveAs(blob, 'filename.ext');
});
}
}
Configure lazy-loaded modules using NgModule
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'lazy', loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Implement real-time data updates using Observable
:
import { Component, OnInit } from '@angular/core'; import { WebSocketSubject } from 'rxjs/webSocket'; @Component({ selector: 'app-real-time', template: \`
Real-time Data: {{ data }}
\` }) export class RealTimeComponent implements OnInit { data: any; private socket$: WebSocketSubject
; ngOnInit() { this.socket$ = new WebSocketSubject('wss://api.example.com/socket'); this.socket$.subscribe(message => { this.data = message; }); } }
Optimize performance using NgZone
:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-ng-zone', template: \`
NgZone Performance Optimization
\` }) export class NgZoneComponent { constructor(private ngZone: NgZone) { this.ngZone.runOutsideAngular(() => { // Perform heavy computations here setTimeout(() => { console.log('Heavy computation done'); this.ngZone.run(() => { // Update UI if needed }); }, 1000); }); } }
Create multi-provider services using @Injectable
:
import { Injectable, InjectionToken } from '@angular/core';
export const API_URL = new InjectionToken('apiUrl');
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(@Inject(API_URL) private apiUrl: string) {}
}
Handle performance issues using ChangeDetectorRef
:
import { Component, ChangeDetectorRef, OnInit } from '@angular/core'; @Component({ selector: 'app-performance', template: \`
Performance Optimized
\` }) export class PerformanceComponent implements OnInit { constructor(private cdRef: ChangeDetectorRef) {} ngOnInit() { this.cdRef.detach(); // Detach change detection // Perform operations without triggering change detection this.cdRef.reattach(); // Reattach change detection if needed } }
To create a custom pipe, use the @Pipe
decorator and implement the PipeTransform
interface:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customPipe'
})
export class CustomPipe implements PipeTransform {
transform(value: string, ...args: any[]): string {
return value.toUpperCase(); // Example transformation
}
}
Use ng-content
to project content into a component:
<!-- Parent component template -->
<app-child>
<p>This content is projected into the child component</p>
</app-child>
<!-- Child component template -->
<ng-content></ng-content>
To implement a custom form control, implement ControlValueAccessor
:
import { Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-custom-input',
template: '<input (input)="onChange($event.target.value)" [value]="value">',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true
}]
})
export class CustomInputComponent implements ControlValueAccessor {
value: string = '';
onChange = (value: string) => {};
onTouched = () => {};
writeValue(value: string): void {
this.value = value;
}
registerOnChange(fn: (value: string) => void): void {
this.onChange = fn;
}
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
}
Provide services using Angular's Dependency Injection:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() { }
}
Handle errors using HttpInterceptor
:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
import { catchError, Observable, throwError } from 'rxjs';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
console.error('Error occurred:', error);
return throwError(error);
})
);
}
}
Create a module with lazy-loaded routes using RouterModule.forChild
:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FeatureComponent } from './feature.component';
const routes: Routes = [
{ path: '', component: FeatureComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class FeatureRoutingModule { }
Use @HostListener
to listen to DOM events:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appHover]'
})
export class HoverDirective {
@HostListener('mouseover') onMouseOver() {
console.log('Mouse over event');
}
@HostListener('mouseout') onMouseOut() {
console.log('Mouse out event');
}
}
Implement ChangeDetectionStrategy
to optimize change detection:
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-optimized',
template: '<p>Optimized Component</p>',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class OptimizedComponent { }
Use @Injectable
with different providers:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root' // Singleton service
})
export class DataService {
constructor(private http: HttpClient) { }
getData() {
return this.http.get('/api/data');
}
}
@Injectable()
export class OtherService {
constructor() { }
}
Handle module dependencies and feature modules:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
@NgModule({
declarations: [FeatureComponent],
imports: [CommonModule],
exports: [FeatureComponent]
})
export class FeatureModule { }
Manipulate DOM elements safely using Renderer2
:
import { Component, Renderer2, ElementRef } from '@angular/core';
@Component({
selector: 'app-dom-manipulation',
template: '<div #myDiv>Content</div>'
})
export class DomManipulationComponent {
constructor(private renderer: Renderer2, private el: ElementRef) {}
changeStyle() {
const div = this.el.nativeElement.querySelector('#myDiv');
this.renderer.setStyle(div, 'color', 'blue');
}
}
Access child components and directives using @ViewChild
:
import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: '<app-child></app-child>'
})
export class ParentComponent {
@ViewChild(ChildComponent) child!: ChildComponent;
callChildMethod() {
this.child.someMethod();
}
}
Access projected content using @ContentChild
:
import { Component, ContentChild, AfterContentInit } from '@angular/core';
import { ChildDirective } from './child.directive';
@Component({
selector: 'app-parent',
template: '<ng-content></ng-content>'
})
export class ParentComponent implements AfterContentInit {
@ContentChild(ChildDirective) contentChild!: ChildDirective;
ngAfterContentInit() {
console.log(this.contentChild);
}
}
Bind properties to host elements using @HostBinding
:
import { Directive, HostBinding } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@HostBinding('class.highlight') isHighlighted = true;
}
Create a service with multiple instances using providers
in component metadata:
import { Component } from '@angular/core';
import { MyService } from './my.service';
@Component({
selector: 'app-example',
template: '<p>Example Component</p>',
providers: [MyService] // New instance for this component
})
export class ExampleComponent {
constructor(private myService: MyService) { }
}
Trigger change detection manually using ChangeDetectorRef
:
import { Component, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-manual-detection',
template: '<p>Manual Change Detection</p>'
})
export class ManualDetectionComponent {
constructor(private cdr: ChangeDetectorRef) { }
triggerChangeDetection() {
this.cdr.detectChanges();
}
}
Create reusable templates using ng-template
:
<ng-template #template>
<p>Reusable content</p>
</ng-template>
<ng-container *ngTemplateOutlet="template"></ng-container>
Configure imports and exports in @NgModule
:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
CommonModule,
FormsModule
],
exports: [
CommonModule,
FormsModule
]
})
export class SharedModule { }
Provide dependencies using @Inject
:
import { Injectable, Inject } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Inject('API_URL') private apiUrl: string) { }
}
Create custom decorators by defining functions that return metadata:
import { Component } from '@angular/core';
function CustomDecorator(config: any) {
return function (target: Function) {
// Custom logic here
console.log('Decorator applied with config:', config);
};
}
@CustomDecorator({ key: 'value' })
@Component({
selector: 'app-decorated',
template: '<p>Custom Decorator Component</p>'
})
export class DecoratedComponent { }
Listen to custom events using @HostListener
:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appCustomEvent]'
})
export class CustomEventDirective {
@HostListener('customEvent', ['$event'])
onCustomEvent(event: Event) {
console.log('Custom event fired', event);
}
}
Access multiple child components using @ViewChildren
:
import { Component, ViewChildren, QueryList } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: '<app-child *ngFor="let child of children"></app-child>'
})
export class ParentComponent {
@ViewChildren(ChildComponent) children!: QueryList;
ngAfterViewInit() {
this.children.forEach(child => child.someMethod());
}
}
Access multiple projected content items using @ContentChildren
:
import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { ProjectedComponent } from './projected.component';
@Component({
selector: 'app-container',
template: '<ng-content></ng-content>'
})
export class ContainerComponent implements AfterContentInit {
@ContentChildren(ProjectedComponent) projectedItems!: QueryList;
ngAfterContentInit() {
this.projectedItems.forEach(item => item.doSomething());
}
}
Implement navigation guards using Router
events:
import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
const isAuthenticated = false; // Logic to check authentication
if (!isAuthenticated) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}
Create a custom validator function:
import { AbstractControl, ValidatorFn } from '@angular/forms';
export function customValidator(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const isValid = /* custom validation logic */;
return isValid ? null : { 'customError': true };
};
}
Inject tokens and configuration values using @Inject
:
import { Injectable, Inject } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ConfigService {
constructor(@Inject('APP_CONFIG') private config: any) { }
getConfig() {
return this.config;
}
}
Create a custom pipe using @Pipe
:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'reverse'
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Navigate programmatically using Router
:
import { Router } from '@angular/router';
constructor(private router: Router) {}
navigateToHome() {
this.router.navigate(['/home']);
}
Make HTTP requests using HttpClient
:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private http: HttpClient) {}
getData() {
return this.http.get('/api/data').subscribe(response => {
console.log(response);
});
}
}
Optimize performance using ChangeDetectionStrategy
:
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-performance',
template: '<p>Optimized Component</p>',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PerformanceComponent { }
Create custom behavior using @Directive
:
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'transparent');
}
}
Configure module imports and exports using @NgModule
:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
@NgModule({
imports: [CommonModule],
declarations: [FeatureComponent],
exports: [FeatureComponent]
})
export class FeatureModule { }
Provide optional dependencies using @Optional
:
import { Injectable, Optional } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Optional() private optionalDependency?: AnyDependency) { }
}
Provide dependencies from the current injector using @Self
:
import { Injectable, Self } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Self() private selfService: OtherService) { }
}
Create dynamic content projection using ng-content
:
<ng-content></ng-content>
Inject dependencies from a parent component using @Host
:
import { Injectable, Host } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Host() private parentService: ParentService) { }
}
Manage component styles using @ViewEncapsulation
:
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-styled',
template: '<p>Styled Component</p>',
styles: ['p { color: red; }'],
encapsulation: ViewEncapsulation.None
})
export class StyledComponent { }
Manually trigger change detection using ChangeDetectorRef
:
import { Component, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-detect',
template: '<p>Manual Change Detection</p>'
})
export class DetectComponent {
constructor(private cdr: ChangeDetectorRef) { }
triggerChange() {
this.cdr.detectChanges();
}
}
Create structural directives using @Directive
:
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appUnless]'
})
export class UnlessDirective {
constructor(private templateRef: TemplateRef, private viewContainer: ViewContainerRef) {}
@Input() set appUnless(condition: boolean) {
if (!condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
}
Control dependency injection using @Host
and @Self
:
import { Injectable, Host, Self } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Host() @Self() private parentService: ParentService) { }
}
Create a custom directive to manipulate DOM elements:
import { Directive, ElementRef, Renderer2 } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
}
Component communication using @Input
and @Output
:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: '<button (click)="sendMessage()">Send Message</button>'
})
export class ChildComponent {
@Input() childInput!: string;
@Output() childOutput = new EventEmitter();
sendMessage() {
this.childOutput.emit('Message from child');
}
}
@Component({
selector: 'app-parent',
template: '<app-child [childInput]="parentData" (childOutput)="receiveMessage($event)"></app-child>'
})
export class ParentComponent {
parentData = 'Data from parent';
receiveMessage(message: string) {
console.log(message);
}
}
Create and use services for state management:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class StateService {
private state = new BehaviorSubject('initial state');
currentState = this.state.asObservable();
changeState(newState: string) {
this.state.next(newState);
}
}
import { Component, OnInit } from '@angular/core';
import { StateService } from './state.service';
@Component({
selector: 'app-example',
template: '<p>State: {{ state | async }}</p>'
})
export class ExampleComponent implements OnInit {
state: Observable;
constructor(private stateService: StateService) {}
ngOnInit() {
this.state = this.stateService.currentState;
}
}
Implement lazy loading of modules:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LazyLoadedComponent } from './lazy-loaded.component';
const routes: Routes = [
{ path: 'lazy', component: LazyLoadedComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LazyLoadedRoutingModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LazyLoadedRoutingModule } from './lazy-loaded-routing.module';
import { LazyLoadedComponent } from './lazy-loaded.component';
@NgModule({
declarations: [LazyLoadedComponent],
imports: [
CommonModule,
LazyLoadedRoutingModule
]
})
export class LazyLoadedModule { }
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: 'lazy', loadChildren: () => import('./lazy-loaded/lazy-loaded.module').then(m => m.LazyLoadedModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Configure Angular CLI for production builds in angular.json
:
"architect": {
"build": {
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"serviceWorker": true
}
}
}
}
Handle errors globally using HttpInterceptor
:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler) {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
console.error('Error occurred:', error);
return throwError(error);
})
);
}
}
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ErrorInterceptor } from './error.interceptor';
@NgModule({
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
]
})
export class AppModule { }
Define shared modules using @NgModule
:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedComponent } from './shared.component';
@NgModule({
declarations: [SharedComponent],
imports: [CommonModule],
exports: [SharedComponent]
})
export class SharedModule { }
Create and use services with dependency injection:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() { }
getServiceData() {
return 'Service Data';
}
}
import { Component, OnInit } from '@angular/core';
import { MyService } from './my.service';
@Component({
selector: 'app-example',
template: '<p>{{ data }}</p>'
})
export class ExampleComponent implements OnInit {
data!: string;
constructor(private myService: MyService) { }
ngOnInit() {
this.data = this.myService.getServiceData();
}
}
Listen to native DOM events using @HostListener
:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appClickTracker]'
})
export class ClickTrackerDirective {
@HostListener('click', ['$event'])
onClick(event: Event) {
console.log('Element clicked:', event);
}
}
Access projected content using @ContentChild
:
import { Component, ContentChild, AfterContentInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: '<ng-content></ng-content>'
})
export class ParentComponent implements AfterContentInit {
@ContentChild(ChildComponent) contentChild!: ChildComponent;
ngAfterContentInit() {
console.log('Projected content:', this.contentChild);
}
}
Access a child component using @ViewChild
:
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: '<app-child></app-child>'
})
export class ParentComponent implements AfterViewInit {
@ViewChild(ChildComponent) childComponent!: ChildComponent;
ngAfterViewInit() {
console.log('Child component:', this.childComponent);
}
}
Provide custom tokens using @Inject
:
import { InjectionToken, Inject, Injectable } from '@angular/core';
export const MY_CUSTOM_TOKEN = new InjectionToken('MyCustomToken');
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(@Inject(MY_CUSTOM_TOKEN) private token: string) {
console.log('Token:', this.token);
}
}
Manage lazy-loaded feature modules using @NgModule
:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureRoutingModule } from './feature-routing.module';
import { FeatureComponent } from './feature.component';
@NgModule({
declarations: [FeatureComponent],
imports: [
CommonModule,
FeatureRoutingModule
]
})
export class FeatureModule { }
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Optimize change detection using ChangeDetectionStrategy
:
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-optimized',
template: '<p>Optimized Change Detection</p>',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class OptimizedComponent { }
Create custom pipes for data transformation:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'reverse'
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Declare and import third-party modules in NgModule
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Bind properties to host elements using @HostBinding
:
import { Directive, HostBinding } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@HostBinding('style.backgroundColor') backgroundColor = 'yellow';
}
Listen to events from host elements using @HostListener
:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appClickTracker]'
})
export class ClickTrackerDirective {
@HostListener('click', ['$event'])
onClick(event: Event) {
console.log('Element clicked:', event);
}
}
Access multiple projected content elements using @ContentChildren
:
import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: '<ng-content select="app-child"></ng-content>'
})
export class ParentComponent implements AfterContentInit {
@ContentChildren(ChildComponent) contentChildren!: QueryList;
ngAfterContentInit() {
this.contentChildren.forEach(child => console.log('Projected child:', child));
}
}
Configure and provide global services using @NgModule
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { GlobalService } from './global.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [GlobalService],
bootstrap: [AppComponent]
})
export class AppModule { }
Create a custom date pipe:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customDate'
})
export class CustomDatePipe implements PipeTransform {
transform(value: Date, format: string = 'MM/dd/yyyy'): string {
const options: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: '2-digit',
day: '2-digit'
};
return new Intl.DateTimeFormat('en-US', options).format(value);
}
}
Provide a service at the module level:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyService } from './my.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [MyService],
bootstrap: [AppComponent]
})
export class AppModule { }
Perform HTTP requests with headers:
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private http: HttpClient) {}
getData() {
const headers = new HttpHeaders({
'Authorization': 'Bearer your-token'
});
return this.http.get('/api/data', { headers });
}
}
Handle route guards for authentication:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(): boolean {
const isAuthenticated = false; // Replace with real authentication check
if (!isAuthenticated) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}
const routes: Routes = [
{ path: 'protected', component: ProtectedComponent, canActivate: [AuthGuard] }
];
Configure and provide global configurations:
import { NgModule, InjectionToken } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
export const API_CONFIG = new InjectionToken('API_CONFIG');
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
{ provide: API_CONFIG, useValue: 'https://api.example.com' }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Define feature modules:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
@NgModule({
declarations: [FeatureComponent],
imports: [CommonModule],
exports: [FeatureComponent]
})
export class FeatureModule { }
Import and configure third-party modules:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { ThirdPartyModule } from 'third-party-library';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
HttpClientModule,
ThirdPartyModule.forRoot({ apiKey: 'your-api-key' })
],
bootstrap: [AppComponent]
})
export class AppModule { }
Configure and manage component metadata:
import { Component } from '@angular/core';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css'],
animations: [ /* animations here */ ]
})
export class ExampleComponent { }
Define and use custom directives:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HighlightDirective } from './highlight.directive';
@NgModule({
declarations: [HighlightDirective],
imports: [CommonModule],
exports: [HighlightDirective]
})
export class SharedModule { }
import { Directive, ElementRef, Renderer2 } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
}
Configure and provide global services:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { GlobalService } from './global.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [GlobalService],
bootstrap: [AppComponent]
})
export class AppModule { }
Create and manage reusable components:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-reusable',
template: '<p>Hello, {{ name }}!</p>',
styleUrls: ['./reusable.component.css']
})
export class ReusableComponent {
@Input() name!: string;
}
Create custom behavior for DOM elements:
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appHover]'
})
export class HoverDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'color', 'blue');
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.setStyle(this.el.nativeElement, 'color', 'black');
}
}
Configure and provide routing modules:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
import { AboutComponent } from './about.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Manage component lifecycle hooks:
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-lifecycle',
template: '<p>Lifecycle Component</p>'
})
export class LifecycleComponent implements OnInit, OnDestroy {
ngOnInit() {
console.log('Component initialized');
}
ngOnDestroy() {
console.log('Component destroyed');
}
}
Declare and use shared services:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedService } from './shared.service';
@NgModule({
declarations: [],
imports: [CommonModule],
providers: [SharedService],
exports: []
})
export class SharedModule { }
Create and use services with different scopes:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Singleton service
})
export class SingletonService { }
@Injectable({
providedIn: 'any' // Service available in any injector
})
export class ScopedService { }
Configure and provide asynchronous modules:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { MyAsyncModule } from './my-async.module';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
HttpClientModule,
MyAsyncModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
@NgModule({
imports: [
HttpClientModule
]
})
export class MyAsyncModule { }
Provide global error handling:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ErrorHandler } from '@angular/core';
import { GlobalErrorHandler } from './global-error-handler';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [{ provide: ErrorHandler, useClass: GlobalErrorHandler }],
bootstrap: [AppComponent]
})
export class AppModule { }
Configure and provide authentication services:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AuthService } from './auth.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [AuthService],
bootstrap: [AppComponent]
})
export class AppModule { }
Manage internationalization (i18n):
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { LOCALE_ID } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import localeEs from '@angular/common/locales/es';
registerLocaleData(localeEs);
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [{ provide: LOCALE_ID, useValue: 'es' }],
bootstrap: [AppComponent]
})
export class AppModule { }
Configure lazy loading of modules:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{
path: 'feature',
loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Define and use feature modules:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
@NgModule({
declarations: [FeatureComponent],
imports: [CommonModule],
exports: [FeatureComponent]
})
export class FeatureModule { }
Handle complex data binding scenarios:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-complex-data',
template: `
<input [(ngModel)]="data.inputValue" />
<button (click)="sendData()">Send</button>
`,
styleUrls: ['./complex-data.component.css']
})
export class ComplexDataComponent {
@Input() data: any;
@Output() dataChange = new EventEmitter();
sendData() {
this.dataChange.emit(this.data);
}
}
Create a custom directive for form validation:
import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
@Directive({
selector: '[appCustomValidator]',
providers: [{ provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true }]
})
export class CustomValidatorDirective implements Validator {
@Input('appCustomValidator') forbiddenName: string;
validate(control: AbstractControl): ValidationErrors | null {
return control.value === this.forbiddenName ? { 'forbiddenName': true } : null;
}
}
Manage nested components:
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<app-child [data]="parentData"></app-child>
`
})
export class ParentComponent {
parentData = 'Data from parent';
}
@Component({
selector: 'app-child',
template: '<p>{{ data }}</p>'
})
export class ChildComponent {
@Input() data: string;
}
Provide global configuration settings:
import { NgModule, InjectionToken } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
export const APP_CONFIG = new InjectionToken('APP_CONFIG');
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
{ provide: APP_CONFIG, useValue: 'https://api.example.com' }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Configure and use dependency injection in services:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DataService } from './data.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [DataService],
bootstrap: [AppComponent]
})
export class AppModule { }
Manage reactive forms with validation:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input formControlName="name" />
<div *ngIf="form.controls.name.invalid && form.controls.name.touched">
Name is required
</div>
<button type="submit">Submit</button>
</form>
`
})
export class ReactiveFormComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: ['', Validators.required]
});
}
onSubmit() {
console.log(this.form.value);
}
}
Optimize performance using lifecycle hooks:
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-optimization',
template: '<p>Optimized Component</p>'
})
export class OptimizationComponent implements OnInit, OnDestroy {
ngOnInit() {
console.log('Component initialized');
// Initialization code here
}
ngOnDestroy() {
console.log('Component destroyed');
// Cleanup code here
}
}
Create custom behavior for components:
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appCustomBehavior]'
})
export class CustomBehaviorDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('click') onClick() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'blue');
}
}
Configure and use HTTP interceptors:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { AuthInterceptor } from './auth.interceptor';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Configure and use Angular Elements:
import { NgModule, Injector } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { createCustomElement } from '@angular/elements';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
entryComponents: [AppComponent]
})
export class AppModule {
constructor(private injector: Injector) {
const el = createCustomElement(AppComponent, { injector });
customElements.define('my-element', el);
}
ngDoBootstrap() {}
}
Configure and use module lazy loading with `RouterModule`:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{
path: 'lazy',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Handle conditional rendering with `*ngIf`:
import { Component } from '@angular/core';
@Component({
selector: 'app-conditional',
template: `
<div *ngIf="showContent">
Content is visible
</div>
<button (click)="toggleContent()">Toggle Content</button>
`
})
export class ConditionalComponent {
showContent = true;
toggleContent() {
this.showContent = !this.showContent;
}
}
Handle dynamic component loading:
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
@Component({
selector: 'app-dynamic-loader',
template: `
<ng-template #container></ng-template>
<button (click)="loadComponent()">Load Component</button>
`
})
export class DynamicLoaderComponent {
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) {}
loadComponent() {
const factory = this.resolver.resolveComponentFactory(DynamicComponent);
this.container.createComponent(factory);
}
}
Manage component interactions using `@Input` and `@Output`:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<app-child [data]="parentData" (dataChange)="onDataChange($event)"></app-child>
`
})
export class ParentComponent {
parentData = 'Data from parent';
onDataChange(data: string) {
console.log('Data from child:', data);
}
}
@Component({
selector: 'app-child',
template: `
<input [(ngModel)]="data" />
<button (click)="sendData()">Send</button>
`
})
export class ChildComponent {
@Input() data: string;
@Output() dataChange = new EventEmitter();
sendData() {
this.dataChange.emit(this.data);
}
}
Manage form controls with `FormArray`:
import { Component } from '@angular/core';
import { FormBuilder, FormArray, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-form-array',
template: `
<form [formGroup]="form">
<div formArrayName="items">
<div *ngFor="let item of items.controls; let i = index">
<input [formControlName]="i" />
</div>
</div>
<button (click)="addItem()">Add Item</button>
</form>
`
})
export class FormArrayComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
items: this.fb.array([this.fb.control('')])
});
}
get items(): FormArray {
return this.form.get('items') as FormArray;
}
addItem() {
this.items.push(this.fb.control(''));
}
}
Manage and handle HTTP requests with `HttpClient`:
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-http',
template: `
<button (click)="fetchData()">Fetch Data</button>
<p *ngIf="data">Data: {{ data | json }}</p>
`
})
export class HttpComponent {
data: any;
constructor(private http: HttpClient) {}
fetchData() {
this.http.get('https://api.example.com/data').subscribe(response => {
this.data = response;
});
}
}
Provide custom providers for dependency injection:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyService } from './my.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
{ provide: MyService, useClass: MyService }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Create a reusable modal component:
import { Component } from '@angular/core';
@Component({
selector: 'app-modal',
template: `
<div class="modal" *ngIf="isVisible">
<div class="modal-content">
<ng-content></ng-content>
<button (click)="close()">Close</button>
</div>
</div>
`,
styles: [`
.modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; justify-content: center; align-items: center; }
.modal-content { background: #fff; padding: 20px; border-radius: 5px; }
`]
})
export class ModalComponent {
isVisible = false;
open() {
this.isVisible = true;
}
close() {
this.isVisible = false;
}
}
Implement a custom validator for a form control:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms';
@Component({
selector: 'app-custom-validator',
template: `
<form [formGroup]="form">
<input formControlName="username" />
<div *ngIf="form.get('username').hasError('customError')">Custom error message</div>
</form>
`
})
export class CustomValidatorComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
username: ['', [this.customValidator()]]
});
}
customValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const isValid = /^[a-zA-Z0-9_]+$/.test(control.value);
return isValid ? null : { customError: true };
};
}
}
Configure an Angular application with Angular Universal:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AppServerModule } from './app.server.module';
@NgModule({
imports: [
BrowserModule.withServerTransition({ appId: 'my-app' }),
AppServerModule
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
Create a directive that modifies the host element's style:
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.removeStyle(this.el.nativeElement, 'backgroundColor');
}
}
Handle the lifecycle of a component with `ngOnInit` and `ngOnDestroy`:
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-lifecycle',
template: `
<p>Component Lifecycle</p>
`
})
export class LifecycleComponent implements OnInit, OnDestroy {
ngOnInit() {
console.log('Component Initialized');
}
ngOnDestroy() {
console.log('Component Destroyed');
}
}
Create a feature module with its own routes:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FeatureComponent } from './feature.component';
const routes: Routes = [
{ path: '', component: FeatureComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
declarations: [FeatureComponent]
})
export class FeatureModule { }
Configure HTTP client interceptors:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { AuthInterceptor } from './auth.interceptor';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Implement a form with nested form groups:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-nested-form',
template: `
<form [formGroup]="form">
<div formGroupName="address">
<input formControlName="street" />
<input formControlName="city" />
</div>
<button (click)="submit()">Submit</button>
</form>
`
})
export class NestedFormComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
address: this.fb.group({
street: [''],
city: ['']
})
});
}
submit() {
console.log(this.form.value);
}
}
Create a component that uses content projection:
import { Component } from '@angular/core';
@Component({
selector: 'app-wrapper',
template: `
<div class="wrapper">
<ng-content></ng-content>
</div>
`,
styles: [`
.wrapper { border: 1px solid #ccc; padding: 10px; }
`]
})
export class WrapperComponent {}
Manage component interactions using Angular Services:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
private dataSubject = new BehaviorSubject('Initial Data');
data$ = this.dataSubject.asObservable();
updateData(newData: string) {
this.dataSubject.next(newData);
}
}
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-consumer',
template: `
<p>Data: {{ data }}</p>
<button (click)="changeData()">Change Data</button>
`
})
export class ConsumerComponent implements OnInit {
data: string;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.data$.subscribe(data => this.data = data);
}
changeData() {
this.dataService.updateData('New Data');
}
}
Configure lazy loading of feature modules:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MainComponent } from './main.component';
const routes: Routes = [
{ path: '', component: MainComponent },
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Set up a module with providers for different environments:
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { environment } from '../environments/environment';
@NgModule({
imports: [HttpClientModule],
providers: [
{ provide: 'API_URL', useValue: environment.apiUrl }
]
})
export class AppModule { }
Create a reusable dialog component:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-dialog',
template: `
<div class="dialog">
<div class="dialog-content">
<ng-content></ng-content>
</div>
</div>
`,
styles: [`
.dialog { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; justify-content: center; align-items: center; }
.dialog-content { background: #fff; padding: 20px; border-radius: 5px; }
`]
})
export class DialogComponent {}
Implement a dynamic component loader:
import { Component, ComponentFactoryResolver, ViewContainerRef, OnInit } from '@angular/core';
@Component({
selector: 'app-dynamic-loader',
template: `
<ng-template #dynamicContainer></ng-template>
`
})
export class DynamicLoaderComponent implements OnInit {
@ViewChild('dynamicContainer', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
ngOnInit() {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(SomeDynamicComponent);
this.container.createComponent(componentFactory);
}
}
Manage animations with Angular's animation library:
import { Component } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations';
@Component({
selector: 'app-animated',
template: `
<div [@fadeInOut]="state" (click)="toggle()">Click me to toggle animation</div>
`,
animations: [
trigger('fadeInOut', [
state('in', style({ opacity: 1 })),
state('out', style({ opacity: 0 })),
transition('in <=> out', [animate('0.5s')])
])
]
})
export class AnimatedComponent {
state = 'in';
toggle() {
this.state = this.state === 'in' ? 'out' : 'in';
}
}
Provide configuration settings for a specific environment:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { environment } from '../environments/environment';
@NgModule({
imports: [CommonModule, HttpClientModule],
providers: [
{ provide: 'API_URL', useValue: environment.apiUrl }
]
})
export class AppModule { }
Manage form validation with asynchronous validators:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, AsyncValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { debounceTime, map, catchError } from 'rxjs/operators';
@Component({
selector: 'app-async-validator',
template: `
<form [formGroup]="form">
<input formControlName="username" />
<div *ngIf="form.get('username').hasError('asyncError')">Username is already taken</div>
</form>
`
})
export class AsyncValidatorComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
username: ['', [], [this.asyncValidator()]]
});
}
asyncValidator(): AsyncValidatorFn {
return (control: AbstractControl): Observable => {
return of(control.value).pipe(
debounceTime(300),
map(value => value === 'admin' ? { asyncError: true } : null),
catchError(() => of(null))
);
};
}
}
Implement a custom pipe for transforming data:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'reverse'
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Handle route guards for protecting routes:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
const isAuthenticated = false; // Check authentication logic
if (!isAuthenticated) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}
Create a component that listens to events from a child component:
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-child',
template: `<button (click)="notifyParent()">Notify</button>`
})
export class ChildComponent {
@Output() notify: EventEmitter = new EventEmitter();
notifyParent() {
this.notify.emit();
}
}
@Component({
selector: 'app-parent',
template: `
<app-child (notify)="onNotify()"></app-child>
`
})
export class ParentComponent {
onNotify() {
console.log('Child component event received');
}
}
Implement dependency injection for services:
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-example',
template: `<div>Data: {{ data }}</div>`,
providers: [DataService]
})
export class ExampleComponent {
data: string;
constructor(private dataService: DataService) {
this.data = this.dataService.getData();
}
}
Configure feature modules with lazy loading and preloading strategies:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MainComponent } from './main.component';
const routes: Routes = [
{ path: '', component: MainComponent },
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
exports: [RouterModule]
})
export class AppRoutingModule { }
Configure dependency injection for a multi-provider scenario:
import { NgModule } from '@angular/core';
import { SomeService } from './some.service';
import { AnotherService } from './another.service';
@NgModule({
providers: [
{ provide: SomeService, useClass: AnotherService, multi: true }
]
})
export class AppModule { }
Implement dynamic content projection with multiple slots:
import { Component } from '@angular/core';
@Component({
selector: 'app-multi-slot',
template: `
<ng-content select="[header]"></ng-content>
<div class="body"><ng-content></ng-content></div>
<ng-content select="[footer]"></ng-content>
`,
styles: [`
.body { padding: 10px; }
`]
})
export class MultiSlotComponent { }
Manage and bind data to a table with sorting and filtering:
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-table',
template: `
<input [formControl]="filterControl" placeholder="Filter">
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of filteredItems">
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
</tr>
</tbody>
</table>
`
})
export class TableComponent {
filterControl = new FormControl('');
items = [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }];
filteredItems = this.items;
constructor() {
this.filterControl.valueChanges.subscribe(filterText => {
this.filteredItems = this.items.filter(item => item.name.includes(filterText));
});
}
}
Create a component that handles file uploads:
import { Component } from '@angular/core';
@Component({
selector: 'app-file-upload',
template: `
<input type="file" (change)="onFileChange($event)" />
`
})
export class FileUploadComponent {
onFileChange(event) {
const file = event.target.files[0];
if (file) {
console.log('Selected file:', file);
}
}
}
Manage state with a Redux-like pattern:
import { Component } from '@angular/core';
import { Store, Select } from '@ngxs/store';
import { Observable } from 'rxjs';
import { Increment } from './counter.actions';
import { CounterState } from './counter.state';
@Component({
selector: 'app-counter',
template: `
<button (click)="increment()">Increment</button>
<p>Count: {{ count$ | async }}</p>
`
})
export class CounterComponent {
@Select(CounterState.getCount) count$: Observable;
constructor(private store: Store) {}
increment() {
this.store.dispatch(new Increment());
}
}
Configure multiple routers for different feature modules:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Feature1Component } from './feature1.component';
import { Feature2Component } from './feature2.component';
const feature1Routes: Routes = [
{ path: 'feature1', component: Feature1Component }
];
const feature2Routes: Routes = [
{ path: 'feature2', component: Feature2Component }
];
@NgModule({
imports: [
RouterModule.forChild(feature1Routes),
RouterModule.forChild(feature2Routes)
],
exports: [RouterModule]
})
export class FeatureRoutingModule { }
Create a custom directive for toggling visibility:
import { Directive, ElementRef, Input, Renderer2 } from '@angular/core';
@Directive({
selector: '[appToggleVisibility]'
})
export class ToggleVisibilityDirective {
@Input() set appToggleVisibility(visible: boolean) {
this.renderer.setStyle(this.el.nativeElement, 'display', visible ? 'block' : 'none');
}
constructor(private el: ElementRef, private renderer: Renderer2) {}
}
Integrate with external libraries or APIs:
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-external-api',
template: `
<div *ngIf="data">
<p>Data from API: {{ data | json }}</p>
</div>
`
})
export class ExternalApiComponent implements OnInit {
data: any;
constructor(private http: HttpClient) {}
ngOnInit() {
this.http.get('https://api.example.com/data')
.subscribe(response => this.data = response);
}
}
Manage form validation with reactive forms:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input formControlName="name" placeholder="Name" />
<div *ngIf="form.get('name').invalid && form.get('name').touched">
Name is required
</div>
<button type="submit" [disabled]="form.invalid">Submit</button>
</form>
`
})
export class ReactiveFormComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: ['', Validators.required]
});
}
onSubmit() {
console.log(this.form.value);
}
}
Create a custom pipe for transforming data:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'reverse'
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Configure routes with child routes and route guards:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ParentComponent } from './parent.component';
import { ChildComponent } from './child.component';
import { AuthGuard } from './auth.guard';
const routes: Routes = [
{
path: 'parent',
component: ParentComponent,
canActivate: [AuthGuard],
children: [
{ path: 'child', component: ChildComponent }
]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Implement advanced animations with `@angular/animations`:
import { Component } from '@angular/core';
import { trigger, transition, style, animate } from '@angular/animations';
@Component({
selector: 'app-animate',
template: `
<div [@fadeInOut]="state">Content</div>
<button (click)="toggle()">Toggle</button>
`,
animations: [
trigger('fadeInOut', [
transition(':enter', [
style({ opacity: 0 }),
animate('500ms', style({ opacity: 1 }))
]),
transition(':leave', [
animate('500ms', style({ opacity: 0 }))
])
])
]
})
export class AnimateComponent {
state = 'visible';
toggle() {
this.state = this.state === 'visible' ? 'hidden' : 'visible';
}
}
Configure dynamic module loading and module federation:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MainComponent } from './main.component';
const routes: Routes = [
{ path: '', component: MainComponent },
{ path: 'dynamic', loadChildren: () => import('./dynamic/dynamic.module').then(m => m.DynamicModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Handle internationalization (i18n) for multilingual applications:
import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-i18n',
template: `
<div>
<p>{{ 'WELCOME_MESSAGE' | translate }}</p>
<button (click)="switchLanguage('en')">English</button>
<button (click)="switchLanguage('es')">Español</button>
</div>
`
})
export class I18nComponent {
constructor(private translate: TranslateService) {
translate.setDefaultLang('en');
}
switchLanguage(lang: string) {
this.translate.use(lang);
}
}
Implement a custom form control with `ControlValueAccessor`:
import { Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-custom-input',
template: `
<input [value]="value" (input)="onChange($event.target.value)" />
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true
}
]
})
export class CustomInputComponent implements ControlValueAccessor {
value: any;
onChange = (value: any) => {};
onTouched = () => {};
writeValue(value: any): void {
this.value = value;
}
registerOnChange(fn: (value: any) => void): void {
this.onChange = fn;
}
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {}
}
Integrate with third-party libraries and configure their modules:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { SomeThirdPartyModule } from 'some-third-party-library';
@NgModule({
imports: [
BrowserModule,
SomeThirdPartyModule.forRoot()
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
Implement a component with custom input decorators and property bindings:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-custom-input',
template: `
<div>
<p>Input value: {{ value }}</p>
<button (click)="notify.emit(value)">Notify</button>
</div>
`
})
export class CustomInputComponent {
@Input() value: string;
@Output() notify = new EventEmitter();
}
Create a component that interacts with a WebSocket service:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { WebSocketService } from './web-socket.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-web-socket',
template: `
<div>
<p>WebSocket Data: {{ data }}</p>
</div>
`
})
export class WebSocketComponent implements OnInit, OnDestroy {
data: string;
private subscription: Subscription;
constructor(private webSocketService: WebSocketService) {}
ngOnInit() {
this.subscription = this.webSocketService.getData().subscribe(data => {
this.data = data;
});
}
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
}
Handle dynamic component loading and rendering:
import { Component, ViewContainerRef, ComponentFactoryResolver, OnInit } from '@angular/core';
import { DynamicComponent } from './dynamic.component';
@Component({
selector: 'app-dynamic-loader',
template: `
<ng-template #dynamicContainer></ng-template>
<button (click)="loadComponent()">Load Dynamic Component</button>
`
})
export class DynamicLoaderComponent implements OnInit {
@ViewChild('dynamicContainer', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) {}
ngOnInit() {}
loadComponent() {
const factory = this.resolver.resolveComponentFactory(DynamicComponent);
this.container.clear();
this.container.createComponent(factory);
}
}