Conditional Rendering in Angular: *ngIf, @if, and ngClass

If you've been building Angular apps for any amount of time, you've run into the need to show or hide elements based on some condition  a loading spinner, an error message, a user-specific button. Angular gives you powerful tools to handle all of this directly in your templates. 

In this guide, we'll walk through the classic *ngIf directive, the modern @if block syntax introduced in Angular 17, and how ngClass fits into the picture.



What Is *ngIf and Why Does It Matter?

*ngIf is a structural directive meaning it physically adds or removes elements from the DOM, not just hides them with CSS. That's a meaningful difference. When an element is removed from the DOM, Angular also destroys its component tree, freeing up memory. This makes *ngIf more performant than display: none for large or deeply nested UIs.

<p *ngIf="isLoggedIn">Welcome back, {{ username }}!</p>

If isLoggedIn is false, that <p> tag doesn't exist in the DOM at all  Angular never renders it.

Handling the Else Case

The else branch uses an <ng-template> with a template reference variable. It's a little verbose, but it gets the job done:

<div *ngIf="isLoading; else content">Loading...</div>
<ng-template #content>
  <p>Data loaded successfully!</p>
</ng-template>

The #content reference links the template to the else clause. One thing to watch out for: if that reference doesn't exist or is misspelled, Angular throws an NG01352 error at runtime. Always double-check your template variable names.

Simulating else if With *ngIf

Angular's *ngIf doesn't have a native else if. The workaround is to nest another *ngIf inside an <ng-template>:

<ng-container *ngIf="condition1; then block1 else block2"></ng-container>

<ng-template #block1>Content for condition1</ng-template>
<ng-template #block2>
  <div *ngIf="condition2">Content for condition2</div>
  <div *ngIf="!condition2">Fallback content</div>
</ng-template>

It works, but it gets messy fast. That's exactly the pain point Angular 17 addresses head-on.

Angular 17+ : Enter @if, @else if, and @else

Angular 17 shipped a completely revamped control flow syntax built directly into the compiler. No more *ngIf. No more <ng-template>. Just clean, readable blocks that look and feel like real control flow:

@if (user.role === 'admin') {
  <button>Edit Settings</button>
} @else if (user.role === 'editor') {
  <button>Draft Post</button>
} @else {
  <p>Guest users cannot perform actions.</p>
}

This is a massive improvement in developer experience. Native @else if support alone eliminates a ton of awkward nesting.

Before vs. After

Old Syntax (Angular ≤16) New Syntax (Angular 17+)
*ngIf="isLoggedIn; else loggedOut"+ <ng-template> @if (isLoggedIn) { ... } @else { ... }
No native else if @else if works natively
Requires NgIf import Built into the compiler — no import needed
Verbose, boilerplate-heavy Clean, readable blocks

Type Narrowing Is Now Built In

One underrated benefit of the new syntax is TypeScript-aware type narrowing. Inside an @if block, Angular's compiler knows the type has been checked:

// component.ts
user: User | null = null;

// template
@if (user) {
  <p>{{ user.name }}</p>  <!-- TypeScript knows user is non-null here -->
}

No more ?. safe navigation operators sprinkled everywhere just to avoid null errors.

Pairing with @for and @empty

The new control flow syntax doesn't stop at conditionals. It pairs naturally with @for loops and an @empty block for handling empty lists:

@for (item of items; track item.id) {
  <div>{{ item.name }}</div>
} @empty {
  <p>No items found.</p>
}

Previously, you'd combine *ngFor with an *ngIf check for empty state. Now it's a single, self-contained block.

Dynamic Styling with ngClass

While *ngIf and @if control whether an element exists, ngClass controls how it looks. They complement each other well:

<!-- Apply a single class conditionally -->
<div [ngClass]="{ 'active': isActive }">...</div>

<!-- Apply multiple classes based on different conditions -->
<div [ngClass]="{ 'success': isSuccess, 'error': hasError }">...</div>

A common real-world pattern: use @if to decide if a component renders, and ngClass to handle its visual states once it does.

