<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: bytebantz</title>
    <description>The latest articles on DEV Community by bytebantz (@bytebantz).</description>
    <link>https://dev.to/bytebantz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1409089%2F81cd3f4f-a6a7-45f3-8adf-fa47897cbde6.jpeg</url>
      <title>DEV Community: bytebantz</title>
      <link>https://dev.to/bytebantz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bytebantz"/>
    <language>en</language>
    <item>
      <title>Web Components in Angular: The Good and Bad of Web Components</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 08 Sep 2025 07:26:47 +0000</pubDate>
      <link>https://dev.to/bytebantz/web-components-in-angular-the-good-and-bad-of-web-components-h64</link>
      <guid>https://dev.to/bytebantz/web-components-in-angular-the-good-and-bad-of-web-components-h64</guid>
      <description>&lt;p&gt;Normally, Angular components work &lt;strong&gt;only inside Angular applications&lt;/strong&gt;. But Angular &lt;strong&gt;createCustomElement()&lt;/strong&gt; allows you to turn an &lt;strong&gt;Angular component&lt;/strong&gt; into a &lt;strong&gt;custom HTML element&lt;/strong&gt; (also called a &lt;strong&gt;web component&lt;/strong&gt;) that can be used anywhere, even outside an Angular app while still keeping all of Angular’s features.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Web Components?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Web components&lt;/strong&gt; are a set of standards that allow developers to create custom HTML elements using JavaScript&lt;/p&gt;

&lt;p&gt;For example, in normal HTML, you have built-in elements like &amp;lt; button &amp;gt; or &amp;lt; input &amp;gt;. But what if you want a new type of element, like &amp;lt; cool-button &amp;gt;? You can create it using JavaScript.&lt;/p&gt;

&lt;p&gt;Web Components allow you to mix and match different UI components from various sources. However, just because you can doesn’t mean you should.&lt;/p&gt;

&lt;p&gt;If one Web Component uses React, another Vue, and another Angular, the browser has to load separate runtimes, which:&lt;/p&gt;

&lt;p&gt;❌Makes the page &lt;strong&gt;slower&lt;/strong&gt; (more JavaScript to download and execute).&lt;/p&gt;

&lt;p&gt;❌Increases &lt;strong&gt;file size&lt;/strong&gt; (bad for performance).&lt;/p&gt;

&lt;p&gt;❌Creates &lt;strong&gt;maintenance headaches&lt;/strong&gt; (hard to manage different technologies).&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of using Web Components:
&lt;/h2&gt;

&lt;p&gt;✅&lt;strong&gt;Reusability:&lt;/strong&gt; Custom elements allow for code sharing across different projects.&lt;/p&gt;

&lt;p&gt;✅&lt;strong&gt;Flexibility:&lt;/strong&gt; They can be used in any web application regardless of the framework.&lt;/p&gt;

&lt;p&gt;✅&lt;strong&gt;Easy Integration:&lt;/strong&gt; They can be seamlessly added to existing web applications to introduce new functionality.&lt;/p&gt;

&lt;p&gt;✅&lt;strong&gt;Future-Proofing&lt;/strong&gt; — Based on web standards, reducing framework dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges involved in using Web Components:
&lt;/h2&gt;

&lt;p&gt;❌&lt;strong&gt;Browser Support&lt;/strong&gt;: Not all browsers support web components, which can limit usage in older browsers.&lt;/p&gt;

&lt;p&gt;❌&lt;strong&gt;Complexity:&lt;/strong&gt; Creating custom elements can be challenging.&lt;/p&gt;

&lt;p&gt;❌&lt;strong&gt;Debugging:&lt;/strong&gt; Debugging custom elements, especially in complex applications, can be difficult.&lt;/p&gt;

&lt;p&gt;Angular provides support for Web Components through &lt;strong&gt;Angular Elements&lt;/strong&gt;, allowing developers to create Web Components from Angular components.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;createCustomElement()&lt;/strong&gt; function takes an Angular component and turns it into a &lt;strong&gt;JavaScript class&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const coolButtonElement = createCustomElement(CoolButtonComponent, { injector });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This JavaScript class can then be registered with the browser as a &lt;strong&gt;custom element&lt;/strong&gt; using the browser’s built-in &lt;strong&gt;customElements.define()&lt;/strong&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customElements.define('cool-button', coolButtonElement);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser keeps track of all custom elements using something called the &lt;strong&gt;CustomElementRegistry&lt;/strong&gt;, which links each tag (like &amp;lt; cool-button &amp;gt;) to its JavaScript class (CoolButton).&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Important Note&lt;/strong&gt;&lt;br&gt;
Avoid using your Angular component’s selector as the Web Component tag name.&lt;/p&gt;

&lt;p&gt;For example, if your component’s selector is &lt;em&gt;app-alert&lt;/em&gt;, and you use it as the custom element tag &amp;lt; app-alert &amp;gt;&amp;lt; /app-alert &amp;gt;, it can cause issues.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Angular might try to create two instances of the component for the same DOM element:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;One instance using the regular Angular component system.&lt;/li&gt;
&lt;li&gt;Another instance using the custom element registration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you register this class with the browser’s &lt;strong&gt;custom element registry&lt;/strong&gt;, it becomes a special HTML tag that you can use just like any built-in HTML element (e.g., &amp;lt; cool-button &amp;gt;&amp;lt; /cool-button &amp;gt;).&lt;/p&gt;
&lt;h2&gt;
  
  
  Handling Inputs &amp;amp; Outputs in Web Components
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Handling Inputs&lt;/strong&gt;&lt;br&gt;
When you convert an Angular component into a custom element, the process automatically handles the &lt;strong&gt;input properties&lt;/strong&gt; and &lt;strong&gt;converts them into attributes&lt;/strong&gt; for the custom element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom elements&lt;/strong&gt; require &lt;strong&gt;attributes&lt;/strong&gt; to use &lt;strong&gt;dash-separated lowercase names&lt;/strong&gt;, and they don’t recognize &lt;strong&gt;camelCase&lt;/strong&gt; which Angular uses for property names.&lt;/p&gt;

&lt;p&gt;Angular automatically changes the input property names from &lt;strong&gt;camelCase&lt;/strong&gt; (like myInputProp) to &lt;strong&gt;dash-separated lowercase&lt;/strong&gt; (like my-input-prop) so that it fits the &lt;strong&gt;custom element&lt;/strong&gt; requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handling Outputs&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Angular automatically converts output events to Custom Events&lt;/strong&gt; and uses either the original output name or the alias you provide as the event name for the custom element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: No alias&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have a component with this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Output() valueChanged = new EventEmitter();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the event valueChanged is triggered, it becomes a Custom Event in the DOM, and you can listen to it like this in HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;my-element (valueChanged)="handleValueChanged($event)"&amp;gt;&amp;lt;/my-element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 2: With alias&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you use an alias with the &lt;strong&gt;@Output()&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Output('myClick') clicks = new EventEmitter();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the custom event name becomes myClick instead of clicks. You can listen to it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;my-element (myClick)="handleClick($event)"&amp;gt;&amp;lt;/my-element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Shadow DOM and Encapsulation
&lt;/h2&gt;

&lt;p&gt;Web Components are rendered in the shadow DOM&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Terms&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Host&lt;/strong&gt; 🏠: The regular DOM element to which a shadow DOM is attached&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Tree&lt;/strong&gt; 🌳: The DOM structure inside the shadow DOM. This tree is encapsulated, meaning styles and scripts from the main document won’t affect it unless explicitly allowed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Boundary&lt;/strong&gt; ✋: The invisible boundary separating the shadow DOM from the main DOM. Anything outside this boundary can’t directly style or interact with shadow DOM elements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Root&lt;/strong&gt; 🌱: The root of the shadow tree. It’s where all shadow content starts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Shadow DOM&lt;/strong&gt; is a way to encapsulate styles and behavior within a web component. This means that elements inside a &lt;strong&gt;Shadow DOM&lt;/strong&gt; behave as if they are in a separate, isolated world. The styles outside don’t affect them, and their styles don’t affect the rest of the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this useful?
&lt;/h2&gt;

&lt;p&gt;✅It prevents conflicts between styles and scripts from different parts of a website.&lt;/p&gt;

&lt;p&gt;✅It allows developers to create &lt;strong&gt;reusable components&lt;/strong&gt; without worrying about breaking the rest of the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But This Encapsulation Also Brings Challenges!&lt;/strong&gt;&lt;br&gt;
Because the Shadow DOM is isolated, certain &lt;strong&gt;normal browser behaviors don’t work as expected&lt;/strong&gt;. Some events don’t bubble out of the Shadow DOM, certain form elements don’t behave normally, and even CSS has limitations.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Are the Key Challenges?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Events Might Not Bubble&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Normally, when you click an element, the event “bubbles up” to parent elements.&lt;br&gt;
But inside the Shadow DOM, some events (like focusin) stop at the Shadow boundary and don’t continue to the outer document.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Some Events Behave Differently&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Events like focusin and mouseenter don’t behave as expected because the Shadow DOM treats the entire component as a single unit.&lt;br&gt;
A child element inside the Shadow DOM might gain focus, but the event reports that the focus is on the whole component instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. CSS Encapsulation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Styles inside a Shadow DOM don’t affect elements outside it, and vice versa.&lt;br&gt;
This is great for preventing unwanted style conflicts but can cause issues if you need to apply global styles to Shadow DOM elements.&lt;/p&gt;
&lt;h2&gt;
  
  
  Web Components and SSR
&lt;/h2&gt;

&lt;p&gt;Web Components rely on browser APIs like &lt;strong&gt;customElements.define(), shadow DOM&lt;/strong&gt;, and &lt;strong&gt;HTML templates&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These APIs don’t exist on the server, which means &lt;strong&gt;Web Components&lt;/strong&gt; don’t naturally work in a &lt;strong&gt;server-side rendering (SSR)&lt;/strong&gt; environment.&lt;/p&gt;

&lt;p&gt;Developers need to create extra wrappers or tricks to make &lt;strong&gt;Web Components&lt;/strong&gt; generate server-side HTML before &lt;strong&gt;hydration&lt;/strong&gt; (the process of making server-rendered HTML interactive).&lt;/p&gt;

&lt;p&gt;This adds &lt;strong&gt;complexity&lt;/strong&gt; and &lt;strong&gt;performance overhead&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Shadow DOM and Hydration Issues
&lt;/h2&gt;

&lt;p&gt;Since Web Components rely on Shadow DOM, they don’t naturally fit into modern hydration strategies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example, Incremental hydration depends on event delegation,&lt;/strong&gt; meaning Angular places global event listeners on the &lt;/p&gt; or a parent component to capture interactions &lt;strong&gt;before hydrating a component.&lt;/strong&gt;

&lt;p&gt;However, &lt;strong&gt;Shadow DOM blocks event delegation&lt;/strong&gt; because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Events do not bubble past the shadow root.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Global event listeners in Angular cannot detect interactions inside a Web Component using Shadow DOM.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What this means:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If a Web Component inside an SSR-rendered Angular app is not hydrated, clicks inside it won’t trigger Angular’s hydration logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Angular will &lt;strong&gt;never detect interactions inside a Shadow DOM&lt;/strong&gt; unless explicitly re-dispatched.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Web Components and Angular Routing
&lt;/h2&gt;

&lt;p&gt;When trying to host a second Angular app as a Web Component within another Angular application, routing often doesn’t work for the hosted app because each Angular application typically has its own isolated router instance; essentially, the parent application’s router doesn’t recognize routes defined within the child web component&lt;/p&gt;
&lt;h2&gt;
  
  
  Web Components Use Cases
&lt;/h2&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;Simplifying Dynamic Component Loading&lt;/strong&gt;&lt;br&gt;
Previously, if you wanted to add a component to a page dynamically (meaning you load it at runtime, not when the page is initially loaded), you had to do things like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the component.&lt;/li&gt;
&lt;li&gt;Add it to the DOM manually (the HTML structure).&lt;/li&gt;
&lt;li&gt;Manually set up dependency injection (services, data) and change detection (keep the view updated).&lt;/li&gt;
&lt;li&gt;Manually wire up events (like clicking buttons, etc.).
This required a lot of code and was pretty complex.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;With Custom Elements:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;strong&gt;Angular Custom Elements&lt;/strong&gt; makes this process much simpler. Here’s how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the Angular component as usual (with your template and logic).&lt;/li&gt;
&lt;li&gt;Convert it to a custom element using Angular’s built-in tools.&lt;/li&gt;
&lt;li&gt;Use it in your HTML as if it were a regular HTML element (like &amp;lt; app-dynamic-component &amp;gt;&amp;lt; /app-dynamic-component &amp;gt;), and Angular takes care of all the setup, dependency injection, and event handling for you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This results in a simplified and streamlined process for dynamically loading components, reducing the amount of code you need to write and making your app easier to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1: Create a New Angular Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new web-components-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Install the @angular/elements package:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @angular/elements --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Create a Dynamic Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component dynamic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the dynamic.component.ts file to include some basic logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, input } from '@angular/core';