Common Real-World Use Cases

  • Loading states : Show a spinner while data fetches, swap it for content when ready
  • Error handling : Display alert banners only when an error flag is set
  • Authentication gates : Show Login/Logout buttons based on session state
  • Role-based UI : Render different controls for admins, editors, and viewers using @else if

Best Practices Worth Following

Keep complex logic out of templates. If your condition has more than one or two checks, move it to a getter in the component:

// component.ts
get isUserValid(): boolean {
  return this.user && this.user.isActive;
}

// template
<div *ngIf="isUserValid">...</div>

Use <ng-container> when you need a conditional wrapper that shouldn't add a real DOM node. It's invisible in the rendered output.

Start migrating to @if today. Angular plans to phase out structural directives in favor of the new block syntax. There's an automatic migration command:

ng generate @angular/core:control-flow

This migrates your entire project's *ngIf, *ngFor, and *ngSwitch to the new syntax in one shot.

Troubleshooting: NG01352 Error

If Angular throws NG01352, it can't find the <ng-template> referenced in your *ngIf else clause. The fix is usually one of two things:

  • The #templateName variable is misspelled or missing
  • The template is defined inside another structural directive  Angular can't reach it from there
<!-- This breaks if #missingTemplate doesn't exist -->
<div *ngIf="condition; else missingTemplate"></div>

Quick Reference

Feature *ngIf (≤ Angular 16) @if (Angular 17+)
Basic conditional
Else support ✅ via <ng-template> ✅ natively
Else if ❌ (workaround needed) ✅ natively
Type narrowing
Import required NgIf from @angular/common None
Boilerplate High Minimal

Whether you're maintaining an older codebase or starting fresh, understanding both *ngIf and the new @if syntax gives you the full picture of Angular's conditional rendering story. The new block syntax is clearly the direction Angular is heading  cleaner templates, better type safety, and noticeably faster rendering. Start with the migration command, and you'll be surprised how quick the switch is.

Further Reading:





40+ Angular and JavaScript Interview Questions


lets discuss 40 + frequently asked angular and JavaScript interview questions  and answers


JavaScript Interview Questions

1. What are closures in JavaScript?

  • Closures allow an inner function to remember variables from its outer function even after the outer function has finished executing.

function outer() {

  let count = 0;

  return function inner() {

    count++;

    return count;

  };

}

const counter = outer();

console.log(counter()); // 1

console.log(counter()); // 2


  • Closures power callbacks, event listeners, and async programming all of which are used in Angular.

2. Difference between var, let, and const?

  • var : functionscoped, can be redeclared.
  • let : blockscoped, reassignable.
  • const: blockscoped, cannot be reassigned.

3. What is event delegation?

  • Instead of attaching event listeners to multiple child elements, you attach one to the parent. The event bubbles up and gets handled at the parent level.

  •  Saves memory and improves performance—super important in large apps.

4. Difference between == and ===?

  • ==  loose equality (performs type conversion).
  • ===  strict equality (compares type + value).
  • Always use === to avoid bugs.

5. What is the event loop in JavaScript?

  • The event loop is what makes JavaScript asynchronous. It constantly checks the call stack and the callback queue, allowing nonblocking code execution.

6. What are Promises and async/await?

  • Promise :represents a future value (resolved or rejected).
  • async/await: syntactic sugar for writing cleaner asynchronous code.

async function fetchData() {

  const res = await fetch('/api/data');

  return res.json();

}

7. What is hoisting?

  • Hoisting means JavaScript moves variable and function declarations to the top of their scope before code execution.

8. Difference between null and undefined?

  • null : intentional “no value.”
  • undefined : variable declared but not assigned.

9. What are arrow functions, and how are they different?

  • Arrow functions don’t have their own this. They inherit it from their surrounding scope.
  • Useful in Angular callbacks and RxJS streams.

10. What is the difference between synchronous and asynchronous JavaScript?

  • Synchronous : one task at a time.
  • Asynchronous : tasks can run in the background (timers, API calls).

11. What is a callback function?

  • A callback is a function passed as an argument and executed later.

12. What is a prototype in JavaScript?

  • Every JS object has a prototype, which enables inheritance. Angular’s TypeScript classes compile down to prototypebased JS.

13. What are higherorder functions?

  • Functions that take other functions as arguments or return them.
  • Examples: map(), filter(), reduce().

14. Explain deep copy vs shallow copy.

  • Shallow copy: copies only toplevel properties.
  • Deep copy  means copies nested objects as well.

Angular Interview Questions

15. What is Angular, and how does it differ from AngularJS?

  • AngularJS (1.x) :JavaScriptbased, MVC, slower.
  • Angular (2+) :TypeScriptbased, componentdriven, faster.

16. What are the main building blocks of Angular?

  • Modules
  • Components
  • Templates
  • Directives
  • Services
  • Pipes

17. What is Dependency Injection in Angular?

DI means Angular creates and injects services instead of you creating them manually. Makes code testable and modular.

18. Explain Angular data binding.

  • Interpolation : {{ name }}
  • Property binding : [src]="imageUrl"
  • Event binding :(click)="onClick()"
  • Twoway binding : [(ngModel)]="username"
check here for more details on data binding in angular

19. What are lifecycle hooks in Angular?

  • ngOnInit() : runs after component loads
  • ngOnChanges() : detects input property changes
  • ngOnDestroy() :cleanup before component is destroyed

for more details on 8 life cycle hooks angular 

20. How do Angular components communicate?

  • @Input() - Parent - Child
  • @Output() -Child -Parent
  • Services with RxJS :Share data across components

21. What are Angular directives?

  • Structural : *ngIf, *ngFor
  • Attribute : [ngClass], [ngStyle]

22. What is Angular Routing?

  • Routing allows navigation between views. Features include:
  • Route parameters (:id)
  • Lazy loading
  • Route guards

23. What are Observables in Angular?

  • Observables (via RxJS) handle async data streams (HTTP requests, events, sockets).
  • Unlike promises, they can emit multiple values over time.

24. What is Angular Ivy?

  • Ivy is the rendering engine that makes Angular apps smaller and faster.

25. What is Angular Universal?

  • It enables ServerSide Rendering (SSR) for SEO and performance.

26. How does Angular handle forms?

  • Templatedriven forms : simpler.
  • Reactive forms:  more control, better validation.

27. What are Angular Pipes?

  • Transform data in templates. Examples: date, currency, async.
  • You can also build custom pipes.

28. What is lazy loading in Angular?

  • Loads modules only when needed, reducing initial bundle size.

29. What are Guards in Angular routing?

  • Guards like CanActivate and CanDeactivate control route access.

30. What is ViewEncapsulation?

  • Controls how CSS styles are applied:
  • Emulated (default)
  • None
  • ShadowDOM

31. What are standalone components in Angular 17+?

  • Standalone components don’t need NgModules, making apps simpler.

32. What are Angular Signals?

  • Signals are new reactive primitives for managing state, simpler than RxJS in some cases.

33. What are Angular Zones?

  • NgZone tracks async tasks and triggers change detection.

34. What is AheadofTime (AOT) compilation?

  • AOT compiles Angular templates at build time & faster runtime performance.

35. Difference between templatedriven and reactive forms?

36. How do you improve performance in Angular apps?

  • Lazy loading
  • OnPush change detection
  • TrackBy in *ngFor
  • Caching API responses

37. Difference between Subject, BehaviorSubject, and ReplaySubject in RxJS?

  • Subject: plain multicast observable.
  • BehaviorSubject: holds last value.
  • ReplaySubject: replays multiple past values.

38. How do you handle state management in Angular?

  • RxJS services
  • NgRx
  • Akita
  • Signals (newer alternative)

39. Difference between Reactive and Imperative programming?

  • Reactive: declarative, uses streams (RxJS, signals).
  • Imperative : stepbystep instructions.

40. How do you make Angular apps SEOfriendly?

  • Angular Universal (SSR)
  • Prerendering
  • Meta tags
  • Lazyloaded images