@Component({
  selector: 'app-dynamic',
  imports: [],
  template: `&amp;lt;div&amp;gt;{{ text() }}&amp;lt;/div&amp;gt;`,
})
export class DynamicComponent {
  text = input&amp;lt;string&amp;gt;('Default dynamic message!');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Register the Web Component&lt;/p&gt;

&lt;p&gt;In your main.ts, register the DynamicComponent as a web component using Angular Elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
import { createCustomElement } from '@angular/elements';
import { DynamicComponent } from './app/dynamic/dynamic.component';

// Bootstrap the application
bootstrapApplication(AppComponent, appConfig)
  .then((app) =&amp;gt; {
    const dynamicElement = createCustomElement(DynamicComponent, {
      injector: app.injector
    });
    customElements.define('dynamic-component', dynamicElement); // Register the web component
  })
  .catch((err) =&amp;gt; console.error(err));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Dynamically Load the Web Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your &lt;strong&gt;app.component.ts&lt;/strong&gt;, create and insert the web component directly into the DOM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    &amp;lt;button (click)="createComponent()"&amp;gt;Create Dynamic Component&amp;lt;/button&amp;gt;
    &amp;lt;button (click)="destroyComponent()"&amp;gt;Destroy Dynamic Component&amp;lt;/button&amp;gt;
    &amp;lt;div id="container"&amp;gt;&amp;lt;/div&amp;gt;
  `,
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  createComponent() {
    const dynamicComponent = document.createElement('dynamic-component'); // Use the registered tag name
    dynamicComponent.setAttribute(
      'text',
      'Hello, this is a dynamic web component!'
    );
    document.querySelector('#container')?.appendChild(dynamicComponent);
  }

  destroyComponent() {
    const container = document.querySelector('#container');
    if (container) {
      container.innerHTML = ''; // Clear the container to remove all dynamic components
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Shared Design System&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Web Components are great &lt;strong&gt;when you need reusable UI elements that work across different frameworks or projects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine you’re building a &lt;strong&gt;large-scale application&lt;/strong&gt; that has multiple teams working on different sections of the UI. One team uses &lt;strong&gt;Angular&lt;/strong&gt;, another uses &lt;strong&gt;React&lt;/strong&gt;, and a third one uses &lt;strong&gt;Vue&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of each team recreating buttons, modals, and form elements &lt;strong&gt;in their own framework&lt;/strong&gt;, you can build &lt;strong&gt;a set of Web Components&lt;/strong&gt; that work everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  How This Helps
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Framework-Agnostic:&lt;/strong&gt; A Web Component like  can be used in React, Vue, Angular, or even plain HTML.&lt;br&gt;
✅ &lt;strong&gt;Single Source of Truth:&lt;/strong&gt; Instead of maintaining separate versions of the same button in different frameworks, you maintain one component.&lt;br&gt;
✅ &lt;strong&gt;Consistent UI:&lt;/strong&gt; The design stays the same no matter where it’s used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1: Create a new Angular project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new shared-design-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Generate a new Angular element (Web Component)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component my-button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Modify my-button.component.ts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, input } from '@angular/core';

@Component({
  selector: 'app-my-button',
  imports: [],
  template: `&amp;lt;button class="my-button"&amp;gt;{{ label() }}&amp;lt;/button&amp;gt;`,
  styles: [
    `.my-button {
      background-color: #007bff;
      color: white;
      padding: 10px 20px;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      font-size: 16px;
    }`
  ]
})
export class MyButtonComponent {
  label = input&amp;lt;string&amp;gt;('Click Me');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Convert it into a Web Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modify main.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { createCustomElement } from '@angular/elements';
import { MyButtonComponent } from './app/my-button/my-button.component';


// Bootstrap the application
createApplication(appConfig)
  .then((app) =&amp;gt; {
    const myButtonElement = createCustomElement(MyButtonComponent, {
      injector: app.injector
    });
    customElements.define('my-button', myButtonElement); // Register the web component
  })
  .catch((err) =&amp;gt; console.error(err));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key reason createApplication is better for pure Web Components is that it does not automatically render a root component in Angular, unlike bootstrapApplication. Instead, it only initializes the Angular injector and allows you to register custom elements manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Build the Angular Web Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng build --output-hashing=none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6: Test the Web Component&lt;/p&gt;

&lt;p&gt;To support older browsers, polyfills may be needed to provide support for web components.&lt;/p&gt;

&lt;p&gt;If you import polyfills in main.ts, they become part of your main JavaScript bundle. This is fine if you’re only using one Angular web component.&lt;/p&gt;

&lt;p&gt;If you embed multiple custom elements (Angular web components) on a page, each one might load the same polyfills multiple times. This can slow down your app or cause errors.&lt;/p&gt;

&lt;p&gt;Instead of importing polyfills inside main.ts, you can load them separately using a &amp;lt; script &amp;gt; tag in your HTML. This way, they are loaded only once for all components.&lt;/p&gt;

&lt;p&gt;Create a simple index.html:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;title&amp;gt;Web Component Demo&amp;lt;/title&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1" /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;my-button&amp;gt;&amp;lt;/my-button&amp;gt;

    &amp;lt;script src="polyfills.js" type="module"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src="main.js" type="module"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to make your custom elements type-safe
&lt;/h2&gt;

&lt;p&gt;In standard DOM methods like &lt;strong&gt;document.createElement()&lt;/strong&gt; or &lt;strong&gt;document.querySelector()&lt;/strong&gt;, TypeScript infers the type of the element returned based on the argument you provide.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;document.createElement(‘a’)&lt;/strong&gt; returns an HTMLAnchorElement with specific properties like href.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;document.createElement(‘div’)&lt;/strong&gt; returns an HTMLDivElement, which doesn’t have an href property.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, when using &lt;strong&gt;custom elements&lt;/strong&gt;, TypeScript can’t automatically infer the type because it doesn’t know the specific properties of that element.&lt;/p&gt;

&lt;p&gt;It just thinks it’s a basic &lt;strong&gt;HTMLElement&lt;/strong&gt; (a generic HTML element). For example, it doesn’t know your my-dialog element has a content property.&lt;/p&gt;

&lt;p&gt;You have two ways to get TypeScript to understand the properties of your custom elements:&lt;br&gt;
&lt;strong&gt;1. Casting the Type Manually&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you create the custom element, you can &lt;strong&gt;cast&lt;/strong&gt; it to a more specific type that knows about the properties it has.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dialog = document.createElement('my-dialog') as NgElement &amp;amp; WithProperties&amp;lt;{ content: string }&amp;gt;;
dialog.content = 'Hello, world!';  // Now TypeScript knows 'content' is a string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, TypeScript will now know that &lt;strong&gt;dialog.content&lt;/strong&gt; should be a string and give you features like &lt;strong&gt;type checking&lt;/strong&gt; and &lt;strong&gt;autocomplete&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The downside:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have to write this casting (as &lt;strong&gt;NgElement &amp;amp; WithProperties) every time&lt;/strong&gt; you create a custom element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Augmenting TypeScript’s Default Knowledge of Elements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of casting every time, you can tell TypeScript about your custom elements once by adding a special definition.&lt;/p&gt;

&lt;p&gt;This is done by extending the &lt;strong&gt;HTMLElementTagNameMap&lt;/strong&gt; which is how TypeScript knows what properties different HTML tags should have.&lt;/p&gt;

&lt;p&gt;For example, you can add this globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;declare global {
  interface HTMLElementTagNameMap {
    'my-dialog': NgElement &amp;amp; WithProperties&amp;lt;{ content: string }&amp;gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you don’t need to cast the element manually every time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dialog = document.createElement('my-dialog');
dialog.content = 'Hello, world!';  // TypeScript knows 'content' is a string automatically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;strong&gt;augmentation&lt;/strong&gt; is simpler and avoids repetitive code. It ensures TypeScript automatically knows the properties of your custom elements, making your code cleaner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Web Components provide a powerful way to create reusable UI elements that can work across different frameworks. By using Angular Elements, you can easily create and manage these components while maintaining the benefits of Angular’s architecture.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Say Goodbye to EventEmitter: Switch to output() for Custom Events in Angular</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Wed, 03 Sep 2025 09:52:41 +0000</pubDate>
      <link>https://dev.to/bytebantz/say-goodbye-to-eventemitter-switch-to-output-for-custom-events-in-angular-17h</link>
      <guid>https://dev.to/bytebantz/say-goodbye-to-eventemitter-switch-to-output-for-custom-events-in-angular-17h</guid>
      <description>&lt;p&gt;In Angular, components can communicate with each other by &lt;strong&gt;raising events&lt;/strong&gt;. For example, when a user clicks a button inside a component, you might want to notify its parent component about that action.&lt;/p&gt;

&lt;p&gt;To do that, Angular allows us to define &lt;strong&gt;custom events&lt;/strong&gt; using the &lt;strong&gt;@Output decorator and EventEmitter&lt;/strong&gt; (old way) or the &lt;strong&gt;output()&lt;/strong&gt; function (new way).&lt;/p&gt;

&lt;p&gt;This enables you to create events that can be emitted and handled by parent components, similar to native DOM events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Old Way: Using @Output and EventEmitter
&lt;/h2&gt;

&lt;p&gt;The traditional approach is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You define an event using the &lt;strong&gt;@Output decorator&lt;/strong&gt; and an &lt;strong&gt;instance of EventEmitter&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You emit the event using &lt;strong&gt;.emit()&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  New Way: Using the output Function
&lt;/h2&gt;

&lt;p&gt;Now, Angular introduces a &lt;strong&gt;simplified syntax&lt;/strong&gt; to define custom events without needing &lt;strong&gt;EventEmitter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of using &lt;strong&gt;@Output() and EventEmitter&lt;/strong&gt;, you can use the &lt;strong&gt;output()&lt;/strong&gt; function directly.&lt;/p&gt;

&lt;p&gt;The newer approach &lt;strong&gt;eliminates&lt;/strong&gt; the need to explicitly instantiate an &lt;strong&gt;EventEmitter&lt;/strong&gt;, which simplifies code and reduces boilerplate.&lt;/p&gt;

&lt;p&gt;Even though the syntax is different, &lt;strong&gt;the behavior is exactly the same&lt;/strong&gt; as the old approach. You still emit events, pass data with them, and listen for them from the parent component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To create a custom event, you define a property in your component using the &lt;strong&gt;output function&lt;/strong&gt;, which returns an &lt;strong&gt;OutputEmitterRef&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, output } from '@angular/core';

@Component({
  selector: 'child-component',
  template: `&amp;lt;button (click)="sendData()"&amp;gt;Click Me&amp;lt;/button&amp;gt;`,
})
export class ChildComponent {
  dataSent = output&amp;lt;string&amp;gt;(); // No need to import EventEmitter

  sendData() {
    this.dataSent.emit('Hello, Parent!');
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the &lt;strong&gt;output function&lt;/strong&gt; does exactly what &lt;strong&gt;EventEmitter&lt;/strong&gt; did, but in a more compact form.&lt;/p&gt;

&lt;p&gt;Whether you’re using the old or new way, the way you listen for the event in the parent component is the same.&lt;/p&gt;

&lt;p&gt;In the parent component, you can listen for the &lt;strong&gt;dataSent&lt;/strong&gt; event using the regular event binding syntax &lt;strong&gt;(eventName)&lt;/strong&gt; and call a method when the event is triggered.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    &amp;lt;h1&amp;gt;Parent Component&amp;lt;/h1&amp;gt;
    &amp;lt;child-component (dataSent)="receiveData($event)"&amp;gt;&amp;lt;/child-component&amp;gt;
    &amp;lt;p&amp;gt;{{ receivedMessage }}&amp;lt;/p&amp;gt;
  `,
})
export class ParentComponent {
  receivedMessage: string = '';