Here is Quick Revision for you: 40 Angular & JavaScript Interview Questions 

JavaScript Questions
  1. Closures: Inner function remembers variables from outer function even after execution.
  2. var vs let vs const: var = function scope, let = block scope, const = block scope (no reassignment).
  3. Event delegation:Attach one listener to parent, handle child events via bubbling.
  4. == vs === : == loose equality with type coercion, === strict equality.
  5. Event loop : Handles async tasks by moving them from queue to call stack.
  6. Promises vs async/await: Promise handles async values; async/await makes them cleaner.
  7. Hoisting:JS moves declarations (not assignments) to the top at runtime.
  8. null vs undefined: null = intentional empty, undefined = unassigned.
  9. Arrow functions: Short syntax, no own this.
  10. Sync vs Async JS: Sync = one task at a time; Async = tasks in background.
  11. Callback: Function passed into another to be executed later.
  12. Prototype: Enables inheritance in JS objects.
  13. Higherorder function: Function that takes/returns another function (map, filter).
  14. Deep vs shallow copy: Shallow copies only one level; deep copies nested too.
Angular interview Questions
  1. Angular vs AngularJS: Angular = TypeScript, faster, componentbased; AngularJS = JS, MVC.
  2. Building blocks: Modules, Components, Templates, Directives, Services, Pipes.
  3. Dependency Injection: Angular provides services/objects automatically.
  4. Data binding: Interpolation, property, event, twoway ([(ngModel)]).
  5. Lifecycle hooks: ngOnInit, ngOnChanges, ngOnDestroy.
  6. Component communication: @Input, @Output, services with RxJS.
  7. Directives: Structural (*ngIf, *ngFor) and Attribute (ngClass).
  8. Routing: Navigation between views, supports lazy loading and guards.
  9. Observables: Async streams of data (multiple values over time).
  10. Ivy: New rendering engine, smaller bundles, faster.
  11. Universal (SSR): Serverside rendering for SEO and performance.
  12. Forms: Templatedriven (simple) vs Reactive (scalable, powerful).
  13. Pipes: Transform data (date, currency, async, custom).
  14. Lazy loading: Loads modules on demand for performance.
  15. Guards: Control access to routes (CanActivate, CanDeactivate).
  16. ViewEncapsulation: Controls style scope (Emulated, ShadowDOM, None).
  17. Standalone components :Angular 17+, no need for NgModules.
  18. Signals : New reactive state primitive, simpler than RxJS in some cases.
  19. Zones (NgZone) :Detect async tasks, trigger change detection.
  20. AOT compilation : Precompiles templates at build time.
  21. Template vs Reactive forms :Template = simple, Reactive = complex validation.
  22. Performance optimization: Lazy load, OnPush, TrackBy, cache data.
  23. Subject vs BehaviorSubject vs ReplaySubject :Subject : plain, Behavior :last value, Replay : past values.
  24. State management: RxJS, NgRx, Akita, Signals.
  25. Reactive vs Imperative programming: Reactive = declarative streams, Imperative = stepbystep.
  26. SEO in Angular : Angular Universal, prerendering, meta tags, lazyloaded images.
please provide your valuable suggestion's and comments 

apex charts angular

A Brief Tutorial on Using ApexCharts with Angular

apex charts angular


Quick Installation

  1. Install dependencies:

    npm i apexcharts ng-apexcharts
    
  2. Import Module (app.module.ts)

Basic Line Chart Example

Component Template (app.component.html)

<apx-chart 
  [series]="chartOptions.series" 
  [chart]="chartOptions.chart"
  [xaxis]="chartOptions.xaxis" 
  [title]="chartOptions.title">
</apx-chart>

Component Class (app.component.ts)

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  chartOptions = {
    series: [{ data: [10, 20, 30, 40] }],
    chart: { type: 'line' },
    xaxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr'] },
    title: { text: 'Basic Line Chart' }
  };
}

Key Features

  1. Dynamic Updates

    updateChart() {
      const newData = this.chartOptions.series[0].data.map(() => 
        Math.floor(Math.random() * 100)
      );
      this.chartOptions = { ...this.chartOptions, series: [{ data: newData }] };
    }
    
  2. Mixed Chart Types – Ability to use multiple chart types in one visualization.

Example Links

Basic Demo: Pie Chart

chartOptions = {
  series: [44, 55, 13],
  chart: { type: 'pie', width: 380 },
  labels: ['Team A', 'Team B', 'Team C']
};

Common Configurations

Styling

chartOptions = {
  chart: { foreColor: '#333' }, // Text color
  colors: ['#4CAF50', '#E91E63'], // Data colors
  grid: { borderColor: '#e0e0e0' } // Grid lines
};

Tooltip Customization

tooltip: {
  theme: 'dark',
  x: { show: false }, // Hide x-axis tooltip
  y: { formatter: (val: number) => `${val} users` } // Custom label
}

Tips for Troubleshooting

  1. Chart Not Rendering?

    • Make sure NgApexchartsModule is imported.
    • Ensure there are no typos with option properties (e.g., xaxis vs xAxis).
  2. Data Not Updating?

    • Assign the entire chartOptions object to enable Angular change detection.
  3. Performance Issues?

    • Use ChangeDetectionStrategy.OnPush for optimization.
    • Debounce quick updates usingrxjs/debounceTime .

Why ApexCharts?

Free & Open Source

  • MIT Licensed

Advanced Features

  • Chart Annotations
  • Data Labels
  • Brush Charts

Native Angular Support

  • Ready-to-use code snippets

For more advanced features like annotations, data labels, brush charts, and others, check out the ApexCharts Documentation.


Angular chart library Highcharts

Highcharts with Angular

Highcharts is a powerful JavaScript library for creating interactive charts and graphs. When combined with Angular, a robust framework for building web applications, you can create dynamic, data-driven visualizations with ease. This guide will walk you through integrating Highcharts into an Angular project, from setup to advanced configurations.

highcharts angular

Why Highcharts with Angular?

  • Rich Features: Supports line, bar, pie, scatter, and complex charts such as heatmaps.
  • Interactivity: Zooming in and out, tooltips, and dynamic updates enhance user engagement.
  • Customization: Theming, annotations, and responsive design.
  • Angular Compatibility: The official highcharts-angular wrapper simplifies integration. Say goodbye to expensive custom solutions!

Prerequisites

  • Node.js and npm tools installed.
  • Angular CLI:
    npm install -g @angular/cli
    
  • Basic knowledge of Angular components and modules.
high charts angular
Project Setup
  1. Create an Angular Project
    ng new highcharts-angular-demo
    cd highcharts-angular-demo
    
  2. Install Dependencies Install Highcharts and Angular wrappers:
    npm install highcharts highcharts-angular
    

Basic Integration

1. Import HighchartsModule

Add HighchartsModule to app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HighchartsChartModule } from 'highcharts-angular';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HighchartsChartModule],
  bootstrap: [AppComponent]
})
export class AppModule {}

2. Create a Chart Component

Inapp.component.ts, define chart options:

import { Component } from '@angular/core';
import * as Highcharts from 'highcharts';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  Highcharts: typeof Highcharts = Highcharts;
  chartOptions: Highcharts.Options = {
    title: { text: 'Monthly Sales' },
    series: [{ type: 'line', data: [1, 2, 3, 4, 5] }]
  };
}

In app.component.html, render the chart:

<highcharts-chart
  [Highcharts]="Highcharts"
  [options]="chartOptions"
  style="width: 100%; height: 400px; display: block;">
</highcharts-chart>

3. Run the App

ng serve

Visit http://localhost:4200 and see your chart!

Dynamic Charts

Update charts reactively using Angular data binding.

1. Add a Button to Update Data

In app.component.html:

<button (click)="updateData()">Add Data</button>

2. Implement Data Update Logic

In app.component.ts:

export class AppComponent {
  //...existing code...
  updateData() {
    this.chartOptions = {
      ...this.chartOptions,
      series: [{ type: 'line', data: [...this.chartOptions.series[0].data, Math.random() * 10] }]
    };
  }
}