  // Method to handle the received data from the child component
  receiveData(message: string) {
    this.receivedMessage = message; // Store the message received from the child
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Customizing Output Names
&lt;/h2&gt;

&lt;p&gt;You can specify a custom name for the event in the template using the alias option&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;changed = output({alias: 'valueChanged'});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;· The alias option only affects how the event is referenced in the template, not in TypeScript code.&lt;/p&gt;

&lt;p&gt;· In the TypeScript code, the original name of the output property is used (in this case, changed).&lt;/p&gt;

&lt;p&gt;· In the template, the alias name valueChanged is used to listen for the event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subscribing to Outputs Programmatically
&lt;/h2&gt;

&lt;p&gt;When dynamically creating components in Angular, you might want to listen for events emitted by the component, for example, when a button inside the dynamically created component is clicked.&lt;/p&gt;

&lt;p&gt;You can do this by subscribing to their output events programmatically using &lt;strong&gt;subscribe&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After creating the dynamic component in the parent component, we can subscribe to its event property to listen for it.&lt;/p&gt;

&lt;p&gt;When the event is emitted, the subscription in the parent component’s code will receive the emitted data and can take an action based on it, such as logging it to the console, updating the UI, or performing some other logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const componentRef = viewContainerRef.createComponent(SomeComponent);

// Subscribe to the dynamically created component's output event
componentRef.instance.someEventProperty.subscribe((eventData) =&amp;gt; {
  console.log(eventData); 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also unsubscribe manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const eventSubscription = componentRef.instance.someEventProperty.subscribe(eventData =&amp;gt; {
  console.log(eventData);
});

eventSubscription.unsubscribe();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Points about Custom Events
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom events do not bubble:&lt;/strong&gt; In native DOM events, when an event is triggered, it can propagate up from the target element to its ancestors, allowing parent elements to listen for events on child elements. However, custom events in Angular do not bubble.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Case sensitivity:&lt;/strong&gt; Output names are case-sensitive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inheritance:&lt;/strong&gt; When a component extends another, it inherits the outputs from the parent component. This means child component automatically inherits the output (custom event) from the parent and can listen to or trigger it without needing to redefine the event.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event names:&lt;/strong&gt; Choose event names carefully to avoid conflicts with native DOM event names like click, focus, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In conclusion, Angular provides two approaches for component communication through custom events: the traditional method using &lt;strong&gt;@Output() and EventEmitter&lt;/strong&gt;, and the newer, simpler &lt;strong&gt;output() function&lt;/strong&gt;. The newer approach &lt;strong&gt;eliminates the need for importing EventEmitter&lt;/strong&gt; and &lt;strong&gt;reduces boilerplate code, making the code more concise and easier to maintain.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Why you should use @use instead of @import in Angular Projects</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Tue, 02 Sep 2025 13:57:37 +0000</pubDate>
      <link>https://dev.to/bytebantz/why-you-should-use-use-instead-of-import-in-angular-projects-56kf</link>
      <guid>https://dev.to/bytebantz/why-you-should-use-use-instead-of-import-in-angular-projects-56kf</guid>
      <description>&lt;p&gt;Before the introduction of &lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;, developers used &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/import"&gt;@import&lt;/a&gt;&lt;/strong&gt; to bring styles from different files into one. However, &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/import"&gt;@import&lt;/a&gt;&lt;/strong&gt; had some issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It could &lt;strong&gt;import the same file multiple times&lt;/strong&gt;, leading to &lt;strong&gt;bloated&lt;/strong&gt; CSS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It &lt;strong&gt;pulled in everything&lt;/strong&gt; from the imported file, &lt;strong&gt;even unused styles&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It caused naming conflicts when multiple files had variables with the same name.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To fix these, Sass introduced &lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;, which:&lt;/p&gt;

&lt;p&gt;✔ &lt;strong&gt;Loads each file only once&lt;/strong&gt;.&lt;br&gt;
✔ &lt;strong&gt;Uses namespaces to avoid variable conflicts&lt;/strong&gt;.&lt;br&gt;
✔ Helps make CSS more optimized by &lt;strong&gt;importing only what’s needed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: @ import (Old way)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// colors.scss
$primary-color: blue;
$secondary-color: red;


// styles.scss
@import 'colors';

body {
  background-color: $primary-color;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; If &lt;strong&gt;colors.scss&lt;/strong&gt; is &lt;strong&gt;imported multiple times&lt;/strong&gt; across different files, it could cause &lt;strong&gt;duplication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: @ use (New way)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// colors.scss
$primary-color: blue;
$secondary-color: red;

// styles.scss
@use 'colors';

body {
  background-color: colors.$primary-color;  // Notice the namespace "colors."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why is this better?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;&lt;/strong&gt; statement &lt;strong&gt;ensures colors.scss is only loaded once&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Variables need to be prefixed&lt;/strong&gt; with the file name (colors.$primary-color), &lt;strong&gt;preventing conflicts&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Using &lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt; with an Alias&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of typing &lt;strong&gt;colors.$primary-color&lt;/strong&gt; every time, we can &lt;strong&gt;shorten&lt;/strong&gt; it using as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@use 'colors' as c;

body {
  background-color: c.$primary-color;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Shorter and more readable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt; in Angular Material&lt;/strong&gt;&lt;br&gt;
Angular Material switched to @ use for theming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Old way (&lt;a class="mentioned-user" href="https://dev.to/import"&gt;@import&lt;/a&gt;):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import '@angular/material';
$my-primary: mat-palette($mat-indigo);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;New way (&lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@use '@angular/material' as mat;
$my-primary: mat.define-palette(mat.$indigo-palette, 500);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understanding @forward rule in Sass
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;@ forward&lt;/strong&gt; rule in Sass works together with &lt;strong&gt;@ use&lt;/strong&gt; to organize and control access to styles.&lt;/p&gt;

&lt;p&gt;It allows you to re-export styles from one file to another while keeping some variables, mixins, or functions private.&lt;/p&gt;

&lt;p&gt;Before Sass introduced &lt;strong&gt;@ forward&lt;/strong&gt;, using &lt;strong&gt;@ import&lt;/strong&gt; meant that everything in a file was always accessible, leading to bloated styles and naming conflicts.&lt;/p&gt;

&lt;p&gt;If you want to explicitly control which variables get exposed, you can use &lt;strong&gt;@forward&lt;/strong&gt; with the show keyword.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Forwarding Only Some Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you only want to expose specific variables, use show:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;_colors.scss&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$primary-color: blue;
$secondary-color: red;
$private-color: black; // ❌ Should not be public

@forward 'colors' show $primary-color, $secondary-color;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;main.scss&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@use 'colors';

body {
  background-color: colors.$primary-color; // ✅ Works
  color: colors.$secondary-color;          // ✅ Works
  border: 1px solid colors.$private-color; // ❌ ERROR! Not exposed
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use &lt;strong&gt;@ forward&lt;/strong&gt; without &lt;strong&gt;show&lt;/strong&gt;, then all public variables, mixins, and functions from that module are &lt;strong&gt;automatically forwarded&lt;/strong&gt; and accessible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Forwarding Everything&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;_colors.scss&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$primary-color: blue;
$secondary-color: red;
$private-color: black; // This is still public unless restricted

@forward 'colors'; // ✅ Everything is forwarded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;main.scss&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@use 'colors';

body {
  background-color: colors.$primary-color; // ✅ Works
  color: colors.$secondary-color;          // ✅ Works
  border: 1px solid colors.$private-color; // ✅ Also works
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since &lt;strong&gt;@forward&lt;/strong&gt; is used without show, public variables, mixins, and functions from _colors.scss are available in main.scss&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In short, &lt;strong&gt;@ use&lt;/strong&gt; provides better performance, prevents conflicts, and ensures cleaner, more efficient stylesheets, making it the preferred choice for modern Sass development.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Angular Best Practices Every Developer Needs to Know</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Tue, 02 Sep 2025 11:29:20 +0000</pubDate>
      <link>https://dev.to/bytebantz/angular-best-practices-every-developer-needs-to-know-39k0</link>
      <guid>https://dev.to/bytebantz/angular-best-practices-every-developer-needs-to-know-39k0</guid>
      <description>&lt;p&gt;Writing clean, maintainable, and performant Angular applications requires following best practices that enhance readability, testability, and performance.&lt;/p&gt;

&lt;p&gt;Here are 6 key principles every Angular developer should follow:&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Avoiding logic in Angular templates
&lt;/h1&gt;

&lt;p&gt;Avoiding logic in Angular templates helps maintain cleaner, more maintainable code. Here’s why and how you should do it:&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Avoid Logic in Templates?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Performance Optimization&lt;/strong&gt; — Function calls in templates are executed repeatedly during change detection, which can impact performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Better Testability&lt;/strong&gt; — Moving logic to the component makes it easier to write unit tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Improved Maintainability&lt;/strong&gt; — Keeping business logic separate from the template reduces the risk of breaking functionality when modifying the UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Enhanced Readability&lt;/strong&gt; — Templates remain clean and focused on presentation rather than logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Extract Logic from Templates
&lt;/h2&gt;

&lt;p&gt;Instead of doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngIf="isUserLoggedIn()"&amp;gt;{{ getUserName() }}&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move the logic to the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class ExampleComponent {
  isLoggedIn = false;
  userName = '';

  constructor(private authService: AuthService) {
    this.isLoggedIn = this.authService.isAuthenticated();
    this.userName = this.authService.getUserName();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use it in the template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngIf="isLoggedIn"&amp;gt;{{ userName }}&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures the function isn’t re-evaluated unnecessarily and improves performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Using Aliases for Cleaner Imports
&lt;/h2&gt;

&lt;p&gt;In a deep folder structure, import paths can become long and messy.&lt;/p&gt;

&lt;p&gt;Using &lt;strong&gt;aliases&lt;/strong&gt; can help keep your import paths clean and manageable in such projects with deep folder structures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of bad imports:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MyComponent } from '../../../components/MyComponent';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This import path is &lt;strong&gt;long, hard to understand&lt;/strong&gt;, and &lt;strong&gt;can easily break&lt;/strong&gt; when files are moved around.&lt;/p&gt;

&lt;p&gt;Instead, &lt;strong&gt;aliases&lt;/strong&gt; allow you to define a short path to access files and components, &lt;strong&gt;improving clarity&lt;/strong&gt; and &lt;strong&gt;reducing the chances of errors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In Angular projects, &lt;strong&gt;aliases&lt;/strong&gt; are set up in the &lt;strong&gt;tsconfig.json&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;tsconfig.json&lt;/strong&gt; file, we will use the &lt;strong&gt;paths property&lt;/strong&gt; to define &lt;strong&gt;aliases&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"compilerOptions": {
  "baseUrl": "./",
  "paths": {
    "@app/*": ["src/app/*"],
    "@services/*": ["src/app/services/*"],
    "@components/*": ["src/app/components/*"]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you’ve set up your &lt;strong&gt;aliases&lt;/strong&gt;, you can use them in your &lt;strong&gt;imports&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MyComponent } from '@components/MyComponent';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of writing a long import path like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MyComponent } from '../../../components/MyComponent';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How Aliases Improve Your Workflow:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved Readability:&lt;/strong&gt; Aliases make it clear where your files are located. For instance, @components or &lt;a class="mentioned-user" href="https://dev.to/services"&gt;@services&lt;/a&gt; give a clear context of what’s being imported, making your codebase easier to navigate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refactoring Made Easy:&lt;/strong&gt; You can move files, folders, or entire sections of your application without worrying about breaking import paths throughout your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency:&lt;/strong&gt; With aliases, your import paths are consistent across the entire project, reducing the chance of errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Avoid Nested Subscriptions in RxJS
&lt;/h2&gt;

&lt;p&gt;When handling multiple streams of data (like user input, API requests, or events), a common mistake is subscribing inside another subscription.&lt;/p&gt;

&lt;p&gt;This leads to the following main problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Multiple ongoing requests →&lt;/strong&gt; If a new request starts before the previous one finishes, multiple requests run at the same time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Race conditions →&lt;/strong&gt; The responses don’t always come back in order, so old data can overwrite new data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory leaks →&lt;/strong&gt; Unnecessary active subscriptions can slow down the app and use extra memory.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead, we should use &lt;strong&gt;switchMap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;switchMap&lt;/strong&gt; makes sure that only &lt;strong&gt;the latest request is completed&lt;/strong&gt; and &lt;strong&gt;all previous requests are canceled&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How This Looks in Code (Nested Subscriptions)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pickupLocation$.subscribe(location =&amp;gt; {
  findDriver$(location).subscribe(driver =&amp;gt; {
    console.log(`Driver assigned: ${driver}`);
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you update your location multiple times, multiple driver searches run at the same time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The first request may return after the second, assigning the wrong driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Using switchMap (Cancels Old Requests)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pickupLocation$.pipe(
  switchMap(location =&amp;gt; findDriver$(location)) // Cancels old requests
).subscribe(driver =&amp;gt; {
  console.log(`Driver assigned: ${driver}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fixed Problems:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Only one active search at a time&lt;/strong&gt; (old requests are canceled).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Always get the correct driver for your latest request&lt;/strong&gt; (no outdated responses).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using switchMap ensures only the latest request matters, preventing outdated responses, unnecessary operations&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Breaking large components into smaller, reusable component
&lt;/h2&gt;

&lt;p&gt;As an Angular application grows, components tend to become large and difficult to maintain.&lt;/p&gt;

&lt;p&gt;A single component that handles multiple responsibilities is harder to debug, test, and manage.&lt;/p&gt;

&lt;p&gt;So, the idea is to &lt;strong&gt;split the large component into smaller ones&lt;/strong&gt; that follows the &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;, meaning each handle a specific task.&lt;/p&gt;

&lt;p&gt;This way, you can test, debug, and reuse each smaller component more easily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Transforming a Large Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s say we have a large Angular component that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Displays a list of items.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Filters items based on a search input.&lt;br&gt;
&lt;strong&gt;Before Splitting: The Large Component&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- main.component.html --&amp;gt;
&amp;lt;div&amp;gt;
  &amp;lt;input [(ngModel)]="searchTerm" placeholder="Search..." /&amp;gt;
  &amp;lt;div *ngFor="let item of filterItems(items, searchTerm)"&amp;gt;
    &amp;lt;h3&amp;gt;{{ item.title }}&amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;{{ item.description }}&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// main.component.ts
export class MainComponent {
  items = [
    { title: 'fist item', description: 'Description of Item 1' },
    { title: 'second item', description: 'Description of Item 2' },
    { title: 'third item', description: 'Description of Item 3' }
  ];
  searchTerm = '';

  filterItems(items: any[], term: string) {
    return items.filter((item) =&amp;gt; item.title.includes(term));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After Splitting: Smaller Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To make the component more reusable, we break it down into:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Search Bar Component&lt;/strong&gt; — Handles search input.&lt;br&gt;
&lt;strong&gt;2. Item List Component&lt;/strong&gt; — Displays a list of items.&lt;br&gt;
&lt;strong&gt;3. Item Component&lt;/strong&gt; — Displays a single item.&lt;br&gt;
&lt;strong&gt;4. Search Bar Component (search-bar.component.ts)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- search-bar.component.html --&amp;gt;
&amp;lt;input [(ngModel)]="searchTerm" (input)="search.emit(searchTerm)" placeholder="Search..." /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// search-bar.component.ts
import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-search-bar',
  templateUrl: './search-bar.component.html',
})
export class SearchBarComponent {
  @Output() search = new EventEmitter&amp;lt;string&amp;gt;();
  searchTerm: string = '';
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Item Component (item.component.ts)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- item.component.html --&amp;gt;
&amp;lt;h3&amp;gt;{{ item.title }}&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;{{ item.description }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// item.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-item',
  templateUrl: './item.component.html',
})
export class ItemComponent {
  @Input() item: any;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Item List Component (item-list.component.ts)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- item-list.component.html --&amp;gt;
&amp;lt;div *ngFor="let item of items"&amp;gt;
  &amp;lt;app-item [item]="item"&amp;gt;&amp;lt;/app-item&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// item-list.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-item-list',
  templateUrl: './item-list.component.html',
})
export class ItemListComponent {
  @Input() items: any[] = [];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Updated Main Component (main.component.ts)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- main.component.html --&amp;gt;
&amp;lt;app-search-bar (search)="searchTerm = $event"&amp;gt;&amp;lt;/app-search-bar&amp;gt;
&amp;lt;app-item-list [items]="filterItems(items, searchTerm)"&amp;gt;&amp;lt;/app-item-list&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// main.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
})
export class MainComponent {
  items = [
    { title: 'Item 1', description: 'Description of Item 1' },
    { title: 'Item 2', description: 'Description of Item 2' },
    { title: 'Item 3', description: 'Description of Item 3' }
  ];
  searchTerm = '';

  filterItems(items: any[], term: string) {
    return items.filter((item) =&amp;gt; item.title.includes(term));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Break Large Components?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- Easier to Debug &amp;amp; Maintain&lt;/strong&gt; — Smaller components mean fewer things can go wrong. If a bug appears, it’s easier to isolate and fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Better Code Organization&lt;/strong&gt; — Each component handles one task, making the project easier to navigate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Better Reusability&lt;/strong&gt; — Extracting common UI elements prevents duplicate code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Improved Readability&lt;/strong&gt; — Smaller files are easier to navigate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Faster Testing&lt;/strong&gt; — Unit testing becomes much simpler because each component has a single purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Documenting code
&lt;/h2&gt;

&lt;p&gt;Documenting code with comments is an excellent practice, because it improves code maintainability, readability, and collaboration, making it easier for new developers (or even yourself in the future) to understand the logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: Documenting a Method&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * This method converts a given age into a string.
 * It takes a number as input and returns the string version of it.
 * 
 * @param age The age value to be converted.
 * @returns A string representation of the age value.
 */
function getAge(age: number): string {
  return age.toString();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 2: Documenting a Variable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For class variables, documenting them can also be helpful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UserProfile {
  /**
   * The name of the user.
   * This is typically initialized when the user registers.
   * @example "John Doe"
   */
  userName: string;

  /**
   * The age of the user in years.
   * This is an optional field and may not be available for every user.
   * @example 28
   */
  userAge?: number;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Angular Example: Documenting a Service Method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Angular services, you can document methods as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable({
  providedIn: 'root'
})
export class UserService {
  /**
   * Fetches user data from the backend API.
   * It sends a GET request to retrieve the user's profile information.
   * 
   * @param userId The ID of the user whose data is to be fetched.
   * @returns An Observable of the user's data.
   */
  getUserData(userId: string): Observable&amp;lt;User&amp;gt; {
    return this.http.get&amp;lt;User&amp;gt;(`/api/users/${userId}`);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using clear, consistent commenting practices like this will make your code much more understandable.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Keep components lean by delegating complex logic to services.
&lt;/h2&gt;

&lt;p&gt;In Angular, components and templates serve distinct roles in the app architecture.&lt;/p&gt;

&lt;p&gt;The general rule is: components handle the logic, and templates handle the view. However, to avoid bloating your components with too much logic, it’s best to delegate business logic to services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Without a Service (Bad Practice)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here, the component is doing too much.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';

@Component({
  selector: 'app-products',
  template: `&amp;lt;div *ngFor="let product of products"&amp;gt;{{ product.name }}&amp;lt;/div&amp;gt;`,
})
export class ProductsComponent {
  products = [
    { id: 1, name: 'Jacket' },
    { id: 2, name: 'Sneakers' },
  ];

  filterProducts(search: string) {
    return this.products.filter(product =&amp;gt; product.name.includes(search));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The filtering logic should be handled by a service instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: With a Service (Good Practice)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Move the logic to a service and inject it into the component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create the Service&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class ProductService {
  private products = [
    { id: 1, name: 'Jacket' },
    { id: 2, name: 'Sneakers' },
  ];

  getProducts() {
    return this.products;
  }

  filterProducts(search: string) {
    return this.products.filter(product =&amp;gt; product.name.includes(search));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Use the Service in the Component&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { ProductService } from '../services/product.service';

@Component({
  selector: 'app-products',
  template: `&amp;lt;div *ngFor="let product of filteredProducts"&amp;gt;{{ product.name }}&amp;lt;/div&amp;gt;`,
})
export class ProductsComponent {
  filteredProducts = [];

  constructor(private productService: ProductService) {
    this.filteredProducts = this.productService.getProducts();
  }

  searchProducts(search: string) {
    this.filteredProducts = this.productService.filterProducts(search);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Delegate Logic to Services?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- Separation of Concerns&lt;/strong&gt; — The component handles UI, and the service handles logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Reusability&lt;/strong&gt; — ProductService can be used in multiple components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Testability&lt;/strong&gt; — We can test the service separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Maintainability&lt;/strong&gt; — Easier to modify or expand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By applying these best practices, your Angular applications will be more efficient, maintainable, and scalable.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Common Security Vulnerabilities in Angular Applications and How to Fix Them</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Wed, 26 Mar 2025 10:36:43 +0000</pubDate>
      <link>https://dev.to/bytebantz/common-security-vulnerabilities-in-angular-applications-and-how-to-fix-them-4055</link>
      <guid>https://dev.to/bytebantz/common-security-vulnerabilities-in-angular-applications-and-how-to-fix-them-4055</guid>
      <description>&lt;p&gt;In this article, we’ll explore common security issues in Angular applications, how attackers exploit them, and how to secure your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Cross-Site Scripting (XSS)
&lt;/h2&gt;

&lt;p&gt;XSS occurs when an application allows malicious scripts to execute in the browser.&lt;/p&gt;

&lt;p&gt;Angular sanitization is a built-in mechanisms that checks untrusted content and ensures it’s safe for the DOM.&lt;/p&gt;

&lt;p&gt;Angular cleans HTML by removing dangerous tags like &amp;lt;script&amp;gt;, blocks unsafe URLs (javascript: schemes), and prevents harmful CSS.&lt;/p&gt;

&lt;p&gt;Angular automatically sanitizes values bound [innerHTML], &amp;lt;a [href]&amp;gt;, &amp;lt;img [src]&amp;gt;, and [style] to protect your app.&lt;/p&gt;

&lt;p&gt;However, you can still introduce vulnerabilities if you &lt;strong&gt;intentionally bypass&lt;/strong&gt; security mechanisms or &lt;strong&gt;manipulate the DOM directly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here are some examples of vulnerable code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerability 1: Using bypassSecurityTrustHtml Unsafely&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;bypassSecurityTrustHtml&lt;/strong&gt; method forces Angular to trust the provided HTML, including unsafe content like &amp;lt;script&amp;gt; tags.&lt;/p&gt;

&lt;p&gt;Angular’s DomSanitizer can be misused to allow malicious scripts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable Code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Component({
  selector: 'app-inner-html-binding',
  template: `&amp;lt;div [innerHTML]="trustedHtmlSnippet"&amp;gt;&amp;lt;/div&amp;gt;`,
})
export class InnerHtmlBindingComponent {
  trustedHtmlSnippet: SafeHtml;

  constructor(private sanitizer: DomSanitizer) {
    const potentiallyUnsafe = 'Template &amp;lt;script&amp;gt;alert("0wned")&amp;lt;/script&amp;gt;';
    this.trustedHtmlSnippet = this.sanitizer.bypassSecurityTrustHtml(potentiallyUnsafe);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Safer Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of bypassing security, let Angular sanitize the HTML automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';

@Component({
  selector: 'app-inner-html-binding',
  template: `&amp;lt;div [innerHTML]="safeHtmlSnippet"&amp;gt;&amp;lt;/div&amp;gt;`,
})
export class InnerHtmlBindingComponent {
  safeHtmlSnippet = 'Template &amp;lt;script&amp;gt;alert("0wned")&amp;lt;/script&amp;gt;'; // Angular will sanitize this automatically
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Vulnerability 2: Directly Manipulating the DOM (ElementRef)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular’s built-in XSS protection &lt;strong&gt;only works in templates&lt;/strong&gt;, but &lt;strong&gt;direct DOM manipulation bypasses it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Using ElementRef and innerHTML allows unsafe content insertion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable Code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, ElementRef, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  imports: [FormsModule],
  template: `
    &amp;lt;input [(ngModel)]="comment" placeholder="Enter your comment"&amp;gt;
    &amp;lt;button (click)="postComment()"&amp;gt;Post Comment&amp;lt;/button&amp;gt;
    &amp;lt;div #commentBox&amp;gt;&amp;lt;/div&amp;gt;
  `,
})
export class AppComponent {
  @ViewChild('commentBox', { static: true }) commentBox!: ElementRef;
  comment: string = '';

  postComment() {
    this.commentBox.nativeElement.innerHTML = this.comment; // ⚠ Vulnerable to XSS!
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, modern browsers &lt;strong&gt;block&lt;/strong&gt; scripts inserted via innerHTML (they won't execute &amp;lt;script&amp;gt; tags).&lt;/p&gt;

&lt;p&gt;However, attackers can still exploit XSS &lt;strong&gt;without&lt;/strong&gt; using &amp;lt;script&amp;gt; tags by injecting &lt;strong&gt;malicious event handlers&lt;/strong&gt; like &lt;strong&gt;onerror&lt;/strong&gt;, &lt;strong&gt;onclick&lt;/strong&gt;, or &lt;strong&gt;onmouseover&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="x" onerror="alert('Hacked!')"&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the app is &lt;strong&gt;directly inserting user input into the DOM&lt;/strong&gt;, if a user submits the comment above, the &amp;lt;img&amp;gt; tag loads, fails (because src="x" is invalid), and &lt;strong&gt;triggers the onerror JavaScript&lt;/strong&gt;, showing an alert box. This is a &lt;strong&gt;Cross-Site Scripting (XSS) attack&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix: Use Angular’s Sanitization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To avoid XSS, use [innerHTML] instead of ElementRef.innerHTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  imports: [FormsModule],
  template: `
    &amp;lt;input [(ngModel)]="comment" placeholder="Enter your comment"&amp;gt;
    &amp;lt;button (click)="postComment()"&amp;gt;Post Comment&amp;lt;/button&amp;gt;
    &amp;lt;div [innerHTML]="safeComment"&amp;gt;&amp;lt;/div&amp;gt;
  `,
})
export class AppComponent {
  comment: string = '';
  safeComment: string = '';

  postComment() {
    this.safeComment = this.comment; // Angular sanitizes input automatically
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Clickjacking
&lt;/h2&gt;

&lt;p&gt;Clickjacking is when someone tricks you into clicking on something different from what you think you're clicking on.&lt;/p&gt;

&lt;p&gt;For example, they might overlay a malicious button on top of a legitimate one, so when you click, you're actually interacting with something you didn't intend to.&lt;/p&gt;

&lt;p&gt;Attackers can embed your Angular app inside an &amp;lt;iframe&amp;gt; and overlay a fake UI to steal user inputs.&lt;/p&gt;

&lt;p&gt;To check if your website can be embedded in an &amp;lt;iframe&amp;gt;, create an &lt;strong&gt;HTML file&lt;/strong&gt; (e.g., clickjack-test.html) and add this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;iframe src="https://your-angular-app.com" width="800" height="600"&amp;gt;&amp;lt;/iframe&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example of Clickjacking in Action:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Fake Job Ad&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A scammer creates a webpage claiming:
&lt;em&gt;"Earn $500 per day! Click below to apply!"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;This &lt;strong&gt;fake ad&lt;/strong&gt; targets people searching for jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. The Clickjacking Trick&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The fake page &lt;strong&gt;loads a real job posting inside an invisible iframe&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;hidden "Like" or "Follow" button&lt;/strong&gt; is &lt;strong&gt;placed over the real "Apply Now" button&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;When the user clicks "Apply Now," they actually &lt;strong&gt;like or follow a scam page&lt;/strong&gt; instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. The Redirection to Avoid Suspicion&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the &lt;strong&gt;hidden click happens&lt;/strong&gt;, the user is &lt;strong&gt;redirected to the real job listing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The victim &lt;strong&gt;sees a legitimate job post&lt;/strong&gt;, making them think everything is normal.&lt;/li&gt;
&lt;li&gt;They never realize they just followed a scam page!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Scammers Use Clickjacking:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They collect thousands of likes or follows for credibility.&lt;/li&gt;
&lt;li&gt;They post fake job offers to lure victims.&lt;/li&gt;
&lt;li&gt;Users click on scam links, thinking they are real opportunities.&lt;/li&gt;
&lt;li&gt;Some are tricked into paying fake "registration fees."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Secure Fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular does not have a specific built-in mechanism solely dedicated to preventing clickjacking out of the box.&lt;/p&gt;

&lt;p&gt;Set X-Frame-Options and Content-Security-Policy headers in the &lt;strong&gt;backend&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents clickjacking by blocking the site from being embedded in iframes.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Cross-Site Request Forgery (CSRF)
&lt;/h2&gt;

&lt;p&gt;CSRF is an attack where a malicious website tricks a user's browser into sending unintended requests to a different website where the user is authenticated.&lt;/p&gt;

&lt;p&gt;CSRF attacks are possible because web browsers automatically include cookies, including session cookies that contain authentication information, in every request&lt;/p&gt;

&lt;p&gt;If the server does not &lt;strong&gt;validate the request properly&lt;/strong&gt; (e.g., &lt;strong&gt;checking for an anti-CSRF token&lt;/strong&gt; or &lt;strong&gt;validating the Origin header&lt;/strong&gt;), an attacker can still trick a logged-in user into making unintended changes.&lt;/p&gt;

&lt;p&gt;Imagine you have an account on &lt;strong&gt;FastPizza&lt;/strong&gt; (&lt;a href="https://fastpizza.com" rel="noopener noreferrer"&gt;https://fastpizza.com&lt;/a&gt;), where you order food regularly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works Normally:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You log in and go to &lt;strong&gt;Settings → Change Email&lt;/strong&gt;, where you enter a new email.&lt;br&gt;&lt;br&gt;
The website sends this request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST https://fastpizza.com/update-email
Content-Type: application/x-www-form-urlencoded

email=mynewemail@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Attack (CSRF Exploit)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You are already logged into &lt;strong&gt;FastPizza&lt;/strong&gt; in one tab.&lt;br&gt;&lt;br&gt;
You then visit a &lt;strong&gt;malicious website&lt;/strong&gt;, maybe a recipe blog or a free giveaway site.&lt;/p&gt;

&lt;p&gt;The hacker &lt;strong&gt;creates this hidden form&lt;/strong&gt; into the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form action="https://fastpizza.com/update-email" method="POST"&amp;gt;
    &amp;lt;input type="hidden" name="email" value="hacker@example.com"&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;script&amp;gt;
    document.forms[0].submit(); // Automatically submits the form when the victim visits
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If the victim is &lt;strong&gt;logged in&lt;/strong&gt;, their session cookie is sent automatically.&lt;/li&gt;
&lt;li&gt;The server processes the request and updates the email without any additional verification.&lt;/li&gt;
&lt;li&gt;Now, the attacker's email is linked to the victim’s account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Secure Fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;CSRF tokens&lt;/strong&gt; in HTTP requests:&lt;/p&gt;

&lt;p&gt;Angular's HttpClient helps prevent these attacks using a &lt;strong&gt;token system&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The backend server &lt;strong&gt;creates a special security token&lt;/strong&gt; (usually named XSRF-TOKEN) and stores it in a &lt;strong&gt;cookie&lt;/strong&gt; when the user loads the page.&lt;/li&gt;
&lt;li&gt;Angular &lt;strong&gt;automatically reads&lt;/strong&gt; this token and includes it in the request headers under X-XSRF-TOKEN.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If it’s &lt;strong&gt;not working automatically&lt;/strong&gt;, create an &lt;strong&gt;Interceptor&lt;/strong&gt; to manually extract the token.&lt;/p&gt;

&lt;p&gt;3.The backend &lt;strong&gt;checks if the request contains a valid token&lt;/strong&gt; before allowing it to change data.&lt;/p&gt;

&lt;p&gt;If your backend &lt;strong&gt;uses different token names&lt;/strong&gt;, you can configure Angular to use them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provideHttpClient(
  withXsrfConfiguration({
    cookieName: 'CUSTOM_XSRF_TOKEN',
    headerName: 'X-Custom-Xsrf-Header',
  }),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. DOM Clobbering
&lt;/h2&gt;

&lt;p&gt;DOM Clobbering is an attack where an attacker manipulates the &lt;strong&gt;DOM properties&lt;/strong&gt; to override JavaScript variables or elements, causing unintended behavior.&lt;/p&gt;

&lt;p&gt;Imagine a user is trying to &lt;strong&gt;update their password&lt;/strong&gt; on a website. If the frontend is vulnerable to &lt;strong&gt;DOM Clobbering&lt;/strong&gt;, an attacker can &lt;strong&gt;inject their own password&lt;/strong&gt;, causing the victim’s password to be changed to one controlled by the attacker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable Code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form id="updatePasswordForm"&amp;gt;
  &amp;lt;input type="password" name="newPassword" placeholder="Enter new password" /&amp;gt;
  &amp;lt;input type="password" name="confirmPassword" placeholder="Confirm new password" /&amp;gt;
  &amp;lt;button type="submit"&amp;gt;Update Password&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;

&amp;lt;script&amp;gt;
  const newPasswordInput = document.querySelector('input[name="newPassword"]');

  document.getElementById('updatePasswordForm').addEventListener('submit', function(event) {
    event.preventDefault();
    console.log('Updating password to:', newPasswordInput.value);
  });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Malicious Injection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An attacker injects the following malicious hidden input field into the page:&lt;/p&gt;

&lt;p&gt;Since &lt;strong&gt;JavaScript automatically associates elements with global variables&lt;/strong&gt;, document.getElementById('newPassword') &lt;strong&gt;now points to the hidden field instead of the real input&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of their chosen password, "hackedPassword123" is sent to the server.&lt;/p&gt;

&lt;p&gt;The attacker can now log in using the victim’s account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secure Fix Using Angular Reactive Forms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To prevent this attack, avoid querySelector() and use &lt;strong&gt;Angular’s Form Controls&lt;/strong&gt; to securely reference inputs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    &amp;lt;form [formGroup]="passwordForm" (ngSubmit)="onSubmit()"&amp;gt;
      &amp;lt;input type="password" formControlName="newPassword" placeholder="Enter new password"&amp;gt;
      &amp;lt;input type="password" formControlName="confirmPassword" placeholder="Confirm new password"&amp;gt;
      &amp;lt;button type="submit"&amp;gt;Update Password&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  `,
})
export class AppComponent {
  passwordForm = new FormGroup({
    newPassword: new FormControl('', [Validators.required]),
    confirmPassword: new FormControl('', [Validators.required])
  });

  onSubmit() {
    console.log('Updating password to:', this.passwordForm.get('newPassword')?.value);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By understanding these vulnerabilities and implementing Angular’s built-in security mechanisms and recommended practices, developers can significantly enhance the security posture of their applications.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Design Patterns Every Angular Developer Should Know</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 24 Mar 2025 17:25:13 +0000</pubDate>
      <link>https://dev.to/bytebantz/design-patterns-every-angular-developer-should-know-4llf</link>
      <guid>https://dev.to/bytebantz/design-patterns-every-angular-developer-should-know-4llf</guid>
      <description>&lt;p&gt;New developers might not consider how the code will handle future changes or how easily it can be reused, expanded, or maintained. In the worst-case scenario, developers might even need to completely rebuild the project from scratch when things become too hard to fix. To avoid these issues, &lt;strong&gt;design patterns&lt;/strong&gt; were created.&lt;/p&gt;

&lt;p&gt;Design patterns are like blueprints that make your code easier to manage and change over time.&lt;/p&gt;

&lt;p&gt;Design patterns are tried-and-tested solutions for common design issues in software development. Instead of giving a full solution, they act as best practices for solving common software design challenges.&lt;/p&gt;

&lt;p&gt;Design patterns in Angular help you write cleaner, more organized code that makes your app easier to build, grow, and fix over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Design Patterns are important
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Scalability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design Patterns help break your app into small, reusable pieces. This makes it easy to add new features later without messing up existing ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Maintainability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Following design patterns ensures your code has a clear, organized structure.&lt;/p&gt;

&lt;p&gt;For example using patterns like the &lt;strong&gt;Singleton Pattern&lt;/strong&gt; makes the app more maintainable because you only have to change one piece of code in the service, and all the components that depend on it will automatically adapt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Testability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design patterns promotes the separation of concerns which makes it easier to mock and test components&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Code Reusability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Patterns encourage writing reusable code.&lt;/p&gt;

&lt;p&gt;For example, patterns like &lt;strong&gt;Factory&lt;/strong&gt; and &lt;strong&gt;Singleton&lt;/strong&gt; help you organize similar tasks in one place, so you can easily reuse them without rewriting the same logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Singleton Pattern
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Singleton Pattern&lt;/strong&gt; ensures that a class only has &lt;strong&gt;one instance&lt;/strong&gt; and allows that instance to be &lt;strong&gt;shared&lt;/strong&gt; globally.&lt;/p&gt;

&lt;p&gt;In Angular, this is often used for &lt;strong&gt;services&lt;/strong&gt;, making sure only one instance of a service is used throughout the app.&lt;/p&gt;

&lt;p&gt;A service becomes a singleton when it's provided at the &lt;strong&gt;root level&lt;/strong&gt;. To do this, you use the &lt;strong&gt;providedIn: 'root'&lt;/strong&gt; setting in the service’s metadata.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root' // This makes the service a singleton
})
export class MyService {
  constructor() { }

  // Your service methods here
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Facade Pattern
&lt;/h2&gt;

&lt;p&gt;The Facade Pattern offers a &lt;strong&gt;simplified interface&lt;/strong&gt; to interact with complex subsystems.&lt;/p&gt;

&lt;p&gt;When you don’t use the &lt;strong&gt;Facade Pattern,&lt;/strong&gt; components directly communicate with multiple services to handle different operations. This increases complexity as multiple components may replicate the same logic, leading to code duplication.&lt;/p&gt;

&lt;p&gt;With the &lt;strong&gt;Facade Pattern&lt;/strong&gt; instead of components calling multiple services, they interact with the facade. This makes the components leaner and easier to maintain, while business logic remains in one centralized place (the facade)&lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable({
  providedIn: 'root',
})
export class CartFacade {
  constructor(private cartService: CartService, private orderService: OrderService) {}

  // Add product to cart
  addToCart(product: Product) {
    this.cartService.addItem(product);
  }

  // Remove product from cart
  removeFromCart(product: Product) {
    this.cartService.removeItem(product);
  }

  // Process checkout using the current cart
  checkout() {
    const cart = this.cartService.getCart();
    this.orderService.processOrder(cart);
  }

  // Get the current items in the cart
  getCartItems() {
    return this.cartService.getCart();
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use the &lt;strong&gt;Facade Pattern&lt;/strong&gt; in your Angular components, you simply &lt;strong&gt;inject the facade service&lt;/strong&gt; into the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(private cartFacade: CartFacade) {}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Factory Pattern
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Factory Pattern&lt;/strong&gt; is a way of creating objects without specifying the exact class of the object that will be created.&lt;/p&gt;

&lt;p&gt;It handles the object creation process and conceals the details of how instances are instantiated.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Factory Pattern&lt;/strong&gt; can create objects dynamically, which is useful of you don’t know in advance the exact objects/services your application will need at runtime&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;Let's say you want to create different types of user notifications (e.g., &lt;strong&gt;email&lt;/strong&gt;, &lt;strong&gt;SMS&lt;/strong&gt;). You can implement the &lt;strong&gt;Factory Pattern&lt;/strong&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/app/notification.interface.ts // src/app/notification.interface.ts
export interface Notification {
  send(message: string): void;
}

// src/app/notification.service.ts
import { Injectable } from '@angular/core';
import { Notification } from './notification.interface';

@Injectable({
  providedIn: 'root',
})
export class EmailNotification implements Notification {
  send(message: string): void {
    console.log(`Email: ${message}`);
  }
}

@Injectable({
  providedIn: 'root',
})
export class SmsNotification implements Notification {
  send(message: string): void {
    console.log(`SMS: ${message}`);
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s create a &lt;strong&gt;factory&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/app/notification.factory.ts
import { Injectable } from '@angular/core';
import { EmailNotification } from './notification.service';
import { SmsNotification } from './notification.service';
import { Notification } from './notification.interface';

@Injectable({
  providedIn: 'root',
})
export class NotificationFactory {
  constructor(
    private emailNotification: EmailNotification,
    private smsNotification: SmsNotification
  ) {}

  createNotification(type: string): Notification {
    if (type === 'email') {
      return this.emailNotification;
    } else if (type === 'sms') {
      return this.smsNotification;
    } else {
      throw new Error('Unknown notification type');
    }
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in your component, you can use the &lt;strong&gt;factory&lt;/strong&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/app/notification/notification.component.ts
import { Component } from '@angular/core';
import { NotificationFactory } from '../notification.factory';
import { Notification } from '../notification.interface';

@Component({
  selector: 'app-notification',
  template: `
    &amp;lt;h1&amp;gt;Send Notification&amp;lt;/h1&amp;gt;
    &amp;lt;button (click)="send('email')"&amp;gt;Send Email&amp;lt;/button&amp;gt;
    &amp;lt;button (click)="send('sms')"&amp;gt;Send SMS&amp;lt;/button&amp;gt;
  `,
})
export class NotificationComponent {
  constructor(private notificationFactory: NotificationFactory) {}

  send(type: string) {
    const notification: Notification = this.notificationFactory.createNotification(type);
    notification.send(`This is a ${type} notification!`);
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Strategy Pattern
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Strategy Pattern&lt;/strong&gt; deals with behaviors (algorithms) and how they are used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strategy patterns&lt;/strong&gt; are useful when you need to switch between different algorithms or functionalities based on the context.&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;This service will dynamically select the payment method based on the user’s choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable({
  providedIn: 'root',
})
export class PaymentService {
  constructor(private paypalPayment: PayPalPayment, private creditCardPayment: CreditCardPayment) {}

  processPayment(method: 'paypal' | 'creditcard', amount: number): string {
    if (method === 'paypal') {
      return this.paypalPayment.processPayment(amount);
    } else {
      return this.creditCardPayment.processPayment(amount);
    }
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Design patterns provide crucial benefits in terms of scalability, maintainability, testability, and code reusability. In Angular, using patterns like Singleton, Facade, Factory, and Strategy will help you build applications that are easier to manage and expand. These patterns are essential for any large or growing application where clean, organized, and maintainable code is a priority.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Understanding :host and :host-context in Angular Styling</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 24 Mar 2025 12:37:39 +0000</pubDate>
      <link>https://dev.to/bytebantz/understanding-host-and-host-context-in-angular-styling-2b9n</link>
      <guid>https://dev.to/bytebantz/understanding-host-and-host-context-in-angular-styling-2b9n</guid>
      <description>&lt;p&gt;When styling Angular components, you can’t simply target them using standard CSS selectors like you would with regular HTML elements. Instead, Angular provides special selectors like &lt;strong&gt;:host&lt;/strong&gt; and &lt;strong&gt;:host-context&lt;/strong&gt; to help style components effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is :host?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;:host&lt;/strong&gt; selector is a special CSS rule in Angular that allows you to apply styles to the &lt;strong&gt;root element&lt;/strong&gt; of a component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do we need it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Normally, in CSS, you can target elements directly. But in Angular, components are custom elements, and you &lt;strong&gt;cannot&lt;/strong&gt; style them the usual way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s say we are building a &lt;strong&gt;User Profile Card&lt;/strong&gt; component in Angular.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;app-user-card&amp;gt;
    &amp;lt;img src="profile.jpg" alt="User Photo"&amp;gt;
    &amp;lt;h3&amp;gt;John Doe&amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;Web Developer&amp;lt;/p&amp;gt;
&amp;lt;/app-user-card&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we try to add a border to this &lt;em&gt;app-user-card&lt;/em&gt; in the component's CSS file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app-user-card {
    border: 2px solid black;
    padding: 10px;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 This will &lt;strong&gt;not work&lt;/strong&gt; because &lt;em&gt;app-user-card&lt;/em&gt; is an Angular component and not a standard HTML element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: Use :host&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can use &lt;strong&gt;:host&lt;/strong&gt; to target the root element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:host {
  display: block;
  border: 2px solid black;
  border-radius: 0.375em;
  background-color: #eee;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Now, the styles apply to the root element of the&lt;/strong&gt; &lt;em&gt;app-user-card&lt;/em&gt; &lt;strong&gt;component.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditional Styling Using :host(.class-name)
&lt;/h2&gt;

&lt;p&gt;Sometimes, you only want to apply styles when the component has a certain class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine we want to highlight &lt;strong&gt;premium users&lt;/strong&gt; with a golden border.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;app-user-card class="premium"&amp;gt;
    &amp;lt;img src="profile.jpg" alt="User Photo"&amp;gt;
    &amp;lt;h3&amp;gt;Jane Smith&amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;Premium Member&amp;lt;/p&amp;gt;
&amp;lt;/app-user-card&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in our component's CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:host(.premium) {
    display: block;
    border: 2px solid gold;
    border-radius: 0.375em;
    background-color: #eee;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Now, these styles apply only when the premium class is present on&lt;/strong&gt; &lt;em&gt;app-user-card&lt;/em&gt;&lt;strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt; If we remove the &lt;strong&gt;class="premium",&lt;/strong&gt; the styles won’t apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is :host-context?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;:host-context&lt;/strong&gt; selector allows us to apply styles &lt;strong&gt;based on where the component is used&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;:host-context(selector)&lt;/strong&gt; applies styles only when the component is inside an element matching the given selector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using :host-context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine your site has a &lt;strong&gt;Dark Mode&lt;/strong&gt; &lt;strong&gt;feature&lt;/strong&gt;. You want all &lt;strong&gt;User Profile Cards&lt;/strong&gt; to look different when inside a &lt;strong&gt;&lt;em&gt;dark-mode&lt;/em&gt;&lt;/strong&gt; container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="dark-mode"&amp;gt;
    &amp;lt;app-user-card&amp;gt;
        &amp;lt;img src="profile.jpg" alt="User Photo"&amp;gt;
        &amp;lt;h3&amp;gt;Sarah Connor&amp;lt;/h3&amp;gt;
        &amp;lt;p&amp;gt;Graphic Designer&amp;lt;/p&amp;gt;
    &amp;lt;/app-user-card&amp;gt;
&amp;lt;/div&amp;gt;

:host-context(.dark-mode) {
    display: block;
    border: 2px solid gray;
    border-radius: 0.375em;
    background-color: #333;
    color: white;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Now, if app-user-card is inside .dark-mode, it automatically changes to dark mode!&lt;/strong&gt; 🌙&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem with :host-context()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While &lt;strong&gt;:host-context&lt;/strong&gt;() is useful, it can cause &lt;strong&gt;tight coupling&lt;/strong&gt; between components and global styles.&lt;/p&gt;

&lt;p&gt;If you rename &lt;strong&gt;.dark-mode&lt;/strong&gt; to &lt;strong&gt;.theme-dark&lt;/strong&gt;, you must update &lt;strong&gt;every&lt;/strong&gt; component using &lt;strong&gt;:host-context(.dark-mode).&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Better Alternative: Use CSS Variables Instead of &lt;strong&gt;:&lt;/strong&gt;host-context()
&lt;/h2&gt;

&lt;p&gt;Instead of &lt;strong&gt;:host-context(),&lt;/strong&gt; we can use &lt;strong&gt;CSS variables&lt;/strong&gt; that change based on a global class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS variables&lt;/strong&gt; are a powerful way to &lt;strong&gt;manage&lt;/strong&gt; and &lt;strong&gt;centralize&lt;/strong&gt; styling properties in CSS.&lt;/p&gt;

&lt;p&gt;Here's how they work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Step 1: Define Global Theme Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CSS variables are defined with a &lt;strong&gt;-- prefix&lt;/strong&gt; followed by &lt;strong&gt;a&lt;/strong&gt; &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;a&lt;/strong&gt; &lt;strong&gt;value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;:root&lt;/strong&gt; pseudo-class is commonly used to &lt;strong&gt;define these variables globally&lt;/strong&gt;, making them accessible &lt;strong&gt;throughout&lt;/strong&gt; the application.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* styles.css */
:root {
  --bg-color: white;
  --text-color: black;
}

.dark-mode {
  --bg-color: black;
  --text-color: white;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;✅ Step 2: Apply Variables in Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To use a CSS variable, you use the &lt;strong&gt;var()&lt;/strong&gt; function, passing the variable name as an argument.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:host {
  background-color: var(--bg-color);
  color: var(--text-color);
  display: block;
  border: 2px solid gray;
  border-radius: 0.375em;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, components will &lt;strong&gt;automatically adjust&lt;/strong&gt; without relying on &lt;strong&gt;:host-context().&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to explore more?
&lt;/h2&gt;

&lt;p&gt;Check out my &lt;strong&gt;&lt;a href="https://bytebantz.gumroad.com/l/kufka" rel="noopener noreferrer"&gt;deep dive on Angular styling techniques&lt;/a&gt;&lt;/strong&gt; on Gumroad for additional insights and best practices! → &lt;a href="https://bytebantz.gumroad.com" rel="noopener noreferrer"&gt;https://bytebantz.gumroad.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>softwaredevelopment</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Your Data, Your Privacy: How VPNs Hide Your Identity</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Sat, 28 Dec 2024 10:25:05 +0000</pubDate>
      <link>https://dev.to/bytebantz/your-data-your-privacy-how-vpns-hide-your-identity-4b08</link>
      <guid>https://dev.to/bytebantz/your-data-your-privacy-how-vpns-hide-your-identity-4b08</guid>
      <description>&lt;h2&gt;
  
  
  What is a VPN?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;VPN&lt;/strong&gt; (Virtual Private Network) is a service that encrypts your internet connection and routes it through a secure server, masking your real IP address. By doing so, it ensures that your online activities remain private and your data is secure, even on public networks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use a VPN?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Enhanced Privacy&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Without a &lt;strong&gt;VPN&lt;/strong&gt;, websites, &lt;strong&gt;ISPs&lt;/strong&gt; (Internet Service Providers), and other entities can track your IP address, browsing habits, and location. A &lt;strong&gt;VPN&lt;/strong&gt; hides this information, giving you greater anonymity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Security on Public Wi-Fi&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Public Wi-Fi networks are hotspots for cybercriminals. A &lt;strong&gt;VPN&lt;/strong&gt; encrypts your connection, safeguarding your data from prying eyes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Bypassing Geo-Restrictions&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;VPNs&lt;/strong&gt; allow you to access content unavailable in your country by routing your connection through servers in different regions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Preventing ISP Throttling&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Some &lt;strong&gt;ISPs&lt;/strong&gt; monitor your online activities and slow down your connection based on usage. A &lt;strong&gt;VPN&lt;/strong&gt; encrypts your traffic, preventing ISPs from selectively throttling your speeds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Online Banking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some banks block access from foreign IP addresses to prevent fraud. A &lt;strong&gt;VPN&lt;/strong&gt; allows you to appear as if you're accessing the internet from your home country by routing your connection through a &lt;strong&gt;VPN&lt;/strong&gt; server in your home country.&lt;/p&gt;

&lt;p&gt;To grasp how &lt;strong&gt;VPNs&lt;/strong&gt; work, it's helpful to understand some fundamental networking concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Network Interface Card (NIC):&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The &lt;strong&gt;NIC&lt;/strong&gt; is the hardware in your computer or device that enables network connectivity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wired NICs&lt;/strong&gt; use Ethernet cables to connect directly to a network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wireless NICs&lt;/strong&gt; connect to Wi-Fi networks without cables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without a &lt;strong&gt;NIC&lt;/strong&gt;, your device cannot access the internet, making it a critical component for &lt;strong&gt;VPN&lt;/strong&gt; functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Network Address Translation (NAT):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NAT&lt;/strong&gt; (Network Address Translation) is a method used by routers to map multiple private IP addresses to a single public IP address (or a few public IPs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NAT&lt;/strong&gt; allows multiple devices on a private network to share a single public IP address, effectively managing limited public IP resources.&lt;/p&gt;

&lt;p&gt;Without &lt;strong&gt;NAT&lt;/strong&gt;, every device would need its own public IP address. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a single household had 10 devices, it would need 10 public IPs.&lt;/li&gt;
&lt;li&gt;Multiply that by millions of households worldwide, and the demand for public IPs would far exceed supply.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NAT&lt;/strong&gt; solves this problem by letting networks use private IPs internally and translating them to one or a few public IPs for external communication. This significantly reduces the number of public IPs required globally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The Setup&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    Imagine you have a home network with 3 devices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Device A: Private IP 192.168.1.2&lt;/li&gt;
&lt;li&gt;Device B: Private IP 192.168.1.3&lt;/li&gt;
&lt;li&gt;Device C: Private IP 192.168.1.4
These private IPs are not unique and cannot be used on the internet. Instead, your Internet Service Provider (ISP) gives you &lt;strong&gt;one public IP&lt;/strong&gt;: 203.0.113.1.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Device Wants to Access the Internet&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    Suppose Device A wants to visit example.com (IP 93.184.216.34). It sends a request to the router with its private IP address:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source IP (Private)&lt;/strong&gt;: 192.168.1.2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination IP (Public)&lt;/strong&gt;: 93.184.216.34.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. The Router Translates&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    The router receives the request and does two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Replaces the private IP (192.168.1.2) with the public IP (203.0.113.1)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Records the translation in a table&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Private IP  | Port    | Public IP       | Port
192.168.1.2 | 12345   | 203.0.113.1     | 54321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, 12345 is the source port assigned by Device A, and 54321 is a new port the router assigns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The Request Goes to the Internet&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    Now, the request sent to example.com looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source IP (Public)&lt;/strong&gt;: 203.0.113.1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source Port&lt;/strong&gt;: 54321&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination IP (Public)&lt;/strong&gt;: 93.184.216.34.
This makes it seem like the request is coming from the public IP, not Device A.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Response Comes Back&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    The website example.com sends a response back to your public IP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source IP&lt;/strong&gt;: 93.184.216.34&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination IP (Public)&lt;/strong&gt;: 203.0.113.1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination Port&lt;/strong&gt;: 54321.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Router Translates Back&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    The router checks its NAT table to match the public IP and port (203.0.113.1:54321) to the corresponding private IP and port (192.168.1.2:12345). It then forwards the response to Device A.&lt;br&gt;
&lt;strong&gt;7. Device A Gets the Data&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    Device A receives the response, and the process is complete!&lt;/p&gt;

&lt;p&gt;VPNs add a layer of privacy to this setup by replacing your public IP with that of the VPN server, preventing websites and other entities from tracking your location and activities.&lt;/p&gt;

&lt;h2&gt;
  
  
  How a VPN works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Establishing a Secure Tunnel&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you enable a &lt;strong&gt;VPN&lt;/strong&gt;, it creates a secure and encrypted connection (a "tunnel") between your device and a &lt;strong&gt;VPN server&lt;/strong&gt; located elsewhere.&lt;/li&gt;
&lt;li&gt;Encryption ensures that any data traveling through this tunnel is scrambled and cannot be intercepted or read by unauthorized parties.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Sending Your Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All your internet traffic (like requests to visit websites) is routed through this secure tunnel to the &lt;strong&gt;VPN server&lt;/strong&gt; instead of going directly to the internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Decryption at the VPN Server&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The VPN server receives your encrypted data.&lt;/li&gt;
&lt;li&gt;It decrypts the data to understand your request (e.g., visiting a specific website).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Hiding Your IP Address&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The VPN server forwards your request to the website you're trying to access.&lt;/li&gt;
&lt;li&gt;The website does not see your actual IP address (your location). Instead, it sees the IP address of the VPN server, effectively hiding your real location.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Receiving the Website’s Response&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The website processes your request and sends the response (e.g., loading a webpage) back to the VPN server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Encrypting the Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The VPN server encrypts the website's response and sends it back through the secure tunnel to your device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Decrypting and Displaying Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your device receives the encrypted data from the VPN server.&lt;/li&gt;
&lt;li&gt;It decrypts the data, making it readable, and displays the content you requested (e.g., the webpage).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, some &lt;strong&gt;VPNs&lt;/strong&gt; may slow down your internet connection due to the extra step of routing traffic through a remote server. It's important to choose a &lt;strong&gt;VPN&lt;/strong&gt; that offers high-speed servers, especially if you plan on streaming or gaming.&lt;/p&gt;

&lt;p&gt;Some free VPNs may track and sell user data to advertisers, defeating the purpose of using a VPN in the first place. Always use a reputable paid service with no-logs policy, but remember that expensive doesn't necessarily equate to higher quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended Affiliate VPN Providers
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Surfshark&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why Choose Surfshark?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No-logs policy&lt;/strong&gt;: Surfshark's no-logs policy means that your online activities are never tracked or stored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Servers&lt;/strong&gt;: Surfshark has over 3,200 servers, and its 100% RAM-only servers erase your data if the server is seized&lt;/li&gt;
&lt;li&gt;You can use one Surfshark account to secure every device you own that supports a VPN client.&lt;/li&gt;
&lt;li&gt;Surfshark offers advanced privacy features, including rotating IP and Dynamic MultiHop.&lt;/li&gt;
&lt;li&gt;Surfshark is considered to be competitively priced.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;NordVPN&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why Choose NordVPN?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large Server Network:&lt;/strong&gt; Access to a vast number of servers in multiple countries, over 5,500 servers worldwide, allowing for fast connections and diverse location options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Security Features:&lt;/strong&gt; Utilizes industry-standard encryption protocols like AES-256 for maximum data protection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark Web Monitor&lt;/strong&gt;: Get instant alerts about leaked credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threat Protection:&lt;/strong&gt; Additional feature to block malware, trackers, and malicious websites.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;VPNs&lt;/strong&gt; are essential for maintaining online privacy and security in today’s digital world. This article covered how &lt;strong&gt;VPNs&lt;/strong&gt; work, their benefits, and key networking concepts like &lt;strong&gt;NIC&lt;/strong&gt; and &lt;strong&gt;NAT&lt;/strong&gt; that facilitate secure and efficient connectivity. Whether you’re looking to safeguard your personal data, bypass geographical restrictions, or prevent ISP throttling, a &lt;strong&gt;VPN&lt;/strong&gt; is a great tool. With reliable options like Surfshark&lt;/p&gt;

</description>
      <category>networking</category>
      <category>vpn</category>
      <category>privacy</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Angular Template Variables: A Comprehensive Breakdown</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Sat, 14 Sep 2024 16:52:45 +0000</pubDate>
      <link>https://dev.to/bytebantz/angular-template-variables-a-comprehensive-breakdown-27i1</link>
      <guid>https://dev.to/bytebantz/angular-template-variables-a-comprehensive-breakdown-27i1</guid>
      <description>&lt;p&gt;Template variables are a simple way to reference DOM elements or directives inside your template, allowing you to use their values or manipulate them elsewhere in your component.&lt;/p&gt;

&lt;p&gt;In this article, we will break down the syntax, scope, and use cases of template variables, demonstrating how they can be used effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Declaring a Template Variable
&lt;/h2&gt;

&lt;p&gt;To declare a &lt;strong&gt;template variable&lt;/strong&gt; in Angular, you use the &lt;strong&gt;#&lt;/strong&gt; &lt;strong&gt;symbol&lt;/strong&gt;, followed by a &lt;strong&gt;variable name&lt;/strong&gt;. You can use this variable to reference DOM elements like &lt;strong&gt;inputs&lt;/strong&gt;, &lt;strong&gt;buttons&lt;/strong&gt;, or even &lt;strong&gt;Angular&lt;/strong&gt; &lt;strong&gt;components&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input #phone placeholder="Enter your phone number" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the #phone variable refers to the &lt;strong&gt;&lt;/strong&gt; element.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Using Template Variables
&lt;/h2&gt;

&lt;p&gt;Once declared, you can use the &lt;strong&gt;template variable&lt;/strong&gt; elsewhere in your template. For example, you can access the value of the input element and pass it to a function when a button is clicked.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input #phone placeholder="Enter your phone number" /&amp;gt;
&amp;lt;button (click)="callPhone(phone.value)"&amp;gt;Call&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the template variable phone refers to the &lt;strong&gt;&lt;/strong&gt; element.&lt;/p&gt;

&lt;p&gt;When you click the button, the value of the input (&lt;strong&gt;phone.value&lt;/strong&gt;) is passed to the &lt;strong&gt;callPhone()&lt;/strong&gt; function in your component.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Angular Assigns Values to Template Variables
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;· DOM Element:&lt;/strong&gt; If you declare a variable on an HTML tag like &lt;strong&gt;&lt;/strong&gt;, the variable refers to that HTML element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;· Component:&lt;/strong&gt; If you declare it on a component, it refers to the &lt;strong&gt;instance&lt;/strong&gt; of that component, allowing you to access its public methods and properties..&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;You can also use &lt;strong&gt;template reference variables&lt;/strong&gt; to interact with child components. For instance, if you have a video player component, you might want to control it (play, pause, etc.) from the parent template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- VideoPlayerComponent has methods like play() and pause() --&amp;gt;
&amp;lt;app-video-player #videoPlayer&amp;gt;&amp;lt;/app-video-player&amp;gt;
&amp;lt;button (click)="videoPlayer.play()"&amp;gt;Play&amp;lt;/button&amp;gt;
&amp;lt;button (click)="videoPlayer.pause()"&amp;gt;Pause&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;· Directive (like ngModel):&lt;/strong&gt; If you declare a variable and specify a name, such as &lt;strong&gt;#form=”ngForm”&lt;/strong&gt;, the variable refers to the &lt;strong&gt;directive instance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form #itemForm="ngForm" &amp;gt;
  &amp;lt;label for="name"&amp;gt;Name&amp;lt;/label&amp;gt;
  &amp;lt;input
    type="text"
    id="name"
    name="name"
    ngModel
    required
    minlength="3"
  /&amp;gt;
  &amp;lt;div *ngIf="!itemForm.form.valid"&amp;gt;
    Name is required and must be at least 3 characters long.
  &amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Template Variable Scope
&lt;/h2&gt;

&lt;p&gt;Template variables are scoped to the area where they are declared, similar to how variables in JavaScript or TypeScript are scoped..&lt;/p&gt;

&lt;p&gt;If you declare a template variable inside an &lt;strong&gt;*ngIf&lt;/strong&gt; or &lt;strong&gt;*ngFor&lt;/strong&gt;, it will only be available in that scope.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input #ref1 type="text" /&amp;gt;
&amp;lt;span&amp;gt;{{ ref1.value }}&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works because both the &lt;strong&gt;input&lt;/strong&gt; and the &lt;strong&gt;span&lt;/strong&gt; are in the same scope. But if you declare the input inside an &lt;strong&gt;*ngIf&lt;/strong&gt;, it will be limited to that block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngIf="true"&amp;gt;
  &amp;lt;input #ref2 type="text" /&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;span&amp;gt;{{ ref2?.value }}&amp;lt;/span&amp;gt;
&amp;lt;!-- This won't work because ref2 is in a different scope --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The span cannot access &lt;strong&gt;ref2&lt;/strong&gt; because the &lt;strong&gt;#ref2&lt;/strong&gt; variable is inside the **/*ngIf **block, which creates a separate scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;p&gt;Common use cases include:&lt;br&gt;
&lt;strong&gt;· Accessing form fields for validation:&lt;/strong&gt; Template variables can be used to easily reference form elements and check their validity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;· Interacting with child components:&lt;/strong&gt; You can control child components directly from the parent template by referencing the component instance with a template variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;· DOM manipulation:&lt;/strong&gt; Template variables allow you to interact with DOM elements, such as retrieving their values or triggering focus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;· Managing dynamically rendered elements:&lt;/strong&gt; When working with dynamically rendered elements (e.g., using &lt;strong&gt;*ngIf&lt;/strong&gt; or &lt;strong&gt;*ngFor&lt;/strong&gt;), template variables help manage their state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Template variables&lt;/strong&gt; in Angular are a simple but powerful feature that allows &lt;strong&gt;direct interaction&lt;/strong&gt; with DOM elements, components, and directives from the template. By understanding their syntax, scope, and various use cases, you can enhance your Angular applications by reducing complexity in your component class while improving template interaction.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Mastering Angular 18 State Management using NgRx</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Tue, 10 Sep 2024 07:38:24 +0000</pubDate>
      <link>https://dev.to/bytebantz/mastering-angular-18-state-management-using-ngrx-5fao</link>
      <guid>https://dev.to/bytebantz/mastering-angular-18-state-management-using-ngrx-5fao</guid>
      <description>&lt;p&gt;&lt;strong&gt;State management&lt;/strong&gt; in Angular ensures that data is consistently and efficiently shared across all parts of an application. Instead of each component managing its own data, a central store holds the state.&lt;/p&gt;

&lt;p&gt;This centralization ensures that when data changes, all components automatically reflect the updated state, leading to consistent behavior and simpler code. It also makes the app easier to maintain and scale, as data flow is managed from a single source of truth.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore how to implement state management in Angular using NgRx by building a simple shopping cart application. We’ll cover the core concepts of NgRx, such as the &lt;strong&gt;Store, Actions, Reducers, Selectors,&lt;/strong&gt; and &lt;strong&gt;Effects&lt;/strong&gt;, and demonstrate how these pieces fit together to manage the state of your application effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt; in Angular refers to the data your app needs to manage and display, like a shopping cart’s contents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you need State Management
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Consistency:&lt;/strong&gt; It ensures that data is uniform across all components. When data changes in one place, the central store updates all relevant components automatically, preventing inconsistencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Simplified Data Flow:&lt;/strong&gt; Instead of passing data between components manually, state management allows any component to access or update data directly from the central store, making the app’s data flow easier to manage and understand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Easier Maintenance and Scalability:&lt;/strong&gt; By centralizing data management, state management reduces code duplication and complexity. This makes the app easier to maintain, debug, and scale as it grows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Performance Optimization:&lt;/strong&gt; State management solutions often come with tools to optimize performance, such as selectively updating only the components that need to react to a change in state, rather than re-rendering the entire application.&lt;/p&gt;

&lt;h2&gt;
  
  
  How NgRx works
&lt;/h2&gt;

&lt;p&gt;NgRx is a state management library for Angular that helps manage and maintain the state of your application in a predictable way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl571fjnruhx3e1bjwjxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl571fjnruhx3e1bjwjxk.png" alt="NgRx Life Cycle" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The component is where the user interacts with your app. It might be a button to add an item to the shopping cart.&lt;/p&gt;

&lt;p&gt;Components and services are separated and don’t communicate with each other directly, instead &lt;strong&gt;services&lt;/strong&gt; are used within &lt;strong&gt;effects&lt;/strong&gt; thus creating an application structure different from a traditional Angular app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Action&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An action describes what happened and contains any necessary payload (data).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Reducer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Updates the state based on the action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Store&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The store is a centralized place that holds the entire state of your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Selector&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Extracts data from the store for components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Effects&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Effects are where you handle logic that doesn’t belong in the reducer, like API calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Services perform the actual business logic or API calls. Effects often use services to perform tasks like fetching data from a server.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use NgRx
&lt;/h2&gt;

&lt;p&gt;Use &lt;strong&gt;NgRx&lt;/strong&gt; when your app’s complexity justifies it, but for straightforward apps, stick to simpler state management methods. Angular’s &lt;strong&gt;services&lt;/strong&gt;, &lt;strong&gt;signals&lt;/strong&gt; and &lt;strong&gt;@Input/@Output&lt;/strong&gt; bindings between components are usually sufficient for managing state in less complex applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Building an Add to Cart Feature with NgRx
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1.Create a New Angular Project:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new shopping-cart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Install NGRX and Effects&lt;/strong&gt;&lt;br&gt;
To install NGRX and Effects, run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng add @ngrx/store@latest

ng add @ngrx/effects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Define the Product Model&lt;/strong&gt;&lt;br&gt;
Inside the &lt;strong&gt;src/app&lt;/strong&gt; directory, create a file named &lt;strong&gt;product.model.ts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Define the &lt;strong&gt;Product&lt;/strong&gt; interface to represent the structure of a product:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface Product {
    id: string;
    name: string;
    price: number;
    quantity: number;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Set Up State Management&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1: Create state Folder inside the src/app directory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Define Cart Actions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;strong&gt;cart.actions.ts&lt;/strong&gt; in the state folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createActionGroup, emptyProps, props } from '@ngrx/store';
import { Product } from '../product.model';

export const CartActions = createActionGroup({
  source: 'Cart',
  events: {
    'Add Product': props&amp;lt;{ product: Product }&amp;gt;(),
    'Remove Product': props&amp;lt;{ productId: string }&amp;gt;(),
    'Update Quantity': props&amp;lt;{ productId: string; quantity: number }&amp;gt;(),
    'Load Products': emptyProps,
  },
});

export const CartApiActions = createActionGroup({
  source: 'Cart API',
  events: {
    'Load Products Success': props&amp;lt;{ products: Product[] }&amp;gt;(),
    'Load Products Failure': props&amp;lt;{ error: string }&amp;gt;(),
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Create Reducers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;strong&gt;cart.reducer.ts&lt;/strong&gt; in the &lt;strong&gt;state&lt;/strong&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createReducer, on } from '@ngrx/store';
import { Product } from '../product.model';
import { CartActions, CartApiActions } from './cart.actions';

// Initial state for products and cart
export const initialProductsState: ReadonlyArray&amp;lt;Product&amp;gt; = [];
export const initialCartState: ReadonlyArray&amp;lt;Product&amp;gt; = [];

// Reducer for products (fetched from API)
export const productsReducer = createReducer(
  initialProductsState,
  on(CartApiActions.loadProductsSuccess, (_state, { products }) =&amp;gt; products)
);

// Reducer for cart (initially empty)
export const cartReducer = createReducer(
  initialCartState,
  on(CartActions.addProduct, (state, { product }) =&amp;gt; {
    const existingProduct = state.find(p =&amp;gt; p.id === product.id);
    if (existingProduct) {
      return state.map(p =&amp;gt;
        p.id === product.id ? { ...p, quantity: p.quantity + product.quantity } : p
      );
    }
    return [...state, product];
  }),
  on(CartActions.removeProduct, (state, { productId }) =&amp;gt;
    state.filter(p =&amp;gt; p.id !== productId)
  ),
  on(CartActions.updateQuantity, (state, { productId, quantity }) =&amp;gt;
    state.map(p =&amp;gt;
      p.id === productId ? { ...p, quantity } : p
    )
  )
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Create Selectors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;state&lt;/strong&gt; folder, create &lt;strong&gt;cart.selectors.ts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSelector, createFeatureSelector } from '@ngrx/store';
import { Product } from '../product.model';

export const selectProducts = createFeatureSelector&amp;lt;ReadonlyArray&amp;lt;Product&amp;gt;&amp;gt;('products');

export const selectCart = createFeatureSelector&amp;lt;ReadonlyArray&amp;lt;Product&amp;gt;&amp;gt;('cart');

export const selectCartTotal = createSelector(selectCart, (cart) =&amp;gt;
  cart.reduce((total, product) =&amp;gt; total + product.price * product.quantity, 0)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Create Effects&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new file &lt;strong&gt;cart.effects.ts&lt;/strong&gt; in the &lt;strong&gt;state&lt;/strong&gt; folder that listens for the &lt;strong&gt;Load Products&lt;/strong&gt; action, uses the service to fetch products, and dispatches either a success or failure action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { ProductService } from '../product.service';
import { CartActions, CartApiActions } from './cart.actions';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { of } from 'rxjs';

@Injectable()
export class CartEffects {
  loadProducts$ = createEffect(() =&amp;gt;
    this.actions$.pipe(
      ofType(CartActions.loadProducts),
      mergeMap(() =&amp;gt;
        this.productService.getProducts().pipe(
          map(products =&amp;gt; CartApiActions.loadProductsSuccess({ products })),
          catchError(error =&amp;gt; of(CartApiActions.loadProductsFailure({ error })))
        )
      )
    )
  );

  constructor(
    private actions$: Actions,
    private productService: ProductService
  ) {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Connect the State Management to Your App&lt;/strong&gt;&lt;br&gt;
In a file called &lt;strong&gt;app.config.ts,&lt;/strong&gt; set up configurations for providing the &lt;strong&gt;store&lt;/strong&gt; and &lt;strong&gt;effects&lt;/strong&gt; to the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ApplicationConfig } from '@angular/core';
import { provideStore } from '@ngrx/store';
import { provideHttpClient } from '@angular/common/http';
import { cartReducer, productsReducer } from './state/cart.reducer';
import { provideEffects } from '@ngrx/effects';
import { CartEffects } from './state/cart.effects';

export const appConfig: ApplicationConfig = {
  providers: [
    provideStore({
      products: productsReducer, 
      cart: cartReducer 
    }),
    provideHttpClient(),
    provideEffects([CartEffects])
],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6. Create a Service to Fetch Products&lt;/strong&gt;&lt;br&gt;
In the &lt;strong&gt;src/app&lt;/strong&gt; directory create &lt;strong&gt;product.service.ts&lt;/strong&gt; to implement the service to fetch products&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { Product } from './product.model';

@Injectable({ providedIn: 'root' })
export class ProductService {
  getProducts(): Observable&amp;lt;Array&amp;lt;Product&amp;gt;&amp;gt; {
    return of([
      { id: '1', name: 'Product 1', price: 10, quantity: 1 },
      { id: '2', name: 'Product 2', price: 20, quantity: 1 },
    ]);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7. Create the Product List Component&lt;/strong&gt;&lt;br&gt;
Run the following command to generate the component: &lt;strong&gt;ng generate component product-list&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This component displays the list of products and allows adding them to the cart.&lt;/p&gt;

&lt;p&gt;Modify the &lt;strong&gt;product-list.component.ts&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { Product } from '../product.model';
import { selectProducts } from '../state/cart.selectors';
import { CartActions } from '../state/cart.actions';

@Component({
  selector: 'app-product-list',
  standalone: true,
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css'],
  imports: [CommonModule],
})
export class ProductListComponent implements OnInit {
  products$!: Observable&amp;lt;ReadonlyArray&amp;lt;Product&amp;gt;&amp;gt;;

  constructor(private store: Store) {

  }

  ngOnInit(): void {
    this.store.dispatch(CartActions.loadProducts()); // Dispatch load products action
    this.products$ = this.store.select(selectProducts); // Select products from the store
  }

  onAddToCart(product: Product) {
    this.store.dispatch(CartActions.addProduct({ product }));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;strong&gt;product-list.component.html&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngIf="products$ | async as products"&amp;gt;
  &amp;lt;div class="product-item" *ngFor="let product of products"&amp;gt;
    &amp;lt;p&amp;gt;{{product.name}}&amp;lt;/p&amp;gt;
    &amp;lt;span&amp;gt;{{product.price | currency}}&amp;lt;/span&amp;gt;
    &amp;lt;button (click)="onAddToCart(product)" data-test="add-button"&amp;gt;Add to Cart&amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;8. Create the Shopping Cart Component&lt;/strong&gt;&lt;br&gt;
Run the following command to generate the component: &lt;strong&gt;ng generate component shopping-cart&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This component displays the products in the cart and allows updating the quantity or removing items from the cart.&lt;/p&gt;

&lt;p&gt;Modify the &lt;strong&gt;shopping-cart.component.ts&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { Product } from '../product.model';
import { selectCart, selectCartTotal } from '../state/cart.selectors';
import { CartActions } from '../state/cart.actions';

@Component({
  selector: 'app-shopping-cart',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './shopping-cart.component.html',
  styleUrls: ['./shopping-cart.component.css'],
})
export class ShoppingCartComponent implements OnInit {
  cart$: Observable&amp;lt;ReadonlyArray&amp;lt;Product&amp;gt;&amp;gt;;
  cartTotal$: Observable&amp;lt;number&amp;gt;;

  constructor(private store: Store) {
    this.cart$ = this.store.select(selectCart);
    this.cartTotal$ = this.store.select(selectCartTotal);
  }

  ngOnInit(): void {}

  onRemoveFromCart(productId: string) {
    this.store.dispatch(CartActions.removeProduct({ productId }));
  }

  onQuantityChange(event: Event, productId: string) {
    const inputElement = event.target as HTMLInputElement;
    let quantity = parseInt(inputElement.value, 10);

    this.store.dispatch(CartActions.updateQuantity({ productId, quantity }));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;strong&gt;shopping-cart.component.html&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngIf="cart$ | async as cart"&amp;gt;
  &amp;lt;div class="cart-item" *ngFor="let product of cart"&amp;gt;
    &amp;lt;p&amp;gt;{{product.name}}&amp;lt;/p&amp;gt;&amp;lt;span&amp;gt;{{product.price | currency}}&amp;lt;/span&amp;gt;
    &amp;lt;input type="number" [value]="product.quantity" (input)="onQuantityChange($event, product.id)" /&amp;gt;
    &amp;lt;button (click)="onRemoveFromCart(product.id)" data-test="remove-button"&amp;gt;Remove&amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class="total"&amp;gt;
    Total: {{cartTotal$ | async | currency}}
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;strong&gt;shopping-cart.component.css&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.cart-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.cart-item p {
  margin: 0;
  font-size: 16px;
}

.cart-item input {
  width: 50px;
  text-align: center;
}

.total {
  font-weight: bold;
  margin-top: 20px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;9. Put Everything Together in the App Component&lt;/strong&gt;&lt;br&gt;
This component will display the product list and the shopping cart&lt;/p&gt;

&lt;p&gt;Modify the &lt;strong&gt;app.component.ts&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProductListComponent } from './product-list/product-list.component';
import { ShoppingCartComponent } from './shopping-cart/shopping-cart.component';
import { NgIf } from '@angular/common';

@Component({
  selector: 'app-root',
  standalone: true,
  templateUrl: './app.component.html',
  imports: [CommonModule, ProductListComponent, ShoppingCartComponent, NgIf],
})
export class AppComponent {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;strong&gt;app.component.html&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- app.component.html --&amp;gt;
&amp;lt;h2&amp;gt;Products&amp;lt;/h2&amp;gt;
&amp;lt;app-product-list&amp;gt;&amp;lt;/app-product-list&amp;gt;

&amp;lt;h2&amp;gt;Shopping Cart&amp;lt;/h2&amp;gt;
&amp;lt;app-shopping-cart&amp;gt;&amp;lt;/app-shopping-cart&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;10. Running the Application&lt;/strong&gt;&lt;br&gt;
Finally, run your application using &lt;strong&gt;ng serve.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, you can add products to your cart, remove them, or update their quantities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we built a simple shopping cart application to demonstrate the core concepts of &lt;strong&gt;NgRx&lt;/strong&gt;, such as the &lt;strong&gt;Store, Actions, Reducers, Selectors,&lt;/strong&gt; and &lt;strong&gt;Effects&lt;/strong&gt;. This example serves as a foundation for understanding how &lt;strong&gt;NgRx&lt;/strong&gt; works and how it can be applied to more complex applications.&lt;/p&gt;

&lt;p&gt;As your Angular projects grow in complexity, leveraging &lt;strong&gt;NgRx&lt;/strong&gt; for state management will help you maintain consistency across your application, reduce the likelihood of bugs, and make your codebase easier to maintain.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Angular Pipes: A Comprehensive guide</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 09 Sep 2024 10:05:39 +0000</pubDate>
      <link>https://dev.to/bytebantz/angular-pipes-a-comprehensive-guide-h5g</link>
      <guid>https://dev.to/bytebantz/angular-pipes-a-comprehensive-guide-h5g</guid>
      <description>&lt;p&gt;&lt;strong&gt;Pipes&lt;/strong&gt; in Angular are simple functions used to transform data in templates without modifying the underlying data. Pipes take in a value, process it, and return a formatted or transformed output. They are often used for formatting dates, numbers, strings, and even arrays or objects.&lt;/p&gt;

&lt;p&gt;They allow you to format and display data in a more readable or relevant format directly in the view without altering the underlying data model.&lt;/p&gt;

&lt;p&gt;Using &lt;strong&gt;pipes&lt;/strong&gt; helps in keeping the code &lt;strong&gt;clean&lt;/strong&gt; and &lt;strong&gt;readable&lt;/strong&gt;. Instead of writing complex logic in the templates or components, you can encapsulate that logic in a &lt;strong&gt;pipe&lt;/strong&gt;, which can then be reused across different parts of your application. &lt;br&gt;
For example, if you’re developing a blog platform where users can see the publication date of articles. Dates need to be displayed in a user-friendly format, such as “August 31, 2024,” instead of the raw format “2024–08–31T14:48:00.000Z”. With &lt;strong&gt;pipes&lt;/strong&gt;, you can use Angular’s built-in &lt;strong&gt;DatePipe&lt;/strong&gt; in the template instead of manually formatting the date in the component, cluttering the code and reducing readability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Published on: {{ article.publishDate | date:'longDate' }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To apply a pipe, use the &lt;strong&gt;pipe&lt;/strong&gt; &lt;strong&gt;operator&lt;/strong&gt; (|) within a template expression as shown in the above code example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built-in Pipes
&lt;/h2&gt;

&lt;p&gt;Angular comes with several built-in pipes that cover common tasks (&lt;strong&gt;DatePipe, UpperCasePipe, LowerCasePipe, CurrencyPipe, AsyncPipe, JsonPipe,&lt;/strong&gt; etc.). Knowing how to use these can make your code cleaner and more efficient.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;pre&amp;gt;{{ user | json }}&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Price: {{ product.price | currency:'USD' }}&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;{{ user.name | uppercase }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Parametrized Pipes
&lt;/h2&gt;

&lt;p&gt;Many Angular &lt;strong&gt;pipes&lt;/strong&gt; accept parameters to customize their behavior.&lt;/p&gt;

&lt;p&gt;To specify the &lt;strong&gt;parameter&lt;/strong&gt;, follow the pipe name with a &lt;strong&gt;colon&lt;/strong&gt; (:) and the parameter value&lt;/p&gt;

&lt;p&gt;Some &lt;strong&gt;pipes&lt;/strong&gt; accept &lt;strong&gt;multiple&lt;/strong&gt; parameters, which are separated by additional colons.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt; can be &lt;strong&gt;optional&lt;/strong&gt; or &lt;strong&gt;required&lt;/strong&gt;. Suppose you have a custom pipe that formats currency and requires you to specify the currency type as a parameter. If this parameter is not provided, the pipe might not be able to format the value correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;The product price is {{ price | customCurrency:'USD' }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;1. DatePipe with Parameters&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Published on: {{ article.publishDate | date:'MMMM d, y, h:mm:ss a' }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This formats the date as “August 31, 2024, 2:48:00 PM”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. CurrencyPipe with Parameters&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Price: {{ product.price | currency:'EUR':'symbol-narrow':'1.0-0' }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This formats the price as “€1,235” (rounded to no decimal places).&lt;/p&gt;

&lt;h2&gt;
  
  
  Chaining Pipes
&lt;/h2&gt;

&lt;p&gt;You can chain multiple pipes together to achieve complex transformations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;{{ article.content | slice:0:100 | uppercase }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will slice the first 100 characters of &lt;strong&gt;article.content&lt;/strong&gt; and convert them to uppercase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Pipes
&lt;/h2&gt;

&lt;p&gt;Sometimes, the built-in pipes may not meet your specific needs and you will need to create a custom pipe to handle the specific logic. Here’s how you can do it.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;In the following example we are going to create a pipe that adds a greeting to a name like “Hello, Alice!”&lt;/p&gt;

&lt;p&gt;Run the following command to generate a new pipe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate pipe greet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s modify the greet.pipe.ts file in the src/app directory to include the pipe logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'greet',  // This is the name you'll use in the template
  standalone: true,
})
export class GreetPipe implements PipeTransform {
  transform(value: string): string {
    return `Hello, ${value}!`;  // This is the transformation logic
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your pipe is ready, you can use it in your templates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;{{ 'Alice' | greet }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Parameterized Custom Pipe
&lt;/h2&gt;

&lt;p&gt;Now we are going to make the greeting customizable, so you can say “Hi, Alice!” or “Welcome, Alice!” depending on what you pass to the pipe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'greet',  // Same pipe name as before
  standalone: true,
})
export class GreetPipe implements PipeTransform {
  transform(value: string, greeting: string = 'Hello'): string {
    return `${greeting}, ${value}!`;  // Now it uses the greeting passed in
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The transform method now has a second parameter, greeting. If no greeting is provided, it defaults to “Hello”.&lt;/p&gt;

&lt;p&gt;Now you can customize the greeting in your templates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;{{ 'Alice' | greet:'Hi' }}&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;{{ 'Bob' | greet:'Welcome' }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pure vs. Impure Pipes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Pure Pipes&lt;/strong&gt;&lt;br&gt;
By default, all Angular pipes are &lt;strong&gt;pure&lt;/strong&gt;. A &lt;strong&gt;pure pipe&lt;/strong&gt; only gets called when input data (like a number or a string) or when the reference to an object (like an array or date) changes. This makes pure pipes efficient and performant because the pipe doesn’t run unnecessarily.&lt;/p&gt;

&lt;p&gt;However, if your data is more complex, like an array of items, Angular might not notice changes inside the array (like adding a new item) because the reference to the array hasn’t changed.&lt;/p&gt;

&lt;p&gt;Unless necessary, keep your pipes &lt;strong&gt;pure&lt;/strong&gt; to avoid unnecessary re-renders and to maintain performance.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Pipe({
  name: "onSale",
  standalone: true,
  pure: true,
})
export class OnSalePipe implements PipeTransform {
  transform(items: Item[]): Item[] {
    return items.filter((item) =&amp;gt; item.isOnSale);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  &amp;lt;li *ngFor="let item of (items | onSale)"&amp;gt;
    {{ item.name }} - {{ item.price | formatPrice }}
  &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you add a new item to the &lt;strong&gt;items&lt;/strong&gt; array that’s on sale, you might expect it to show up in the list. But if you simply push the new item into the array, the list might not update because the array reference hasn’t changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Impure Pipes
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;impure pipe&lt;/strong&gt;, on the other hand, is called every time Angular performs a change detection cycle. However, because they run so often, they can slow down your app.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Pipe({
  name: "onSaleImpure",
  standalone: true,
  pure: false,
})
export class OnSaleImpurePipe implements PipeTransform {
  transform(items: Item[]): Item[] {
    return items.filter((item) =&amp;gt; item.isOnSale);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  &amp;lt;li *ngFor="let item of (items | onSaleImpure)"&amp;gt;
    {{ item.name }} - {{ item.price | formatPrice }}
  &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you add a new item, the pipe will notice the change and update the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for Using Pipes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Keep Pipes Simple. Avoid Heavy Computations in Pipes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Name Pipes Clearly and Descriptively&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep Pipes Focused on a Single Responsibility&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid Impure Pipes When Possible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test Custom Pipes Thoroughly&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Angular &lt;strong&gt;pipes&lt;/strong&gt; streamline data transformation tasks, making your code more modular, reusable, and maintainable. They help to enforce consistency across the application and improve the readability of your templates, which is crucial for developing scalable and maintainable applications.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Boosting Angular Speed with Better Change Detection</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 15 Jul 2024 09:10:33 +0000</pubDate>
      <link>https://dev.to/bytebantz/boosting-angular-speed-with-better-change-detection-81</link>
      <guid>https://dev.to/bytebantz/boosting-angular-speed-with-better-change-detection-81</guid>
      <description>&lt;p&gt;Angular Change detection is a feature that detects changes in the application’s data and updates the DOM accordingly, ensuring that the user interface remains up-to-date with the latest data. Imagine you have a to-do list app. When you add a new item, change detection ensures that the new item appears on the screen without you having to manually refresh the page.&lt;/p&gt;

&lt;p&gt;Angular uses a library called &lt;strong&gt;Zone.js&lt;/strong&gt; to help with change detection. &lt;strong&gt;Zone.js&lt;/strong&gt; is a library that provides a mechanism for wrapping JavaScript code and executing it in a specific context or zone. In Angular, &lt;strong&gt;Zone.js&lt;/strong&gt; is used to create a new zone for each component and to track changes within that component’s zone. A &lt;strong&gt;zone&lt;/strong&gt; is basically an execution context for your code. When the application starts, Angular creates its own zone instance ngZone by extending the one provided by &lt;strong&gt;Zone.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By default, Angular uses a “&lt;strong&gt;check always&lt;/strong&gt;” strategy, where it checks all components in the component tree for changes on every event cycle. This can be inefficient, especially for large applications with complex component trees.&lt;/p&gt;

&lt;p&gt;Angular Change Detection runs automatically by default. However, there are times when you may want to manually trigger change detection. To manually trigger change detection in your application, you can use the &lt;strong&gt;detectChanges()&lt;/strong&gt; method provided by the &lt;strong&gt;ChangeDetectorRef&lt;/strong&gt; class which will run change detection on this view and its children. This method can be used within components or services&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(private cd:ChangeDetectorRef){}
    // Call this function when you want to manually trigger change detection 
    detectChanges(){
        this.cd.detectChanges();
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also trigger change detection manually by using:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- ApplicationRef.tick()&lt;/strong&gt; which triggers change detection for every components in the component tree (basically whole application)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- markForCheck()&lt;/strong&gt; on &lt;strong&gt;ChangeDetectorRef&lt;/strong&gt; which marks all &lt;strong&gt;OnPush&lt;/strong&gt; ancestors to be checked once, either on the current or next detection cycle. This method does not trigger the change detector directly.&lt;/p&gt;

&lt;p&gt;Running specific code outside the Zone allows developers to manage change detection manually, which can be beneficial in complex applications where optimizing change detection cycles is critical.&lt;/p&gt;

&lt;p&gt;Any code that we want to run outside of the Angular zone should be placed inside &lt;strong&gt;runOutsideAngular()&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By placing code inside &lt;strong&gt;runOutsideAngular()&lt;/strong&gt;, developers can ensure that certain operations do not trigger change detection, thus improving performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class AppComponent {
    constructor(private zone: NgZone) { }

    handleClick() {
        this.zone.runOutsideAngular(() =&amp;gt; {
            // Code to run outside of the Angular zone
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly any code that we want to run inside of the Angular zone should be placed inside &lt;strong&gt;run()&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This simplifies development as developers don’t have to manually trigger change detection after every asynchronous operation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class AppComponent {
    constructor(private zone: NgZone) { }

    handleClick() {
        this.zone.run(() =&amp;gt; {
            // Code to run inside the Angular zone
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Angular comes with two component change detection strategies: &lt;strong&gt;default&lt;/strong&gt; and &lt;strong&gt;onPush&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  i. Default (check always)
&lt;/h2&gt;

&lt;p&gt;In the &lt;strong&gt;default&lt;/strong&gt; change detection strategy, Angular automatically triggers change detection whenever an event occurs or data changes.&lt;/p&gt;

&lt;p&gt;The process works by traversing the component tree in the application. It starts from the root component and checks for changes in each component even if no changes occured.&lt;/p&gt;

&lt;p&gt;If you have a large number of components or nested components in your Angular application, performance issues are more likely to occur.&lt;/p&gt;

&lt;h2&gt;
  
  
  ii. OnPush
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;OnPush&lt;/strong&gt; change detection strategy allows you to optimize performance by only triggering change detection when input properties of a component change or when an event has been fired from that component.&lt;/p&gt;

&lt;p&gt;This strategy significantly reduces the number of checks Angular performs, leading to better performance, especially in large and complex applications.&lt;/p&gt;

&lt;p&gt;Developers can specify this strategy at the component level, meaning that some components can use “&lt;strong&gt;OnPush&lt;/strong&gt;” while others continue to use the &lt;strong&gt;default&lt;/strong&gt; strategy.&lt;/p&gt;

&lt;p&gt;We can change the detection strategy from &lt;strong&gt;default&lt;/strong&gt; to &lt;strong&gt;ChangeDetectionStrategy.OnPush&lt;/strong&gt; by adding &lt;strong&gt;changeDetection&lt;/strong&gt; property on &lt;strong&gt;@Component&lt;/strong&gt; decorator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MyComponent {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since “&lt;strong&gt;OnPush&lt;/strong&gt;” relies on reference changes to detect updates, mutating the properties of an object (e.g., adding or modifying elements in an array) won’t trigger change detection. Always create new instances of objects or arrays when updating them.&lt;/p&gt;

&lt;p&gt;To treat a reference type as immutable, reassign the value all together.&lt;/p&gt;

&lt;p&gt;In this example, calling &lt;strong&gt;updateName()&lt;/strong&gt; will not trigger change detection in the &lt;strong&gt;ChildComponent&lt;/strong&gt; because the reference to data remains the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class ParentComponent {
    data = { name: 'John' };

    updateName() {
        this.data.name = 'Doe'; // Mutating the existing object
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;strong&gt;updateName()&lt;/strong&gt; creates a new object, changing the reference, which triggers change detection in the &lt;strong&gt;ChildComponent&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class ParentComponent {
    data = { name: 'John' };

    updateName() {
        this.data = { ...this.data, name: 'Doe' }; // Creating a new object
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To effectively use the “&lt;strong&gt;OnPush&lt;/strong&gt;” change detection strategy in Angular, always ensure immutability&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use OnPush&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· You have a component that solely depends on immutable input parameters.&lt;/p&gt;

&lt;p&gt;· You have a component which has heavy rendering (such as components that display charts, graphs etc.). In this case, you can use OnPush to save computation power by avoiding to render the component when it is not necessary&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Angular’s change detection, powered by &lt;strong&gt;Zone.js&lt;/strong&gt;, keeps the user interface in sync with data changes. While the default “&lt;strong&gt;check always&lt;/strong&gt;” strategy ensures the UI is updated automatically, it can be inefficient for large applications. Developers can manually control change detection using methods like &lt;strong&gt;detectChanges()&lt;/strong&gt; or &lt;strong&gt;markForCheck()&lt;/strong&gt;. Running code outside Angular’s zone can optimize performance by reducing unnecessary change detections. Additionally, using the &lt;strong&gt;OnPush&lt;/strong&gt; strategy helps improve performance by only checking for changes when necessary. By understanding and using these strategies, developers can build efficient and responsive Angular applications.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