Configuration & Customization

1. Chart Types

Change type in series to 'bar', 'pie', etc.:

series: [{ type: 'bar', data: [10, 20, 30] }]

2. Styling

Customize colors, axes, and tooltips:

chartOptions: Highcharts.Options = {
  chart: { backgroundColor: '#f4f4f4' },
  xAxis: { title: { text: 'Month' } },
  yAxis: { title: { text: 'Sales' } },
  tooltip: { valueSuffix: ' units' }
};

3. Exporting

Enable exporting to PNG/PDF:

exporting: { enabled: true }

Advanced Features

1. Highcharts Modules

Import additional features like 3D charts:

npm install highcharts-3d

In app.component.ts:

import HC_3D from 'highcharts/highcharts-3d';
HC_3D(Highcharts);

2. Lazy Loading Chart

Load charts on demand using Angular's ngOnInit:

async ngOnInit() {
  const Highcharts = await import('highcharts');
  // Initialize chart here
}

3. Performance Optimization

  • Use OnPush change detection.
  • Debounce rapid data updates.

Common Issues & Solutions

  1. Chart Not Updating: Reassign chartOptions instead of mutating it.
  2. Missing Dependencies: Ensure highcharts andhighcharts-angular versions match.
  3. Resize Issues: CallHighcharts.charts[0].reflow() on window resize.

Highcharts and Angular together offer a powerful toolkit for data visualization. This guide has enabled you to set up, customize, and optimize charts in an Angular app. Explore the Highcharts documentation for more advanced features such as stock charts or accessibility options.


how to merge objects in javascript

There are various ways to combine two objects in JavaScript. Whether you want to conduct a shallow or deep merge will determine which technique you use.

merge objects in javascript


1. Shallow Merge (Overwrite Properties) in Javascript

  • Using Object.assign():

const obj1 = { a: 1, b: 2 };

const obj2 = { b: 3, c: 4 };


const merged = Object.assign({}, obj1, obj2);

// Result: { a: 1, b: 3, c: 4 }

  • Using the Spread Operator (...):

const merged = {...obj1,...obj2 };

// Result: { a: 1, b: 3, c: 4 }

Note: Both methods are shallow merges—nested objects/arrays are all by reference (not cloned). If there are duplicate keys, subsequent properties will overwrite prior ones.

2. Deep Merge (Recursively Combine Nested Properties) in javascript

  • Using Lodash:

const merged = _.merge({}, obj1, obj2);

  • Custom Deep Merge Function (Simplified Example):

function deepMerge(target, source) {

for (const key in source) {

if (source[key] instanceof Object && target[key]) {

deepMerge(target[key], source[key]);

} else {

target[key] = source[key];

}

}

return target;

}


const merged = deepMerge({}, { a: { x: 1 } }, { a: { y: 2 } });

// Result: { a: { x: 1, y: 2 } }

Other Considerations about merging objects in javascript

  • Shallow Merge: For simple scenarios, employ Object.assign() or the spread operator.
  • Deep Merge: For greater resilience, use a tool such as Lodash (e.g. _.merge()), which is able to contend with sophisticated structures, including arrays and null values
  • Overwriting Behavior: In situations involving conflict over keys, later objects always win.

Preventdefault vs stoppropagation javascript

 Here is a brand new essay about preventDefault() versus stopPropagation() in Angular. I'll start by comparing how they're used with preventDefault() and stopPropagation. We'll also offer a case study for each method and share some tips.

preventdefault vs stoppropagation javascript angular


1. event.preventDefault() in Angular

  • Purpose: To prevent the default action of a browser event (for example, a submission form or hyperlink).
  • Use in Angular: With Angular’s event binding syntax (event)="handler($event)"
.

Example: Prevent link from navigating:

<a href="https://dangerous.com" (click)="onLinkClick($event)">Dangerous Link</a>
onLinkClick(event: MouseEvent) {
  event.preventDefault(); // Stop navigation
  // Custom logic here (e.g., show a modal instead)
}
  • Scenarios Commonly Encountered in Angular:
    • When using (submit) and <form> to cancel form submission.
    • Shut off the default behaviors of anchor tags, buttons, or form fields.

2. event.stopPropagation() in Angular

  • Purpose: Stop event bubbling/capturing in the DOM tree.
  • Use in Angular: To prevent parent and descendant components from receiving the exact same events.

Example: Don't let a press on a button cause the parent <div> method to fire:

<div (click)="onParentClick()">
  <button (click)="onButtonClick($event)">Click Me</button>
</div>
onButtonClick(event: MouseEvent) {
  event.stopPropagation(); // The mom's onParentClick() will not fire
  // Take care of button click
}
  • Specific Cases:
    • Stop nested components from propagating events.
    • Avoid conflict with other handlers dealing in similar space (e.g., dropdown, modals).

3. Key Differences in Angular

preventDefault() stopPropagation()
Focus Prevent browser from default behavior (e.g., form submit) Prevent DOM event bubbling/capturing
Use Case in Angular Cancel navigation, form submission Parent and child Components surface events in their own spaces
Template Syntax (submit)="onSubmit($event)" (click)="onClick($event)"

4. Using Both Together in Angular

Example: Handle a custom form action without submitting and prevent parent components from interpreting it:

<form (submit)="onFormSubmit($event)">
  <button type="submit">Save</button>
</form>
onFormSubmit(event: Event) {
  event.preventDefault(); // Halt the default form submission
  event.stopPropagation(); // Don't let parent events hear about this
  this.saveData(); // Custom logic here, e.g. http call
}

5. Angular Special Notes

Event Modifiers

Angular does not provide its own event modifiers like Vue's .prevent or .stop. You need to call the method explicitly instead:

<form (submit)="onSubmit($event)"></form>
onSubmit(event: Event) {
  event.preventDefault(); // Manually call
}

Component Communication

  • stopPropagation() only affects DOM events, not Angular's @Output().

Example:

<app-child (customEvent)="onChildEvent()"></app-child>
// ChildComponent
@Output() customEvent = new EventEmitter();
emitEvent() {
  this.customEvent.emit();
  // Whether the parent code listens to DOM event propagation, onChildEvent() will fire
}

Change Detection

  • Neither method affects Angular change detection.
  • Use NgZone or ChangeDetectorRef when events bypass Angular's domain (for example, setTimeout).

6. Angular Best Practices

  1. How to Break Free from Inline Calls: Place your methods right in the constituent, rather than inside the official template:

    <a href="#" (click)="onClick($event)">Link</a>
    <button (click)="onClick($event)">Link</button>
    
  2. For Component Communication, Use EventEmitter : Old-fashioned emit rather than DOM event. Use @Output() Stateless Copy for State Changes: Ensure data is never changed after a call to preventDefault(), to be sure change detection fires.


7. Common Traps

  • Lack of $event: Don’t forget to mention $event in the template:

    <button (click)="onClick">Click</button> ❌ Incorrect
    <button (click)="onClick($event)">Click</button> ✅ Correct
    
  • Too Much stopPropagation(): For highly intricate component trees, it can only create debugging headaches.

In Angular:

  • preventDefault(): Regulate browser defaults (e.g., forms, links).
  • stopPropagation(): Control event flow between some connected DOM elements/components.
  • Use both in tandem to finely manage your event firing and your UI experience.


ng-template & ng container in angular

 In an Angular application, the user interface is the fact: the tags themselves, stored in a template file. Most developers are familiar with both components and directives. However, the ng-template directive is a powerful but often misunderstood tool. This blog will teach you what ng-template is, provide some examples, and show how it lets Angular applications display advanced UI patterns.
Understanding ng-template and ng-container in Angular

What is ng-template?

ng-template is an Angular directive that specifies a template block not to be rendered by the browser by default. Instead, it is treated as a blueprint for making dynamic places: when combined with structural directives such as *ngIf, *ngFor, or your own, one of the above might as well be called a register. Here is a way to save.

Characteristics

  1. Not Rendered at the Beginning: It's as if everything inside ng-template were dull, waiting for approval.
  2. Collaborates with Structural Directives: Used to mark content which depends on something like a condition you may want to show a larger view of or data that is supposed to not just go away.
  3. Takes Contextual Information: Lets you pass data to templates for dynamic rendering.

Basic Usage of ng-template

Example 1: Conditional Rendering with *ngIf and else

This is a common use case where alternate content is shown when a particular condition isn’t true:

<div *ngIf="userLoggedIn; else loginPrompt">
  Welcome, {{ username }}!
</div>

<ng-template #loginPrompt>
  <p>Please log in.</p>
</ng-template>

Here:

  • The else clause calls the loginPrompt template.
  • The loginPrompt template only gets rendered when userLoggedInis false.

How It Works:

Angular converts the *ngIf syntax into:

<ng-template [ngIf]="userLoggedIn">
  <div>Welcome, {{ username }}!</div>
</ng-template>

The #loginPrompt is a template reference variable pointing to the ng-template.

The Role of Structural Directives

Structural directives (e.g., *ngIf, *ngFor) manipulate the DOM by adding or removing elements. As it turns out, they use ng-template to define the content they manage.

Example 2: How *ngFor Uses ng-template

This code:

<ul>
  <li *ngFor="let item of items; let i = index">{{ i }}: {{ item }}</li>
</ul>

Turns into this thanks to Angular:

<ul>
  <ng-template ngFor let-item [ngForOf]="items" let-i="index">
    <li>{{ i }}: {{ item }}</li>
  </ng-template>
</ul>

The contents of ng-template provide the structure that gets repeated for each item in items .

Advanced Use Cases

1. Dynamic Templates with ngTemplateOutlet

Use ngTemplateOutlet to render a template dynamically, optionally with context data:

@Component({
  template: `
    <ng-container *ngTemplateOutlet="greetingTemplate; context: { $implicit: 'User' }">
    </ng-container>

    <ng-template #greetingTemplate let-message>
      Welcome, {{ message }}!
    </ng-template>
  `
})

Here:

  • ngTemplateOutlet displays greetingTemplate, together with context information.
  • let-message gets the context's $implicit value.

2. Custom Structural Directives

Create reusable directives that leverage ng-template:

@Directive({
  selector: '[appRepeat]'
})
export class RepeatDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef
  ) {}

  @Input() set appRepeat(times: number) {
    this.viewContainer.clear();
    for (let i = 0; i < times; i++) {
      this.viewContainer.createEmbeddedView(this.templateRef, { $implicit: i + 1 });
    }
  }
}

Usage:

<ul>
  <li *appRepeat="3">Item {{ count }}</li>
</ul>

Output:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
3. Content Projection with ng-content and Templates
Pass templates to components as inputs for flexible content projection.
Parent Component:

<app-card>
<ng-template #header>My Custom Header</ng-template>
<ng-template #body>Body: {{ data }}</ng-template>
</app-card>
@Component({
selector: 'app-card',
template: `
<div class="card">
<ng-container *ngTemplateOutlet="headerTemplate"></ng-container>
<ng-container *ngTemplateOutlet="bodyTemplate; context: { data: cardData }"></ng-container>
</div>
`,
})
export class CardComponent {
@ContentChild('header') headerTemplate!: TemplateRef<any>;
@ContentChild('body') bodyTemplate!: TemplateRef<any>;
cardData = 'Sample data';
}

ng-template vs. ng-container

Featureng-templateng-container
RenderingNot rendered by defaultRendered as a lightweight container
Use CaseDefine reusable template blocksGroup elements without adding extra DOM nodes
Structural DirectivesRequires a directive to renderCan host structural directives directly
Best Practices

Child Component (app-card):
  • Avoid Overuse of Templates: Use ng-template only when necessary to keep the DOM clean.

  • Pass Data Through Context: Use context objects for dynamic template rendering.

  • Combine with ng-container: Use ng-container for grouping structural directives to prevent unnecessary DOM elements.

Select Menu