<?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: Playful Programming Angular</title>
    <description>The latest articles on DEV Community by Playful Programming Angular (@playfulprogramming-angular).</description>
    <link>https://dev.to/playfulprogramming-angular</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%2Forganization%2Fprofile_image%2F3316%2F612534f5-7bba-4bfe-8455-998219bc57cf.png</url>
      <title>DEV Community: Playful Programming Angular</title>
      <link>https://dev.to/playfulprogramming-angular</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/playfulprogramming-angular"/>
    <language>en</language>
    <item>
      <title>Ng-News 26/12: Future of Selectorless, Skills vs. MCP, Zoneless Testing</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Fri, 10 Apr 2026 13:22:25 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2612-future-of-selectorless-skills-vs-mcp-zoneless-testing-3gmo</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2612-future-of-selectorless-skills-vs-mcp-zoneless-testing-3gmo</guid>
      <description>&lt;p&gt;Ng-News 26/12 covers the Angular Q&amp;amp;A on selectorless and Skills versus MCP, then zoneless testing and auto tick from the Angular Plus Show.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/AV8DDpkbeZI"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Q&amp;amp;A: selectorless and Skills vs MCP
&lt;/h2&gt;

&lt;p&gt;The monthly Q&amp;amp;A session featured Mark Thompson as host and Alex Rickabaugh, tech lead of the Angular framework.&lt;/p&gt;

&lt;p&gt;Alex explained why selectorless got downgraded. Selectorless was a planned feature that would have allowed referring to components in a template by using their class name. In the latest roadmap update, that feature was removed.&lt;/p&gt;

&lt;p&gt;According to Alex, selectorless would have been a huge jump. The risk of an AI agent not being able to write modern Angular code was not worth the DX benefits from selectorless. Therefore, that feature is on hold and will be re-evaluated in the future.&lt;/p&gt;

&lt;p&gt;Timestamp: 0:05:50&lt;/p&gt;

&lt;p&gt;Skills and MCPs: According to Alex, Skills are starting to replace MCP tools, because a Skill can tell the agent about certain CLI commands, which can replace a dedicated MCP tool call.&lt;/p&gt;

&lt;p&gt;Timestamp: 23:11&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/VigynyjJJnM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Zoneless testing and auto tick
&lt;/h2&gt;

&lt;p&gt;The Angular Plus Show published an episode on &lt;strong&gt;zoneless testing&lt;/strong&gt; with Andrew Scott (Angular team), &lt;a class="mentioned-user" href="https://dev.to/younesjd"&gt;@younesjd&lt;/a&gt;, and Rainer Hahnekamp.&lt;/p&gt;

&lt;p&gt;Zoneless tests run outside Zone.js, which clarifies some patterns but means you cannot use &lt;code&gt;fakeAsync&lt;/code&gt; or &lt;code&gt;waitForAsync&lt;/code&gt; in that mode.&lt;/p&gt;

&lt;p&gt;With zoneless, change detection in tests would be triggered like in the application, whereas in zone-based tests, users had to trigger it very often manually via &lt;code&gt;ComponentFixture#detectChanges&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The panel also discussed &lt;strong&gt;auto tick&lt;/strong&gt;, recently released around the time of recording and covered in a prior ng-news segment.&lt;/p&gt;

&lt;p&gt;It can simplify async behavior when timer APIs are faked, but it is not always the first choice: mixing real and fake timers produces confusing failures, and faking timers overrides timing globally and can affect third-party code you do not control.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/wgWCOdeshtE"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Upcoming Conferences
&lt;/h2&gt;

&lt;p&gt;This is a new feature of ng-news. At the end of each article, we are listing all upcoming conferences.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://angularbelgrade.org/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fangularbelgrade.org%2Fbanners%2Fng-belgrade-conf-2026.jpg" height="424" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://angularbelgrade.org/" rel="noopener noreferrer" class="c-link"&gt;
            NG Belgrade Conf 2026
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            NG Belgrade Conf 2026 is the largest Angular conference in the Balkans. It takes place in Belgrade, Serbia, including a Conference Day on May 7th and a Workshop Day on May 8th. Join us to explore the latest trends and best practices in Angular!
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fangularbelgrade.org%2Fassets%2Ffavicon-A8dvQfkm.ico" width="256" height="256"&gt;
          angularbelgrade.org
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://ngbaguette.angulardevs.fr/en/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;ngbaguette.angulardevs.fr&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>angular</category>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Ng-News 26/11: TypeScript 6, NgRx RFCs delegatedSignal, Resource Extensions</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Fri, 03 Apr 2026 17:43:23 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2611-typescript-6-ngrx-rfcs-delegatedsignal-resource-extensions-ig6</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2611-typescript-6-ngrx-rfcs-delegatedsignal-resource-extensions-ig6</guid>
      <description>&lt;p&gt;Main topics: &lt;strong&gt;TypeScript 6.0&lt;/strong&gt; and &lt;strong&gt;NgRx&lt;/strong&gt; (RFCs for &lt;code&gt;delegatedSignal&lt;/code&gt; and resource extensions). Also in brief: Martina Kraus on security, debounce for async validators, Alfredo Perez on SpecKit, and Angular Graz on YouTube.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/SOJddVKtnMo"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript 6.0
&lt;/h2&gt;

&lt;p&gt;TypeScript 6.0 was released and it is going to be the last TypeScript version, written in TypeScript. Officially, TypeScript 6 is seen as the bridge between TypeScript 5 and TypeScript 7 (which will be written in Go). First of all, TypeScript 6 is not yet part of Angular. So you can't make use of those changes yet. Angular 21 supports TypeScript 5.9, but 22 will support TypeScript 6.&lt;/p&gt;

&lt;p&gt;In order to prepare for version 7, TypeScript 6 comes primarily with a lot of deprecations and new default settings, which pay tribute to the modern TypeScript ecosystem.&lt;/p&gt;

&lt;p&gt;For example, ESM is now default module system, the strict mode is enabled and the target is the ECMAScript version with the number of the current last year. By now, that would be ECMAScript 2025.&lt;/p&gt;

&lt;p&gt;When it comes to the deprecation. Target ES5, which was the last version of JavaScript without the class syntax, lambda expressions, Promises, let or const, string interpolation, and much more got deprecated.&lt;/p&gt;

&lt;p&gt;What also went away is the &lt;code&gt;baseUrl&lt;/code&gt; property in the &lt;code&gt;tsconfig.json&lt;/code&gt; file, support for the module systems amd, umd, and systemjs (not sure if our younger colleagues still know what that is) has also gone. You can of course also revert those deprecations, but be aware that in TypeScript 7, that means game over.&lt;/p&gt;

&lt;p&gt;There is an automatic migration tool available, which is marked as experimental.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://devblogs.microsoft.com/typescript/announcing-typescript-6-0/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdevblogs.microsoft.com%2Ftypescript%2Fwp-content%2Fuploads%2Fsites%2F11%2F2026%2F03%2Fts-6.0-2.png" height="350" class="m-0" width="562"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://devblogs.microsoft.com/typescript/announcing-typescript-6-0/" rel="noopener noreferrer" class="c-link"&gt;
            Announcing TypeScript 6.0 - TypeScript
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            TypeScript 6.0 is now available! TypeScript 6 is a stepping-stone release, aligning with the upcoming native-speed 7.0 release.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdevblogs.microsoft.com%2Ftypescript%2Fwp-content%2Fuploads%2Fsites%2F11%2F2018%2F10%2FMicrosoft-Favicon.png" width="18" height="18"&gt;
          devblogs.microsoft.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;There are also new features, and the most prominent one is the introduction of the Temporal API.&lt;/p&gt;

&lt;p&gt;This is a new, built-in date and time API in JavaScript, which can be seen as a full replacement for the old Date object. As that, it provides way more functionality for example handling timezones, a calendar which can be used to reflect Chinese or other calendar systems, immutability and a range of utility functions.&lt;/p&gt;

&lt;p&gt;Some veterans of us might remember the switch to the Date-time API in Java more than 10 years ago. It kind of did the same thing.&lt;/p&gt;

&lt;p&gt;Temporal API has reached stage 4 of the TC39 process, which means it is standardized, finished. That doesn't mean that each platform supports it. The latest version of Chrome, Firefox supports it, but not Safari and also Node.js which means if you use it, you should secure your code with polyfills.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://www.typescriptlang.org/play/?target=99&amp;amp;amp;jsx=0&amp;amp;amp;ssl=5&amp;amp;amp;ssc=46&amp;amp;amp;pln=1&amp;amp;amp;pc=1#code/MYewdgzgLgBFIBMCGBPGBeGAVApgWwAcQAnJAGwDoA5EAdwoLKQEswARJKHASQGUB5ABQBKANwAoUJFjQkxKPwBmATRxyMcRKgq1mUABaCA3jDzgDALhgBGADQxkKK9ZgBfMZPDQHzRYo2y8kqqchQArmBQzGSC8I4enpAgZDgUZCAA5oIABgAkRgi+ihSOEK4OqBAw+kgAbjgwBEgQEDgI2WJAA" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;typescriptlang.org&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plainDateISO&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startOfYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;today&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;startOfYear&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;today&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; days have passed`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  NgRx RFCs
&lt;/h2&gt;

&lt;p&gt;NgRx is the most used library for state management in Angular and official work has begun on supporting resources but also forms. Two RFCs for that have landed.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;delegatedSignal()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The first RFC is related to supporting Signal Forms and it introduces a new Signal type called &lt;code&gt;delegatedSignal&lt;/code&gt;. To the outside it is a writable Signal, but it doesn't store a value. Instead it writes and reads to another Signal. What's the use of it?&lt;/p&gt;

&lt;p&gt;Let's say we have a user object in a Signal, that has two nested properties: &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;address&lt;/code&gt;. &lt;code&gt;name&lt;/code&gt; has &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt;, and &lt;code&gt;address&lt;/code&gt; has &lt;code&gt;street&lt;/code&gt; and &lt;code&gt;city&lt;/code&gt;, like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123 Main St&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Anytown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If we have a form, which requires a flattened version of the user object, we would usually create a &lt;code&gt;linkedSignal&lt;/code&gt;. The problem is that changes in the form might be synchronized back to the original Signal. At the moment, the only way would be to use an &lt;code&gt;effect&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;``&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserPage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Main Street&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;London&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;userFormModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;linkedSignal&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;street&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt;

  &lt;span class="nx"&gt;userForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userFormModel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;syncEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;street&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;userFormModel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;street&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;delegatedSignal&lt;/code&gt; solves this problem by writing synchronously back to the original Signal.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PROTOTYPE!!!&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;delegatedSignal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;computation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;WritableSignal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;delegated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;linkedSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;computation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;delegated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;delegated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;updateFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateFn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;delegated&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;delegated&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;``&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserPage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Main Street&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;London&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;userFormModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;delegatedSignal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;computation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; 
        &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;street&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;street&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;street&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastname&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;street&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;userForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userFormModel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;delegatedSignal&lt;/code&gt; can be used for different use cases. Not just forms. Regarding the SignalStore, you could connect a Signal Form and a SignalStore together, where each change in the form is directly written to the SignalStore.&lt;/p&gt;

&lt;p&gt;You can see the &lt;code&gt;delegatedSignal&lt;/code&gt; as a &lt;code&gt;linkedSignal&lt;/code&gt; which doesn't create a clone, but just writes directly back to the original Signal. &lt;code&gt;delegatedSignal&lt;/code&gt; exists already in the Angular framework (slightly differently as &lt;code&gt;deepSignal&lt;/code&gt;), but is not exposed publicly. Angular uses it for the Signal Forms:&lt;br&gt;
&lt;a href="https://github.com/angular/angular/blob/394ad0c2a26eec8a8f7136b1b7971420b30a117e/packages/forms/signals/src/util/deep_signal.ts#L21" rel="noopener noreferrer"&gt;https://github.com/angular/angular/blob/394ad0c2a26eec8a8f7136b1b7971420b30a117e/packages/forms/signals/src/util/deep_signal.ts#L21&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ngrx/platform/issues/5121" rel="noopener noreferrer"&gt;ngrx/platform#5121 — RFC delegatedSignal&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Resource Extensions
&lt;/h3&gt;

&lt;p&gt;And the second RFC is related to resources. It allows to extend the resources which goes beyond the possibilities of the current &lt;code&gt;snapshot&lt;/code&gt; function. For example, an extension would change the behavior of a resource in an error state, where an access to the value does not throw. Custom extensions are possible as well and there is even the option to define default extensions.&lt;/p&gt;

&lt;p&gt;All two issues were created by &lt;a class="mentioned-user" href="https://dev.to/markostanimirovic"&gt;@markostanimirovic&lt;/a&gt; and if the same Marko was also guest at a previous episode of the Angular Plus show. So if you are interested to hear more about state management and SignalStore specifically, you should check out the episode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ngrx/platform/issues/5126" rel="noopener noreferrer"&gt;ngrx/platform#5126 — RFC resource extensions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/hBOwrpnUDds"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;
&lt;h2&gt;
  
  
  Martina Kraus on security (Angular Plus Show)
&lt;/h2&gt;

&lt;p&gt;In other news, the Angular Plus Show also had Martina Kraus as guest, which usually means the topic is about security.&lt;/p&gt;

&lt;p&gt;Together with the three hosts, Lara Newsom, Brooke Avery, and Jan-Niklas Wortmann, they discussed a whole portfolio of security. Be it trusted types, Sanitization, attacks like XSS and CSRF, but also content policies and the increased risk that comes with AI.&lt;/p&gt;

&lt;p&gt;At the end, Martina gave some tips where to start with security and she also highlighted the OWASP juice shop, which is written in Angular and is a playground to try out different vulnerabilities.&lt;/p&gt;

&lt;p&gt;And by the way, you should not store your access token in local storage.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/kyxF0Kk3WEQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://owasp.org/www-project-juice-shop/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fowasp.org%2Fwww--site-theme%2Ffavicon.ico" height="64" class="m-0" width="64"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://owasp.org/www-project-juice-shop/" rel="noopener noreferrer" class="c-link"&gt;
            OWASP Juice Shop | OWASP Foundation
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Probably the most modern and sophisticated insecure web application for security trainings, awareness demos and CTFs. Also great voluntary guinea pig for your security tools and DevSecOps pipelines!
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fowasp.org%2Fwww--site-theme%2Ffavicon.ico" width="64" height="64"&gt;
          owasp.org
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Form validation: debouncing async validators
&lt;/h2&gt;

&lt;p&gt;And we have a third debounce option in Angular. For Signal Forms, there is a &lt;code&gt;debounce&lt;/code&gt; function, which debounces the synchronization of a form field with the underlying model. The second is a &lt;code&gt;debounced&lt;/code&gt; function, scheduled for Angular 22 and is meant for any Signal type out there. The new one, is debouncing for asynchronous validators in Signal Forms. That allows you to have "undebounced" synchronous validators, but debouncing an asynchronous validator.&lt;/p&gt;

&lt;p&gt;That feature has been merged into the 22 version branch, but didn't make it into the latest 21.2.7 version. So it seems, we have to wait for Angular 22.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/commit/24e52d450d201e3da90bb64f84358f9eccd7877d" rel="noopener noreferrer"&gt;angular/angular@24e52d4 — debounce on validateAsync / validateHttp&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Alfredo Perez: SpecKit and SpecKit Companion
&lt;/h2&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/alfredoperez"&gt;@alfredoperez&lt;/a&gt; published a three-article series about a Spec-driven development process with AI. The most prominent tool in that spectrum is GitHub's SpecKit, which Alfredo describes. Additionally, he has created a VSCode extension, called SpecKit Companion, not just to visualize but also to edit and execute that specification.&lt;/p&gt;

&lt;p&gt;Since GitHub's SpecKit is not the only tool out there, Alfredo also shows alternatives and how SpecKit Companion can be configured to support those tools as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/ngconf/speckit-companion-e4fc99d1e061" rel="noopener noreferrer"&gt;https://medium.com/ngconf/speckit-companion-e4fc99d1e061&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/ngconf/custom-workflows-in-speckit-companion-266fda3b5eec" rel="noopener noreferrer"&gt;https://medium.com/ngconf/custom-workflows-in-speckit-companion-266fda3b5eec&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/ngconf/build-your-own-sdd-workflow-daa3fc1ae673" rel="noopener noreferrer"&gt;https://medium.com/ngconf/build-your-own-sdd-workflow-daa3fc1ae673&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=alfredoperez.speckit-companion" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=alfredoperez.speckit-companion&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Graz Meetup videos
&lt;/h2&gt;

&lt;p&gt;Finally, the recordings of the Angular Graz Meetup are available on YouTube. They are published not at once but in a regular interval.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/o0FK5ZORAv4"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ngrx</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Ng-News 26/10: Signality, Vitest 4.1, Angular Skills</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Fri, 27 Mar 2026 18:56:51 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2610-signality-vitest-41-angular-skills-19m3</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2610-signality-vitest-41-angular-skills-19m3</guid>
      <description>&lt;p&gt;This week's ng-news covers ngxtension on Angular Space, Signality's signal-first utilities inspired by VueUse, and Vitest 4.1 fake-timer improvements for Angular tests. We also look at official Angular agent skills.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/uxGi4DzkL5Q"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Space and ngxtension
&lt;/h2&gt;

&lt;p&gt;ngxtension, a set of utility functions, was the topic on the Angular Space live stream. The hosts were - as always - Armen Vardanyan and Enea Jahollari, the maintainer of ngxtension; Enea joined the stream after a few minutes.&lt;/p&gt;

&lt;p&gt;They discussed several main features. For example, &lt;code&gt;injectParams&lt;/code&gt;, which a former episode of ng-news covered already, and the &lt;code&gt;on&lt;/code&gt; helper, which offers strong developer experience for explicit effects but can also be used for explicit signal tracking in &lt;code&gt;computed&lt;/code&gt;, resources, or &lt;code&gt;linkedSignal&lt;/code&gt;.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://ngxtension.dev/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;ngxtension.dev&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/618dOf9jeew"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Signality
&lt;/h2&gt;

&lt;p&gt;Another promising library that offers utility functions - this time only signal-based - was published. Signality is its name, and according to its author, Vyacheslav Borodin, it is heavily inspired by VueUse, a popular library of utilities for Vue.js. Although Signality was released at version 0.1, the number of functions is already quite impressive.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://signality.dev/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsignality.dev%2Fog-image.png" height="400" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://signality.dev/" rel="noopener noreferrer" class="c-link"&gt;
            Getting started | Signality
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Comprehensive library of signal-first utilities for Angular. SSR-ready, type-safe, and designed for seamless reactive composition and DI-interop.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsignality.dev%2Ffavicon-32x32.png" width="32" height="32"&gt;
          signality.dev
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Vitest 4.1 fake timers
&lt;/h2&gt;

&lt;p&gt;Vitest, Angular's default testing framework for new projects, was released in version 4.1 and gained a major improvement in handling asynchronous timers. Fake timers gained an automatic tick mode.&lt;/p&gt;

&lt;p&gt;In the past, when code used a delayed timer - for example because of &lt;code&gt;debounceTime&lt;/code&gt; - you often had to advance those timers manually in tests. Now there is a mode that advances scheduled timers asynchronously without you hard-coding each delay. You no longer need to remember whether it was 100 ms, 200 ms, or something else. It does not remove asynchronicity, but it runs the deferred work on a short tick - roughly speaking, along the lines of &lt;code&gt;setTimeout(() =&amp;gt; void true, 0)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/younesjd"&gt;@younesjd&lt;/a&gt; added a section about that feature to his cookbook, and the Vitest documentation has more detail.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://main.vitest.dev/api/vi.html#vi-settimertickmode" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvitest.dev%2Fog.jpg" height="420" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://main.vitest.dev/api/vi.html#vi-settimertickmode" rel="noopener noreferrer" class="c-link"&gt;
            Vi | Vitest
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Next generation testing framework powered by Vite
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmain.vitest.dev%2Ffavicon.ico" width="64" height="64"&gt;
          main.vitest.dev
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://cookbook.marmicode.io/angular/testing/controlling-time-in-tests#fake-timers-in-fast-forward-mode" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcookbook.marmicode.io%2Fimg%2Fsocial-card.png" height="418" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://cookbook.marmicode.io/angular/testing/controlling-time-in-tests#fake-timers-in-fast-forward-mode" rel="noopener noreferrer" class="c-link"&gt;
            Controlling Time in Tests | Marmicode Cookbook
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Understand why time-based behavior is challenging to test and how fake timers and dynamic timing configuration address different scenarios.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcookbook.marmicode.io%2Fimg%2Ffavicon.png" width="64" height="64"&gt;
          cookbook.marmicode.io
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Official Angular agent skills
&lt;/h2&gt;

&lt;p&gt;Official Angular skills have landed. You can install them now with &lt;code&gt;npx skills add angular/skills&lt;/code&gt;. After that, your agent should pick them up whenever the LLM decides to use them.&lt;/p&gt;

&lt;p&gt;Skills are text content that explains to the LLM - for example, how Signal Forms work or how Angular's dependency injection works. The main distinction from MCP servers, basic rules, custom instructions, or whatever term your agent uses, is that skills are not loaded automatically up front. A skill starts with a short description of what it covers, which does not overload context, and - as noted above - when the LLM decides it is time to use one, it can load the full body on demand.&lt;/p&gt;

&lt;p&gt;That pattern lets you keep many skills available without bloating every prompt.&lt;/p&gt;

&lt;p&gt;Angular skills are not new. Ng-News already covered the Analog.js skills, which were created in January. As their author Brandon Roberts confirmed, now that official Angular skills exist, the Analog.js skills are deprecated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/skills" rel="noopener noreferrer"&gt;angular/skills (GitHub)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2036184874898321635-415" src="https://platform.twitter.com/embed/Tweet.html?id=2036184874898321635"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2036184874898321635-415');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2036184874898321635&amp;amp;theme=dark"
  }



&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>vitest</category>
      <category>ai</category>
    </item>
    <item>
      <title>Ng-News 26/09: AI &amp; Angular, debounced() in v22, Oxidation Compiler in Analog</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Thu, 19 Mar 2026 20:43:38 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2609-ai-angular-debounced-in-v22-oxidation-compiler-in-analog-4n3</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2609-ai-angular-debounced-in-v22-oxidation-compiler-in-analog-4n3</guid>
      <description>&lt;p&gt;Ng-News 26-09 features three topics: the new Signal-based &lt;code&gt;debounced&lt;/code&gt; API,  the Oxidation compiler benchmark in Analog.js, and AI &amp;amp; Angular.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/SwBswq2ZDHY"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular XSS Advisory
&lt;/h2&gt;

&lt;p&gt;A Cross-Site Scripting (XSS) vulnerability was discovered in Angular. If you use Angular i18n and apply it to HTML attributes, their values are not sanitized. The fix was applied to the supported versions Angular 19, 20, and 21.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/security/advisories/GHSA-g93w-mfhg-p222" rel="noopener noreferrer"&gt;Angular security advisory (GitHub)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ng-Asia with Mark Thompson
&lt;/h2&gt;

&lt;p&gt;Mark Thompson, Angular DevRel, was guest at Ng-Asia hosted by Ilyoskhuja Ikromkhujaev. The session was a mix between presentation and Q&amp;amp;A.&lt;/p&gt;

&lt;p&gt;For example, Mark presented his view on how AI will shape the way development will work for us. He doesn't expect a replacement a software developers, but - as many people would agree - a shift in terms of activities/competencies.&lt;/p&gt;

&lt;p&gt;He also explained what AI means for future applications, where the UI is highly responsive and can be seen as just another AI tool, instrumented by an LLM. There are libraries that support that use case already, like HashBrown.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/fSDFuoazXeE"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Q&amp;amp;A with Mark Thompson
&lt;/h2&gt;

&lt;p&gt;Mark Thompson also hosted the monthly Angular Q&amp;amp;A session. His guest was Alan from the Angular team and the main topic was AI - specifically Angular's MCP server combined with Chrome's MCP server. MCP allows LLMs to perform actions, not just return text. Angular's MCP server provides up-to-date documentation on best practices, can help migrate to zoneless, or act as a tutor. Together with Chrome's MCP server, it allows the LLM to verify its generated code automatically and fix it.&lt;/p&gt;

&lt;p&gt;Two answers stood out. First, a nice analogy on how skills and MCP tools differentiate. According to Mark, a tool's execution is more deterministic, whereas a skill is still text, which needs to be processed by the LLM, and could therefore cause non-deterministic, but better or different results, than an MCP tool's author could achieve.&lt;/p&gt;

&lt;p&gt;He compared it with playing a piece of music on a guitar. In the case of an MCP tool and if the LLM would be an artist, then the LLM would play a piece always in the same way - without even knowing how or what it is doing.&lt;br&gt;
In the context of a skill, it would learn how to play the guitar and could probably identify certain things that the tool would have oversawn.&lt;br&gt;
For example Mark mentioned, that there could a first part of a piece, which the tool was not aware of, but the skill would cover it.&lt;/p&gt;

&lt;p&gt;Second, why is Angular investing so much in AI? According to Mark, if you have a framework without AI support, many developers will say that it is not ready for the future and will switch to others. Given AI's omnipresence, having an AI-ready framework is a reasonable choice. &lt;/p&gt;

&lt;p&gt;Timestamp 41:20.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/G7GYQEcUbNA"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Oxidation Compiler and Analog
&lt;/h2&gt;

&lt;p&gt;As mentioned in a previous episode, there is an experimental Angular compiler, which is developed by Void Zero and is called the Oxidation compiler (Oxc).&lt;br&gt;
The interesting thing is that it is written in Rust, and not in Go, which is the language of choice for the upcoming official TypeScript rewrite.&lt;/p&gt;

&lt;p&gt;Brandon Roberts, who is well known in the Angular community, has integrated the Oxidation compiler into Analog.js, the most popular meta-framework for Angular, which supports building Angular with Vite. Brandon posted a benchmark stating that build time with Angular's esbuild dropped from 47 seconds to 1.5 seconds - a roughly 97% improvement.&lt;/p&gt;

&lt;p&gt;

&lt;iframe class="tweet-embed" id="tweet-2029653775330292103-98" src="https://platform.twitter.com/embed/Tweet.html?id=2029653775330292103"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2029653775330292103-98');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2029653775330292103&amp;amp;theme=dark"
  }





&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Roadmap Update
&lt;/h2&gt;

&lt;p&gt;Angular's roadmap got a major update, or one could say a reprioritization. In short, AI is king: topics like a new authoring format, streaming for server-side rendering, or improvements to the &lt;code&gt;TestBed&lt;/code&gt; were removed. That does not mean these topics will never be worked on, but they are deprioritized for now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/commit/53c1a1cee70753fc61fe0f7e115929e653fd5b82" rel="noopener noreferrer"&gt;Angular roadmap change (GitHub commit)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular NPM Downloads
&lt;/h2&gt;

&lt;p&gt;If you are a fan of download numbers: despite the results of the State of JavaScript survey, Angular appears to be in a strong position. In May 2025, weekly downloads exceeded 4 million for the first time. In the week of March 9th they were above 5 million - roughly a 25% increase within a year. For reference, Angular passed 3 million weekly downloads in February 2022.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://npmtrends.com/@angular/core" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnpmtrends.com%2Fimages%2Fnpm_trends_share_image.png" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://npmtrends.com/@angular/core" rel="noopener noreferrer" class="c-link"&gt;
            @angular/core | npm trends
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Comparing trends for @angular/core 21.2.6 which has 5,338,072 weekly downloads and 100,138 GitHub stars.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnpmtrends.com%2Ffavicon.ico"&gt;
          npmtrends.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  Debounced API
&lt;/h2&gt;

&lt;p&gt;Fatima Amzil published an article about a new Signal-based function called &lt;code&gt;debounced&lt;/code&gt;. Do not confuse it with the &lt;code&gt;debounce&lt;/code&gt; function in Signal Forms: that one is limited to Signal Forms and debounces the synchronization of a form field with the underlying model. The new &lt;code&gt;debounced&lt;/code&gt; is meant for any Signal - you can use it to debounce a resource's value, a computed, a linkedSignal, or a function that returns a value (which will be automatically tracked). The return value is not another Signal but a resource. &lt;code&gt;debounced&lt;/code&gt; is targeted for Angular 22.&lt;/p&gt;

&lt;p&gt;Michael Small also contributed a post on Bluesky with a GIF demonstrating the new function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://famzil.medium.com/angular-22-the-power-of-debound-and-debounced-apis-c41e33c0a18e" rel="noopener noreferrer"&gt;https://famzil.medium.com/angular-22-the-power-of-debound-and-debounced-apis-c41e33c0a18e&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;blockquote class="bluesky-embed"&gt;
&lt;p&gt;Just landed in the Angular nightly: debouncing signals. 

Photo of code snippet + link to PR in this thread

github.com/angular/angu...&lt;/p&gt;— &lt;a href="https://bsky.app/profile/did:plc:3jf7btbezgqcaxpdoru7zr2l?ref_src=embed" rel="noopener noreferrer"&gt;Michael Small (@michaelsmalldev.bsky.social)&lt;/a&gt; &lt;a href="https://bsky.app/profile/did:plc:3jf7btbezgqcaxpdoru7zr2l/post/3mgnuxoqkes2d?ref_src=embed" rel="noopener noreferrer"&gt;2026-03-09T22:14:51.079Z&lt;/a&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Angular Vienna and Code Magazine
&lt;/h2&gt;

&lt;p&gt;In other news, the Angular Vienna meetup took place and the recording of the live stream is available on YouTube. At the meetup, Dmytro Mezhenskyi from Decoded Frontends gave his first public talk. Other speakers were Matthieu Riegler from the Angular team on JavaScript in general and the upcoming changes in Angular due to the TypeScript rewrite in Go, Manfred Steyer on AI in Angular, and Daniel Szendrei on Angular hacks.&lt;/p&gt;

&lt;p&gt;Sonu Kapoor published an in-depth article on the evolution of Angular forms in Code Magazine. The article contains almost 15,000 words.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/ld3NCwBbWiQ"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://www.codemag.com/Article/264041/From-Template-Driven-to-Signal-Driven-The-Complete-Evolution-of-Angular-Forms" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fepsenterprise.blob.core.windows.net%2Fpermanent-files%2FFileAttachments%2Fe4008125_f5eb_45f2_8d9d_4302f88043b6%2F264041_Header_Rectangle.jpeg" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://www.codemag.com/Article/264041/From-Template-Driven-to-Signal-Driven-The-Complete-Evolution-of-Angular-Forms" rel="noopener noreferrer" class="c-link"&gt;
            From Template-Driven to Signal-Driven: The Complete Evolution of Angular Forms
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Sonu Kapoor's article, "From Template-Driven to Signal-Driven: The Complete Evolution of Angular Forms," provides a comprehensive exploration of Angular's evolving form APIs, tracing their journey ...
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codemag.com%2Fimages%2FCodeIcon.png"&gt;
          codemag.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




</description>
      <category>webdev</category>
      <category>angular</category>
      <category>frontend</category>
      <category>ai</category>
    </item>
    <item>
      <title>Vitest's 4.1 New "Fast-Forward" Mode Skips Timer Delays Instantly</title>
      <dc:creator>Younes Jaaidi</dc:creator>
      <pubDate>Wed, 18 Mar 2026 13:42:46 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/vitests-41-new-fast-forward-mode-skips-timer-delays-instantly-4a4h</link>
      <guid>https://dev.to/playfulprogramming-angular/vitests-41-new-fast-forward-mode-skips-timer-delays-instantly-4a4h</guid>
      <description>&lt;p&gt;An important property of tests is that they should be &lt;a href="https://cookbook.marmicode.io/angular/testing/glossary?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward#composable" rel="noopener noreferrer"&gt;composable&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example. Say you have a search component with a 300ms debounce. You've already tested the debounce behavior itself — "does it wait 300ms before firing?" — in a dedicated test. Now every other test that involves this component shouldn't care whether the debounce is there or not. Change the delay from 300ms to 500ms? Only the debounce test should break. Not the 15 other tests that just happen to type into that search field.&lt;/p&gt;

&lt;p&gt;Let's look at what this problem looks like, then at different approaches to solving it.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Challenge with Manual Fake Timers
&lt;/h1&gt;

&lt;p&gt;The classic approach of fake timers in manual mode breaks composability by coupling all the tests to the debounce.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useFakeTimers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;mountCookbookSearch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Keywords&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marmicode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;advanceTimersByTimeAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;310&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toHaveTextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Angular Testing Cookbook | Marmicode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test knows about the 300ms debounce &lt;em&gt;(note the 310ms — &lt;a href="https://cookbook.marmicode.io/angular/testing/controlling-time-in-tests?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward#time-is-not-a-precise-science" rel="noopener noreferrer"&gt;time is not a precise science&lt;/a&gt; 😉)&lt;/em&gt;. Change the debounce to 500ms and this test breaks — even though it's testing search results, not timing.&lt;br&gt;
You could use &lt;code&gt;vi.runAllTimersAsync()&lt;/code&gt; instead to flush all pending timers without specifying a duration. That's less coupled to the exact value, but the test still knows it needs to deal with timers at all. And manual mode freezes all timers — including framework internals like Angular's synchronization or React's scheduler fallbacks — which can require deep knowledge of framework internals just to get your test to run.&lt;/p&gt;

&lt;p&gt;Let's fix this.&lt;/p&gt;
&lt;h1&gt;
  
  
  Solution #1 — Real Time and Polling
&lt;/h1&gt;

&lt;p&gt;If you're using &lt;a href="https://cookbook.marmicode.io/angular/testing/vitest-browser-mode?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward" rel="noopener noreferrer"&gt;Vitest Browser Mode&lt;/a&gt;, DOM interactions using the &lt;code&gt;page&lt;/code&gt; API and assertions such as &lt;code&gt;expect.element&lt;/code&gt; poll. They respectively retry until the element is found or the assertion passes — or until the timeout is reached.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;mountCookbookSearch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Keywords&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marmicode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// This will keep retrying until the debounce hits and the&lt;/span&gt;
&lt;span class="c1"&gt;// "Angular Testing Cookbook" is the only cookbook remaining.&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toHaveTextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Angular Testing Cookbook | Marmicode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No fake timers. No manual time advancement. The test just waits for the heading to appear.&lt;/p&gt;

&lt;p&gt;This works, and it's composable but it has a cost: &lt;strong&gt;the test is as slow as the debounce&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution #2 — Dynamic Timing Configuration
&lt;/h1&gt;

&lt;p&gt;Another approach is to make the delay configurable and override it in tests. &lt;/p&gt;

&lt;p&gt;This is composable and fast. It's often the best approach when you control the code. I cover this pattern in detail in my &lt;a href="https://cookbook.marmicode.io/angular/testing/controlling-time-in-tests?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward" rel="noopener noreferrer"&gt;Controlling Time in Tests&lt;/a&gt; cookbook chapter.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution #3 — "Fast-Forward" Mode
&lt;/h1&gt;

&lt;p&gt;Vitest 4.1 introduces a way to control how fake timers automatically advance time &lt;code&gt;vi.setTimerTickMode('nextTimerAsync')&lt;/code&gt; — what I call "fast-forward" mode.&lt;br&gt;
Unlike manual fake timers where you have to call &lt;code&gt;vi.advanceTimersByTimeAsync(310)&lt;/code&gt; and know the delay, "fast-forward" mode advances the clock on its own, as quickly possible and as far as necessary. You don't need to know the delay value. You don't need to manually advance anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useFakeTimers&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;setTimerTickMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nextTimerAsync&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 👈&lt;/span&gt;

&lt;span class="nf"&gt;mountCookbookSearch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Keywords&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marmicode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toHaveTextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Angular Testing Cookbook | Marmicode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 300ms debounce is skipped instantly. Change it to 5 seconds — the test still passes in milliseconds. ✨&lt;/p&gt;

&lt;p&gt;It's composable (the test doesn't know about the delay), and it's fast (no real waiting).&lt;/p&gt;

&lt;p&gt;⚠️ Make sure you &lt;a href="https://cookbook.marmicode.io/angular/testing/controlling-time-in-tests?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward#restoring-real-timers" rel="noopener noreferrer"&gt;restore real timers&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Special thanks to Andrew and Vladimir
&lt;/h1&gt;

&lt;p&gt;"Fast-forward" mode exists thanks to &lt;a href="https://github.com/atscott" rel="noopener noreferrer"&gt;Andrew Scott&lt;/a&gt; from the Angular team — alongside &lt;a href="https://github.com/sheremet-va" rel="noopener noreferrer"&gt;Vladimir Sheremet&lt;/a&gt; from the Vitest team.&lt;/p&gt;

&lt;h1&gt;
  
  
  Going Deeper
&lt;/h1&gt;

&lt;p&gt;I cover the full decision tree — manual mode, "fast-forward" mode, dynamic timing configuration, and their trade-offs — in the &lt;a href="https://cookbook.marmicode.io/angular/testing/controlling-time-in-tests?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward" rel="noopener noreferrer"&gt;Controlling Time in Tests&lt;/a&gt; chapter of my Angular Testing Cookbook. Step-by-step recipes included. 👨🏻‍🍳&lt;/p&gt;




&lt;p&gt;I'm Younes Jaaidi, Angular GDE &amp;amp; Nx Champion. I help teams write tests that survive refactoring through a &lt;a href="https://courses.marmicode.io/courses/pragmatic-angular-testing?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward" rel="noopener noreferrer"&gt;video course&lt;/a&gt;, a &lt;a href="https://marmicode.io/workshops/pragmatic-angular-testing?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward" rel="noopener noreferrer"&gt;3-day hands-on workshop&lt;/a&gt;, and a &lt;a href="https://cookbook.marmicode.io?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=fast-forward" rel="noopener noreferrer"&gt;free cookbook&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>testing</category>
      <category>angular</category>
    </item>
    <item>
      <title>Angular Addicts #47: Angular 21.2, Skills, Signal Forms &amp; more</title>
      <dc:creator>Gergely Szerovay</dc:creator>
      <pubDate>Tue, 17 Mar 2026 08:53:47 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/angular-addicts-47-angular-212-skills-signal-forms-more-14jm</link>
      <guid>https://dev.to/playfulprogramming-angular/angular-addicts-47-angular-212-skills-signal-forms-more-14jm</guid>
      <description>&lt;h2&gt;
  
  
  👋Hey fellow Angular Addict
&lt;/h2&gt;

&lt;p&gt;This is the 47th issue of the Angular Addicts Newsletter, a monthly collection of carefully selected Angular resources that caught my attention. (Here are the &lt;a href="https://www.angularaddicts.com/p/angular-addicts-46-skills-signal-forms" rel="noopener noreferrer"&gt;46th&lt;/a&gt;, &lt;a href="https://www.angularaddicts.com/p/angular-addicts-44-angualr-21-signal-forms-vitest" rel="noopener noreferrer"&gt;45th&lt;/a&gt; and &lt;a href="https://www.angularaddicts.com/p/angular-addicts-44-angualr-21-signal-forms-vitest" rel="noopener noreferrer"&gt;44th&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  📢 Release announcements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://blog.ninja-squad.com/2026/02/26/what-is-new-angular-21.2" rel="noopener noreferrer"&gt;What's new in Angular 21.2?&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://x.com/cedric_exbrayat" rel="noopener noreferrer"&gt;Cédric Exbrayat&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤖 Angular AI skills, tools and development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://angular.love/agent-skills-in-claude-a-practical-guide-for-angular-developers" rel="noopener noreferrer"&gt;Agent Skills in Claude – A Practical Guide for Angular Developers&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://x.com/m_stefanczyk" rel="noopener noreferrer"&gt;Mateusz Stefańczyk&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://www.angulararchitects.io/en/blog/dynamic-reports-natural-lanaguage-queries-with-on-the-fly-code-generation/" rel="noopener noreferrer"&gt;Dynamic Reports: Natural Language Queries with On-the-Fly Code Generation&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://x.com/ManfredSteyer" rel="noopener noreferrer"&gt;Manfred Steyer&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://blog.mgechev.com/2026/02/26/skill-eval/" rel="noopener noreferrer"&gt;Unit Tests for AI Agent Skills&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://x.com/mgechev" rel="noopener noreferrer"&gt;Minko Gechev&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://medium.com/ngconf/angular-best-practices-for-ai-701bafdcda44" rel="noopener noreferrer"&gt;Angular Best Practices for AI&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://twitter.com/alfrodo_perez" rel="noopener noreferrer"&gt;Alfredo Perez&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💎Angular Gems of February, 2026
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://angularexperts.ch/blog/signal-forms-essentials" rel="noopener noreferrer"&gt;Angular Signal Forms Essentials&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://x.com/nivekcode" rel="noopener noreferrer"&gt;Kevin Kreuzer&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://push-based.io/article/goodbye-controlvalueaccessor-hello-signals" rel="noopener noreferrer"&gt;Goodbye ControlValueAccessor, Hello Signals-powered FormValueControl!&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://x.com/Enea_Jahollari" rel="noopener noreferrer"&gt;Enea Jahollari&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://medium.com/@borzifrancesco/how-to-migrate-your-angular-app-to-zoneless-9f9350040e19" rel="noopener noreferrer"&gt;How to migrate your Angular app to Zoneless&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://www.linkedin.com/in/francesco-borzi/" rel="noopener noreferrer"&gt;Francesco Borzì&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://dev.to/ujja/sunsetting-legacy-angular-how-were-migrating-to-nextjs-graphql-and-a-monorepo-without-a-big-1295"&gt;How We’re Surviving 600+ Legacy Angular Components While Migrating to Next.js, GraphQL, and a Monorepo&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By &lt;a href="https://github.com/ujjavala" rel="noopener noreferrer"&gt;ujja&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📰 &lt;a href="https://blog.angular.dev/security-advisory-addressing-recent-vulnerabilities-in-angular-c2656249b799" rel="noopener noreferrer"&gt;Security Advisory: Addressing Recent Vulnerabilities in Angular&lt;/a&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  👨‍💻About the author
&lt;/h2&gt;

&lt;p&gt;My name is &lt;a href="https://www.linkedin.com/in/gergelyszerovay/" rel="noopener noreferrer"&gt;Gergely Szerovay&lt;/a&gt;, I worked as a data scientist and full-stack developer for many years, and I have been working as frontend tech lead, focusing on Angular based frontend development. As part of my role, I'm constantly following how Angular and the frontend development scene in general is evolving. To share my knowledge, I started the &lt;a href="https://angularaddicts.com/" rel="noopener noreferrer"&gt;Angular Addicts&lt;/a&gt; monthly newsletter and publication in 2022, so that I can send you the best resources I come across each month. Whether you are a seasoned Angular Addict or a beginner, I got you covered. Let me know if you would like to be included as a writer. Let’s learn Angular together! &lt;a href="https://www.angularaddicts.com/" rel="noopener noreferrer"&gt;Subscribe here&lt;/a&gt; 🔥&lt;/p&gt;

&lt;p&gt;Angular has evolved very rapidly over the past few years, and in the past year, with the rise of generative AI, our software development workflows have also evolved rapidly. In order to closely follow the evolution of AI-assisted software development, I decided to start building AI tools in public, and publish my progress on &lt;a href="https://aiboosted.dev" rel="noopener noreferrer"&gt;AIBoosted.dev&lt;/a&gt;. Join my on this learning journey: &lt;a href="https://aiboosted.dev" rel="noopener noreferrer"&gt;Subscribe here&lt;/a&gt; 🚀&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://www.angularaddicts.com/" rel="noopener noreferrer"&gt;Substack (Angular Addicts)&lt;/a&gt;, &lt;a href="https://aiboosted.dev" rel="noopener noreferrer"&gt;Substack (AIBoosted.dev)&lt;/a&gt;, &lt;a href="https://medium.com/@GergelySzerovay" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;, &lt;a href="https://dev.to/gergelyszerovay"&gt;Dev.to&lt;/a&gt;, &lt;a href="https://twitter.com/GergelySzerovay" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/gergelyszerovay/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; to learn more about Angular, and how to build AI apps with AI, Typescript, React and Angular!&lt;/p&gt;

&lt;h2&gt;
  
  
  🕹️Previous issues
&lt;/h2&gt;

&lt;p&gt;If you missed the previous issues of the newsletter, you can read them &lt;a href="https://www.angularaddicts.com/t/angular-addicts-monthly" rel="noopener noreferrer"&gt;here&lt;/a&gt;, these are the latest 3 issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.angularaddicts.com/p/angular-addicts-46-skills-signal-forms" rel="noopener noreferrer"&gt;Angular Addicts #46: Angular 21.1, Skills, Signal Forms &amp;amp; more&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.angularaddicts.com/p/angular-addicts-44-angualr-21-signal-forms-vitest" rel="noopener noreferrer"&gt;Angular Addicts #45: Signal Form guides, AI integrations &amp;amp; more&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.angularaddicts.com/p/angular-addicts-44-angualr-21-signal-forms-vitest" rel="noopener noreferrer"&gt;Angular Addicts #44: Angular 21, Signal Forms, Vitest, Chat assistant integration &amp;amp; more&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📨 Submit your Angular resource
&lt;/h2&gt;

&lt;p&gt;Have you found or written an interesting Angular-related article, tweet or other resource lately? Please let me know here in the comments or send me a DM on &lt;a href="https://twitter.com/gergelyszerovay" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;! I might feature it in the next Angular Addicts issue!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Ng-News 26/08: Angular 21.2</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Thu, 12 Mar 2026 17:54:46 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2608-angular-212-223j</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2608-angular-212-223j</guid>
      <description>&lt;p&gt;The release of Angular 21.2 introduced several significant features - most notably for Signal Forms - while also delivering key enhancements across the broader framework.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/ILuVtpnWZNU"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;Angular 21.2 was released. According to the plan, that was the last minor release in the 21.x series. The next major release will be Angular 22 in May. According to schematic versioning, a minor brings only bug fixes and small features, but there is quite a lot in this release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signal Forms
&lt;/h2&gt;

&lt;p&gt;Signal Forms have picked up several useful features that round it out and suggest it is moving toward stability or developer preview.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Submission
&lt;/h3&gt;

&lt;p&gt;For example, the need to manually disable form submission is now handled in a simple way. You no longer have to wire this yourself: add the &lt;code&gt;formRoot&lt;/code&gt; directive to the form and it turns off the browser default submit behavior (e.g. full page reload).&lt;/p&gt;

&lt;p&gt;You configure the submit handler via the &lt;code&gt;submission&lt;/code&gt; option of the &lt;code&gt;form()&lt;/code&gt; function. That handler runs only when the user actually submits (e.g. Enter or the submit button) and when the form is not invalid.&lt;/p&gt;

&lt;p&gt;By default, that means submit can run even while asynchronous validators are still pending.&lt;/p&gt;

&lt;p&gt;While an async validator is running, it keeps &lt;code&gt;{invalid: false, valid: false}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Submit only happens if the &lt;code&gt;invalid&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, so pending validators do not block submission.&lt;/p&gt;

&lt;p&gt;You can change this with &lt;code&gt;ignoreValidators: 'none'&lt;/code&gt; if you want to wait until all validators, including async, have finished.&lt;/p&gt;

&lt;p&gt;The default is permissive because the server will validate again on submit anyway, so there is no need to wait for client-side async validators before allowing the request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bootstrapApplication&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FormRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;validateAsync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;validateStandardSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms/signals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormRoot&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;form [formRoot]="userForm"&amp;gt;
      &amp;lt;input [formField]="userForm.firstName" /&amp;gt;
      &amp;lt;input [formField]="userForm.lastName" /&amp;gt;
    &amp;lt;/form&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;bootstrapApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://stackblitz.com/edit/github-xuyek34y?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Code Example on Stackblitz&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Custom Control
&lt;/h3&gt;

&lt;p&gt;For custom controls, we now have the ability to use the &lt;code&gt;transformedValue&lt;/code&gt; utility for formatting and parsing.&lt;/p&gt;

&lt;p&gt;For example, it can be used for input fields with non-English number or date formats.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bootstrapApplication&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FormRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FormValueControl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;transformedValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms/signals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;JsonPipe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-german-number-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;p&amp;gt;&amp;lt;ng-content /&amp;gt;&amp;lt;/p&amp;gt;
      &amp;lt;input
        matInput
        [value]="rawValue()"
        (input)="rawValue.set($event.target.value)"
      /&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GermanNumberField&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;FormValueControl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;rawValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;transformedValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GermanNumberField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JsonPipe&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;form [formRoot]="userForm"&amp;gt;
    &amp;lt;app-german-number-field [formField]="userForm.heightInMeter"&amp;gt;Height in Meters&amp;lt;/app-german-number-field&amp;gt;
    {{user() | json}}
    &amp;lt;/form&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;heightInMeter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.75&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;bootstrapApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://stackblitz.com/edit/github-xuyek34y-fdnj2dgg?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Code Example on Stackblitz&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  SignalFormControl
&lt;/h3&gt;

&lt;p&gt;Although the improved form submission and the advanced features for custom controls are really great, most of us work with an existing Angular application.&lt;/p&gt;

&lt;p&gt;For us, the most important new feature is &lt;code&gt;SignalFormControl&lt;/code&gt;. It allows you to introduce a &lt;code&gt;FormControl&lt;/code&gt; into Reactive Forms that supports, for example, the advanced validation rules from Signal Forms.&lt;/p&gt;

&lt;p&gt;That makes the migration to Signal Forms much easier.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bootstrapApplication&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validateAsync&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms/signals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SignalFormControl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms/signals/compat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormBuilder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactiveFormsModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ReactiveFormsModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;form [formGroup]="userForm"&amp;gt;
      &amp;lt;input formControlName="email" /&amp;gt;
    &amp;lt;/form&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FormBuilder&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;nonNullable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SignalFormControl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user@host.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email is reqired&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="nf"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;validateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;networkError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;bootstrapApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://stackblitz.com/edit/github-xuyek34y-hwaqwg2v?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Code Example on Stackblitz&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;ResourceSnapshot&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The Resource Snapshot API was finally released. That is a feature that was expected to land in Angular 21 already; it was in the main branch but got reverted.&lt;/p&gt;

&lt;p&gt;In short, Resource Snapshots allow you to map one resource to another or use them for compositional tasks.&lt;/p&gt;

&lt;p&gt;The example given in the docs changes the default behavior of setting the value to undefined during loading to keeping the original value. In Angular's codebase, the snapshot is used for testing, where it acts as a convenient resource factory function. We will see what use cases are possible.&lt;/p&gt;

&lt;p&gt;The example below shows an error handler, which can be used to avoid the &lt;code&gt;error&lt;/code&gt; status.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bootstrapApplication&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;resourceFromSnapshots&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;JsonPipe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms/signals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;withErrorHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;errorHandler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;snap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;snap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resolved&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;errorHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;snap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;snap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;resourceFromSnapshots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FormRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JsonPipe&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;form [formRoot]="idForm"&amp;gt;
      &amp;lt;input [formField]="idForm.id" type="number"/&amp;gt;

      &amp;lt;pre&amp;gt;{{safeUser.value() | json}}&amp;lt;/pre&amp;gt;
      &amp;lt;pre&amp;gt;{{unsafeUser.value() | json}}&amp;lt;/pre&amp;gt;
    &amp;lt;/form&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;idForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

  &lt;span class="nx"&gt;unsafeUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no negative users ;)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;safeUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withErrorHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unsafeUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;bootstrapApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://stackblitz.com/edit/github-xuyek34y-ijamx4nz?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Code Example on Stackblitz&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  CLI - Prettier Integration
&lt;/h2&gt;

&lt;p&gt;As the CLI already provides full integration of Tailwind CSS, Angular 21 also integrates Prettier as a first-class citizen.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lambdas in Templates
&lt;/h2&gt;

&lt;p&gt;The syntax in the template, which is not native JavaScript, has been extended with two new features. We can now use lambda functions directly in templates.&lt;/p&gt;

&lt;p&gt;The favored use case is to call the update method on a signal.&lt;/p&gt;

&lt;p&gt;In general, logic should stay out of the template, so do not overuse this feature.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bootstrapApplication&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
  &amp;lt;p&amp;gt;Current Value: {{counter()}}&amp;lt;/p&amp;gt;
  &amp;lt;button (click)="counter.update((value) =&amp;gt; value + 1)"&amp;gt;Increment&amp;lt;/button&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;bootstrapApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://stackblitz.com/edit/github-xuyek34y-fcuywgfs?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Code Example on Stackblitz&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Exhaustive Checks
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;@switch&lt;/code&gt; statement now supports exhaustive checking: the compiler verifies that all possible cases are covered when you use &lt;code&gt;@default never&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bootstrapApplication&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;UserType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;anonymous&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
@switch(userType) {
  @case('anonymous') {
    &amp;lt;p&amp;gt;Welcome Visitor&amp;lt;/p&amp;gt;
  }
  @case('admin') {
    &amp;lt;p&amp;gt;Welcome admin&amp;lt;/p&amp;gt;
  }
  @default never;
}

  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;userType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;bootstrapApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://stackblitz.com/edit/github-xuyek34y-w7z7amxv?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Code Example on Stackblitz&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ChangeDetectionStrategy.Eager
&lt;/h2&gt;

&lt;p&gt;As already announced, &lt;code&gt;ChangeDetectionStrategy.Default&lt;/code&gt; was renamed to &lt;code&gt;ChangeDetectionStrategy.Eager&lt;/code&gt;. The reason is that in Angular 22, in May, the default will become &lt;code&gt;OnPush&lt;/code&gt;, and because it does not make sense to call the non-default option "default", its new name is Eager.&lt;/p&gt;

&lt;p&gt;You do not have to change anything. If you explicitly use &lt;code&gt;ChangeDetectionStrategy.Default&lt;/code&gt;, you can remove that setting or, even better, migrate to &lt;code&gt;OnPush&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You are not forced to change anything. When Angular 22 is released, the update scripts will explicitly set existing implicit or explicit components with &lt;code&gt;ChangeDetectionStrategy.Default&lt;/code&gt; to &lt;code&gt;ChangeDetectionStrategy.Eager&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sources and Thanks
&lt;/h2&gt;

&lt;p&gt;For further information, check out the official changelog and a big thanks to Cedric Exbrayat&lt;/p&gt;

&lt;p&gt;His article was the main source for this episode.&lt;/p&gt;

&lt;p&gt;Merci beaucoup Cedric!&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://blog.ninja-squad.com/2026/02/26/what-is-new-angular-21.2" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.ninja-squad.com%2Fimages%2Flogo.svg" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://blog.ninja-squad.com/2026/02/26/what-is-new-angular-21.2" rel="noopener noreferrer" class="c-link"&gt;
            What's new in Angular 21.2? - Ninja Squad
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Angular 21.2 is out!
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.ninja-squad.com%2Ffavicon.svg"&gt;
          blog.ninja-squad.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;&lt;a href="https://github.com/angular/angular/blob/main/CHANGELOG.md" rel="noopener noreferrer"&gt;Angular CHANGELOG (GitHub)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>programming</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Ng-News 26/07: Angular's Router, Vitest, Hashbrown, History &amp; Popularity</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Tue, 24 Feb 2026 23:24:05 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2607-angulars-router-vitest-hashbrown-history-popularity-4phc</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2607-angulars-router-vitest-hashbrown-history-popularity-4phc</guid>
      <description>&lt;p&gt;Andrew Scott on Angular's Router, Vitest with Younes Jaadi, Hashbrown and AI, State of JS and 100k stars, Maximilian's Angular retrospective, ngxtension 7.1 and ngDiagram 1.0.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/3oTeWPzVPtY"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Andrew Scott on Angular's Router
&lt;/h2&gt;

&lt;p&gt;Andrew Scott, member of the Angular team, was a guest on Armen Vardanyan's podcast at Angular Space, and they discussed a wide range of topics.&lt;/p&gt;

&lt;p&gt;They talked about a potential integration of resources into the router, where the router would know exactly what kind of data needs to be loaded and the loading could also be done in parallel. Right now we have a waterfall effect, where each segment with its resolvers needs to be loaded sequentially.&lt;/p&gt;

&lt;p&gt;On RxJS, it is still going to become optional in the future, but that does not have the highest priority at the moment.&lt;/p&gt;

&lt;p&gt;Another topic was the relationship between community libraries and Angular. For example, ngxtension has a lot of useful utility functions for the router, which would make sense to be part of the framework. Andrew meant that the framework should provide the building blocks and the community should build certain features on top of it.&lt;/p&gt;

&lt;p&gt;The TypeScript rewrite in Go was also discussed. A lot of the Angular team's time is currently going into preparing for that rewrite.&lt;/p&gt;

&lt;p&gt;Theoretically, a mixed approach might also be possible. Alex Rickabaugh, lead of the Angular framework, was not on the podcast, but he posted that they are looking into using Rust in some parts of Angular's compilation process.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/82GdyNLzXI4"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;

&lt;iframe class="tweet-embed" id="tweet-2024164838688379157-601" src="https://platform.twitter.com/embed/Tweet.html?id=2024164838688379157"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2024164838688379157-601');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2024164838688379157&amp;amp;theme=dark"
  }





&lt;/p&gt;

&lt;h2&gt;
  
  
  Younes Jaadi on Vitest
&lt;/h2&gt;

&lt;p&gt;Younes Jaadi posted a video about Vitest, which is Angular's default testing framework since Angular version 21.&lt;/p&gt;

&lt;p&gt;His main focus was on the so-called browser mode, which uses an E2E-style runner such as Playwright or WebdriverIO to interact with the DOM. He shared technical insights and pragmatic tips on how to use Vitest.&lt;/p&gt;

&lt;p&gt;Younes is highly respected in the Angular community and has been promoting Vitest in Angular before it became the official testing framework.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/Pu22JQG6jdg"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Manfred Steyer on Hashbrown and AI in Angular
&lt;/h2&gt;

&lt;p&gt;AI shows up in many places, including Angular, where it can generate dynamic components, accept prompts, and call tools on the fly. A prominent library for this is Hashbrown.&lt;/p&gt;

&lt;p&gt;Manfred Steyer has written a three-article series on the topic: basic setup, integrating a prompt, connecting with your application, and more advanced features such as dynamic components or letting Hashbrown execute code in the browser.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://www.angulararchitects.io/en/blog/dynamic-reports-natural-lanaguage-queries-with-on-the-fly-code-generation/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.angulararchitects.io%2Fwp-content%2Fuploads%2F2026%2F02%2Fsujet-2-1024x536.png" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://www.angulararchitects.io/en/blog/dynamic-reports-natural-lanaguage-queries-with-on-the-fly-code-generation/" rel="noopener noreferrer" class="c-link"&gt;
            Dynamic Reports: Natural Language Queries with On-the-Fly Code Generation - ANGULARarchitects
          &lt;/a&gt;
        &lt;/h2&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.angulararchitects.io%2Fwp-content%2Fuploads%2F2024%2F01%2Fcropped-2023_Angular_Architects_FavIcon-32x32.png"&gt;
          angulararchitects.io
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  State of JavaScript and Angular's popularity
&lt;/h2&gt;

&lt;p&gt;State of JavaScript released the results from last year. Angular saw a rise in 2024 in metrics around popularity and satisfaction, and a small decline in 2025, with some gap to 2023. The survey's sample is often said to be not representative, so the numbers may not reflect the broader population.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://stateofjs.com/en-US" rel="noopener noreferrer" class="c-link"&gt;
            State of JavaScript
          &lt;/a&gt;
        &lt;/h2&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
          stateofjs.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Angular's repository on GitHub has reached 100,000 stars. For comparison, React has about 240,000 and Vue about 53,000. Enea Jahollari posted about a Reddit thread on the webdev subreddit where someone asked if Angular is still used; as Enea put it, there were some good comments about Angular.&lt;/p&gt;

&lt;p&gt;

&lt;iframe class="tweet-embed" id="tweet-2024897592006422590-594" src="https://platform.twitter.com/embed/Tweet.html?id=2024897592006422590"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2024897592006422590-594');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2024897592006422590&amp;amp;theme=dark"
  }





&lt;/p&gt;

&lt;h2&gt;
  
  
  Maximilian Schwarzmüller – 10 Years of Angular
&lt;/h2&gt;

&lt;p&gt;Maximilian Schwarzmüller is a well-known name in Angular. His Udemy course has been the door opener for many Angular developers since 2016. He published a video titled "Looking back at 10 years of Angular - and into its future", covering the early days, milestones, and where we are now. If you want nostalgia or a brief overview of Angular's history, it's a good watch.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/7dqMSlv2jeA"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Also in the News
&lt;/h2&gt;

&lt;p&gt;Ngxtension 7.1 brought &lt;code&gt;injectParams.global()&lt;/code&gt;, which gives you one signal with all the parameters of the current route hierarchy.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://ngxtension.dev/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;ngxtension.dev&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;ngDiagram had its first stable release with version 1. It has zero dependencies, is based on modern Angular, and lets you create interactive diagrams. It looks very promising.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://www.ngdiagram.dev/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;ngdiagram.dev&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;If you use VS Code, check out the latest Angular VS Code extension; it includes some new goodies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/releases/tag/vsix-21.2.0/" rel="noopener noreferrer"&gt;https://github.com/angular/angular/releases/tag/vsix-21.2.0/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>programming</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Ng-News 26/05: OnPush as Default, Agent Skills, Q&amp;A</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Wed, 11 Feb 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2605-onpush-as-default-agent-skills-qa-glb</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2605-onpush-as-default-agent-skills-qa-glb</guid>
      <description>&lt;p&gt;Agent Skills are landing for Angular. This episode also covers the January Angular Q&amp;amp;A (Jeremy Elbourn leaving, markForCheck discussion, Dart's legacy) and Mark Thompson's RFC to make OnPush the default.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ufjAAQOC7rM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Skills landing in Analog first, and now in Angular
&lt;/h2&gt;

&lt;p&gt;The AI world continues to evolve, and things that were top notch yesterday are already outdated today. When it comes to teaching AI how to write proper and modern Angular code, the answer in 2025 was the Angular CLI's built-in MCP server. In 2026, the answer is Skills.&lt;/p&gt;

&lt;p&gt;With MCP, we have the issue that they overload the context size of the LLM, because the tools' manifest has to be loaded always. Skills, on the other hand, are lightweight. They are not loaded automatically - only a small amount of metadata. The whole content is only loaded once on demand, namely when the LLM decides that it is now time to use it.&lt;/p&gt;

&lt;p&gt;Skills, like MCP, were introduced by Anthropic, which stands behind Claude Code. They first introduced them in October last year and in December standardized them as Agent Skills. To use them, you usually need one of the common IDEs that are good at AI integration, and you are not limited to Claude's models; it also works with others like GPT or Gemini.&lt;/p&gt;

&lt;p&gt;Brandon Roberts posted that he added skills to Analog.js, which is a meta-framework for Angular. One week later, Angular reacted as well: Mark Thompson confirmed and created a PR so that Skills land officially in Angular.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2014895426088919431-979" src="https://platform.twitter.com/embed/Tweet.html?id=2014895426088919431"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2014895426088919431-979');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2014895426088919431&amp;amp;theme=dark"
  }



&lt;br&gt;
&lt;a href="https://github.com/angular/angular/pull/66834" rel="noopener noreferrer"&gt;Angular PR #66834&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://claude.com/blog/equipping-agents-for-the-real-world-with-agent-skills" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;claude.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://agentskills.io/home" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fagent-skills.mintlify.app%2Fmintlify-assets%2F_next%2Fimage%3Furl%3D%252F_mintlify%252Fapi%252Fog%253Fdivision%253DDocumentation%2526title%253DOverview%2526description%253DA%252Bsimple%25252C%252Bopen%252Bformat%252Bfor%252Bgiving%252Bagents%252Bnew%252Bcapabilities%252Band%252Bexpertise.%2526primaryColor%253D%2525237f7f7f%2526lightColor%253D%252523bfbfbf%2526darkColor%253D%252523404040%2526backgroundLight%253D%252523ffffff%2526backgroundDark%253D%2525230d0d0f%26w%3D1200%26q%3D100" height="630" class="m-0" width="1200"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://agentskills.io/home" rel="noopener noreferrer" class="c-link"&gt;
            Overview - Agent Skills
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            A simple, open format for giving agents new capabilities and expertise.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fagentskills.io%2Fmintlify-assets%2F_mintlify%2Ffavicons%2Fagent-skills%2FxaP4f19bjp9SO_87%2F_generated%2Ffavicon%2Ffavicon-16x16.png" width="16" height="16"&gt;
          agentskills.io
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Angular Q&amp;amp;A with the Angular team
&lt;/h2&gt;

&lt;p&gt;We had the January Angular Q&amp;amp;A with the Angular team. As usual, Mark Thompson and Jeremy Elbourn were there, but this time they were joined by Doug Parker, the lead of the Angular CLI team. Unfortunately, it was also the last appearance of Jeremy Elbourn. He announced that he is leaving Google already in February. Jeremy Elbourn is the current Angular uber lead, which means he presides over the Angular projects - Material, framework, and the CLI. A successor has not been announced yet.&lt;/p&gt;

&lt;p&gt;A very interesting side note: Jeremy was discussing the behavior of markForCheck on event listeners. So at the moment, a handled DOM event triggers change detection, and there was an internal discussion about changing that. The outcome was not to do it now, but to integrate that change once the "legendary" Signal Components come out. Signal Components were announced as a requirement for zoneless and were planned to land in Angular 17. But in the end, zoneless could be done without those kinds of changes, and Signal Components lost in terms of priority.&lt;/p&gt;

&lt;p&gt;Using Dart in Angular had some negative consequences. It was there in the beginning but did not have the best impact on Angular's API. For example, Dart does not have types for DOM elements, and that's why &lt;code&gt;nativeElement&lt;/code&gt; is &lt;code&gt;any&lt;/code&gt;. Dart also does not have &lt;code&gt;undefined&lt;/code&gt;, and that's why &lt;code&gt;null&lt;/code&gt; shows up often in the older API.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/bAaW9Ew5Pwo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  ChangeDetection OnPush should become the default for Angular
&lt;/h2&gt;

&lt;p&gt;Mark Thompson has published an RFC to set Angular's default change detection strategy to OnPush. The current one is called Default - probably not the best name.&lt;/p&gt;

&lt;p&gt;OnPush means that when Angular synchronizes the state of our application with the DOM, a component under OnPush has to be marked as dirty in order to be checked for actual change. That dirty marking only happens if you have a handled user event, run markForCheck manually, use the async pipe, or - of course - if a Signal changes. A component that is not dirty also excludes its children from the change detection process.&lt;/p&gt;

&lt;p&gt;Since Default is not the best name, it will get an alias called Eager, and that is already going to happen in Angular 21.2, which will be released later this month. The actual switch to OnPush as the default will happen in Angular 22.&lt;/p&gt;

&lt;p&gt;As always, existing codebases will not be modified - safety first. As it was when standalone became the default, existing apps will get the explicit setting to ChangeDetectionStrategy.Eager (aka Default) via automatic migration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/discussions/66779" rel="noopener noreferrer"&gt;RFC Discussion #66779&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>angular</category>
      <category>programming</category>
    </item>
    <item>
      <title>Ng-News 26/04: Micro Frontends at Google</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Sun, 08 Feb 2026 23:38:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2604-micro-frontends-at-google-13ch</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2604-micro-frontends-at-google-13ch</guid>
      <description>&lt;p&gt;Doug Parker from the Angular team shared insights on Micro Frontends at Google — isolation, Protocol Buffers, and when to avoid the approach. This episode also covers the TypeScript Go rewrite progress, and Angular DevTools Signal Graph updates.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/OF3QHLUPvEw"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Micro Frontends at Google
&lt;/h2&gt;

&lt;p&gt;Doug Parker was a guest at the Angular Meetup Graz, which was this time more a podcast. Doug is a member of the Angular team, focuses on the CLI, and talked about Micro Frontends at Google.&lt;/p&gt;

&lt;p&gt;A little bit of context. Google has a monorepo, which means all applications are within one repository. That does not mean they use Micro Frontend architectures. In fact, there has been some information (also on ng-news) where we shared the Micro Frontend approach of Google's Cloud Console, which is based on a huge micro frontend architecture using an iFrame approach, which is not used anymore.&lt;/p&gt;

&lt;p&gt;Instead, the new concept is to do Micro Frontends in complete isolation. In order to avoid collisions with shared dependencies, Google plays it safe. They do not share anything at all. So a very autonomous solution. When it comes to shared logic, they use Protocol Buffers, where a service is not really shared between micro frontends but more a messaging infrastructure. Another requirement is that they have the need to combine multiple frameworks together.&lt;/p&gt;

&lt;p&gt;Doug's approach is to see Micro Frontends as a contract between apps. In the end, there is an interface that needs to be implemented and the infrastructure takes care of the integration.&lt;/p&gt;

&lt;p&gt;There are no plans to open source the solution once it is finished.&lt;/p&gt;

&lt;p&gt;When should Micro Frontends be used? Whenever the underlying problem could be solved in a different way, then try out that approach before Micro Frontends. For example build times could be improved in different ways.&lt;/p&gt;

&lt;p&gt;If there are hard UX requirements, a micro-frontend approach might be hard to implement.&lt;/p&gt;

&lt;p&gt;Lastly, very often Micro Frontends are used to reduce the communication between teams. One has to ask first, if this is actually the goal, or if the opposite approach, namely, where people need to talk with each other more, should be achieved.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/mOcpu6aZocs"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Status Update on Go Rewrite of TypeScript
&lt;/h2&gt;

&lt;p&gt;Last year, TypeScript announced that they are going to rewrite the compiler in Go, which should bring performance improvements that might be an order of magnitude, so about 10 times.&lt;/p&gt;

&lt;p&gt;This undertaking takes some time and consumes obviously all the resources of the team. Push-based posted about the current state. We are coming closer and the upcoming version of TypeScript 6.0 will be the last one written in TypeScript.&lt;/p&gt;

&lt;p&gt;The Angular team follows and has already started to make their codebase ready for v6 as well.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://www.linkedin.com/posts/push-based_angular-typescript-js-activity-7417946368138358784-yhU6/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.licdn.com%2Fdms%2Fimage%2Fv2%2FD4D10AQGVLDyDhY-s4g%2Fimage-shrink_800%2FB4DZvHW1zXHYAg-%2F0%2F1768576212787%3Fe%3D2147483647%26v%3Dbeta%26t%3DsUoq7Py492jsT4jP1zou3dgr7vu2NjW0FBVxUc9XKeI" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://www.linkedin.com/posts/push-based_angular-typescript-js-activity-7417946368138358784-yhU6/" rel="noopener noreferrer" class="c-link"&gt;
            #angular #typescript #js | PushBased
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            TypeScript is changing forever! 

v6.0 will be the last JS-based release before the complete native Go rewrite in v7.0. TS Team is officially transitioning v6.0 into "Maintenance Mode" to focus on the port.

🔥 Major Breaking Changes to prepare for:
- Strict by Default: 𝘀𝘁𝗿𝗶𝗰𝘁: 𝘁𝗿𝘂𝗲 is finally the default.
- No More Legacy Modules: Support for 𝗮𝗺𝗱, 𝘂𝗺𝗱, and 𝘀𝘆𝘀𝘁𝗲𝗺𝗷𝘀 is being removed.
- Modern Targets: 𝘁𝗮𝗿𝗴𝗲𝘁 defaults to 𝗲𝘀&amp;lt;𝗰𝘂𝗿𝗿𝗲𝗻𝘁 𝘆𝗲𝗮𝗿&amp;gt; (Evergreen).
- Faster Builds: 𝘁𝘆𝗽𝗲𝘀 defaults to [ ] (stops auto-including every @𝘁𝘆𝗽𝗲𝘀 package).
- Enum Merging: Removed.
- Side Effects: 𝗻𝗼𝗨𝗻𝗰𝗵𝗲𝗰𝗸𝗲𝗱𝗦𝗶𝗱𝗲𝗘𝗳𝗳𝗲𝗰𝘁𝗜𝗺𝗽𝗼𝗿𝘁𝘀 defaults to 𝘁𝗿𝘂𝗲.

The Goal? 
A 10x faster compiler, but it requires shedding legacy weight.

Links: 
- Maintenance Mode (TS #62963): https://buff.ly/BRBTweG
- Deprecation List (TS #54500): https://buff.ly/Tb7QyGl 

The Angular Team has started preparing for it too:
https://buff.ly/Tb5KSBS 

#angular #typescript #js
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.licdn.com%2Faero-v1%2Fsc%2Fh%2Fal2o9zrvru7aqj8e1x2rzsrca"&gt;
          linkedin.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;br&gt;
&lt;a href="https://github.com/angular/angular/pull/66578" rel="noopener noreferrer"&gt;Angular PR #66578&lt;/a&gt;
&lt;h2&gt;
  
  
  Miscellaneous
&lt;/h2&gt;

&lt;p&gt;The Angular DevTools provide a visualization of the Signal Graph. The latest version received an update and now gives a much better view on the resource, which in the end is a group of different Signals belonging together.&lt;/p&gt;

&lt;p&gt;

&lt;iframe class="tweet-embed" id="tweet-2015832104722911325-347" src="https://platform.twitter.com/embed/Tweet.html?id=2015832104722911325"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2015832104722911325-347');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2015832104722911325&amp;amp;theme=dark"
  }





&lt;/p&gt;

&lt;h2&gt;
  
  
  New Conferences
&lt;/h2&gt;

&lt;p&gt;Last but not least, ticket sales for Ng-India, India's largest Angular conference, have started.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://www.ng-ind.com" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;ng-ind.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;And again, if you are organizing a conference, please reach out to us so that we can promote it here.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Ng-News: Angular 21.1</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Fri, 23 Jan 2026 20:36:23 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-angular-211-4ofe</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-angular-211-4ofe</guid>
      <description>&lt;p&gt;Angular 21.1 is out with a smaller set of updates, but there are still some useful changes to cover. This episode highlights Signal Forms updates, experimental router auto-cleanup, and template syntax extensions.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/hx3_pmfeHyI"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Signal Forms
&lt;/h2&gt;

&lt;p&gt;As Signal Forms are still experimental, breaking changes within a minor and even patch are allowed and do happen.&lt;/p&gt;

&lt;p&gt;Probably the most impactful change was that the Field directive was renamed to FormField. You now use &lt;code&gt;FormField&lt;/code&gt; and &lt;code&gt;[formField]&lt;/code&gt;, while &lt;code&gt;Field&lt;/code&gt; and &lt;code&gt;[field]&lt;/code&gt; were completely removed and are no longer available. &lt;/p&gt;

&lt;p&gt;Technically speaking, that change and most others didn't come with the minor release but already happened within patch releases of the 21.0 range.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-customer-registration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div&amp;gt;
      &amp;lt;mat-form-field&amp;gt;
        &amp;lt;input
          type="text"
          matInput
          [formField]="customerForm.firstname"
        /&amp;gt;
      &amp;lt;/mat-form-field&amp;gt;
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;MatFormFieldModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;MatInputModule&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomerRegistrationScreen&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;customerForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;First name is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Auto Cleanup for Router-Provided Services
&lt;/h2&gt;

&lt;p&gt;We usually provide a service in root, that means we have a singleton, so one instance throughout the whole application, or we can provide it locally. That is usually done within a component and that instance goes down with the component and it is only available within that component and its children.&lt;/p&gt;

&lt;p&gt;But there is also another option, namely to provide a service on the router level. Until now, that service was instantiated when users entered that route but did not get destroyed and it was also not available in another route. So kind of a mixture between global and local.&lt;/p&gt;

&lt;p&gt;Angular 21.1 brings a new experimental router option for these services that auto-cleans route injectors, so the service behaves like one provided in a component and gets destroyed when users switch to a different route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;takeUntilDestroyed&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;h1&amp;gt;Counter&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Count: {{ count() }}&amp;lt;/p&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterPage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApplicationConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;provideRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CounterPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="nf"&gt;withExperimentalAutoCleanupInjectors&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Template Syntax Extensions
&lt;/h2&gt;

&lt;p&gt;Angular's template allows us to inline code which looks like JavaScript but isn't. That's why features that JavaScript has but are missing in the template have to be implemented explicitly.&lt;/p&gt;

&lt;p&gt;Angular 21.1 extends its "template syntax" with the possibility of multiple consecutive switch case statements and supports the three dots, better known as the spread and rest operator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;anonymous&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;member&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscriber&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;` &amp;lt;h2&amp;gt;Welcome&amp;lt;/h2&amp;gt;
    @switch (status()) {
      @case ('guest')
      @case ('anonymous') {
        &amp;lt;p&amp;gt;Please sign in&amp;lt;/p&amp;gt;
      }
    }`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Welcome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Miscellaneous
&lt;/h2&gt;

&lt;p&gt;Beyond the headline features, there are smaller improvements across the router and image-loading utilities. There are also reports of new MCP server tooling to better support running the dev server.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do We Continue
&lt;/h2&gt;

&lt;p&gt;As always, consult the changelog on GitHub and community write-ups for details and migration notes.&lt;/p&gt;

&lt;p&gt;The current public schedule suggests Angular 21.2 is planned for the week of February 23, with Angular 22 targeted for May and no further 21.x minors after that, but confirm in the official roadmap.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/angular/releases/tag/v21.1.0" rel="noopener noreferrer"&gt;Angular releases on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>angular</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Ng-News 26/02: Frameworks in 2026, Competition among Frameworks, Angular Inside</title>
      <dc:creator>ng-news</dc:creator>
      <pubDate>Tue, 20 Jan 2026 20:51:41 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/ng-news-2602-frameworks-in-2026-competition-among-frameworks-angular-inside-1jee</link>
      <guid>https://dev.to/playfulprogramming-angular/ng-news-2602-frameworks-in-2026-competition-among-frameworks-angular-inside-1jee</guid>
      <description>&lt;p&gt;This episode covers framework direction perspectives, a deep dive into Angular template type checking, and several community updates.&lt;/p&gt;

&lt;p&gt;📺 &lt;strong&gt;Watch the full episode on YouTube:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/3ftNVHdsjyk"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Ryan Carniato on 2026
&lt;/h2&gt;

&lt;p&gt;Ryan Carniato is the creator of Solid.js and has a good overview of what the various front-end frameworks are doing. He published an article where he gave his prediction for 2026.&lt;/p&gt;

&lt;p&gt;The rise of powerful SSR techniques (he mentioned React Server Components and Astro’s island architecture) led to separate code paths—one for the server and one for the client. Ryan expects frameworks to reduce that friction and coined the term isomorphic-first for this. In my opinion, if you want to see that reduced friction in action, Angular’s incremental hydration gets it right.&lt;/p&gt;

&lt;p&gt;Ryan sees asynchronicity as a central theme for the future. Frameworks will integrate async behavior more deeply rather than treating it as an add-on. Examples include Angular’s resource, and what React is doing under the “Async React” framing, which is a mix of techniques that work together.&lt;/p&gt;

&lt;p&gt;Lastly on AI: Ryan says meta-frameworks used to win by packaging tools together, but AI can now stitch those basic tools on its own, so that advantage is shrinking.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/playfulprogramming/javascript-frameworks-heading-into-2026-2hel" class="crayons-story__hidden-navigation-link"&gt;JavaScript Frameworks - Heading into 2026&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/playfulprogramming"&gt;
            &lt;img alt="Playful Programming logo" 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%2Forganization%2Fprofile_image%2F3314%2Ffd92caab-2014-431e-a19e-8ab47f2bf5ab.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/ryansolid" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F186199%2Fa3d1cfed-a1ca-41cd-a146-9db4e65711d4.jpeg" alt="ryansolid profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ryansolid" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ryan Carniato
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ryan Carniato
                
              
              &lt;div id="story-author-preview-content-3102509" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/ryansolid" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F186199%2Fa3d1cfed-a1ca-41cd-a146-9db4e65711d4.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ryan Carniato&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/playfulprogramming" class="crayons-story__secondary fw-medium"&gt;Playful Programming&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/playfulprogramming/javascript-frameworks-heading-into-2026-2hel" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 5&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/playfulprogramming/javascript-frameworks-heading-into-2026-2hel" id="article-link-3102509"&gt;
          JavaScript Frameworks - Heading into 2026
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webperf"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webperf&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/frameworks"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;frameworks&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/playfulprogramming/javascript-frameworks-heading-into-2026-2hel" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;104&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/playfulprogramming/javascript-frameworks-heading-into-2026-2hel#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              28&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            8 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Mark Thompson at PodRocket
&lt;/h2&gt;

&lt;p&gt;Mark Thompson, DevRel on the Angular team, was a guest on the PodRocket podcast. It was aimed at a non-Angular audience, so most things that were discussed are broadly known, but at the end, Mark explained a little on how they see the competition. Every framework has a very similar feature set, and it is not that Angular wants to attract Svelte, React, or Vue users (or the other way around).&lt;/p&gt;

&lt;p&gt;Every framework looks at its user and optimizes the framework for their users. Or to put it short: when it comes to new features, it is more what the Angular community wants and not so much what React developers want from Angular.&lt;/p&gt;

&lt;p&gt;Apart from that, AI will bring changes in the way how developers write applications. They won't even care what framework is used, other things like MCP, context files could become more important.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/r4AOIBYiL68"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular from the Inside (Angular Space)
&lt;/h2&gt;

&lt;p&gt;Angular from the Inside was the title of the Angular Space podcast. Armen Vardanyan had Matthieu Riegler from the Angular team as a guest.&lt;/p&gt;

&lt;p&gt;Matthieu showed how the template checks are actually working. He showed this in VSCode: Angular's compiler runs a special compilation just for the type check (via the language service for the VSCode integration) and then another compilation for the final application code.&lt;/p&gt;

&lt;p&gt;They also discussed things beyond compilation: the most requested PR, general insights into how the Angular team works internally, a PR explained in detail, and an overview of what is going to come for Angular 21.1 (which has already been released).&lt;/p&gt;

&lt;p&gt;An episode you don't want to miss if you are interested in learning some of Angular's internals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/live/vz4LZAimZBc" rel="noopener noreferrer"&gt;https://www.youtube.com/live/vz4LZAimZBc&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailwind Crisis
&lt;/h2&gt;

&lt;p&gt;Tailwind is also in the news, but unfortunately with sad news. Their business model was based on selling UI components. Unfortunately, you usually only discover those products if you visit their website and documentation, which is what we developers usually do... or rather, used to do. Because these days, AI applies the proper Tailwind classes automatically. Although Tailwind is used more than ever, 75% of the engineering team has been laid off because the company became a victim of the current AI trend. The good news is that Vercel and Google have contacted them and stepped in with sponsorships to help find a solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/tailwindlabs/tailwindcss.com/pull/2388#issuecomment-3717222957" rel="noopener noreferrer"&gt;https://github.com/tailwindlabs/tailwindcss.com/pull/2388#issuecomment-3717222957&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;

&lt;iframe class="tweet-embed" id="tweet-2009336725043335338-64" src="https://platform.twitter.com/embed/Tweet.html?id=2009336725043335338"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2009336725043335338-64');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2009336725043335338&amp;amp;theme=dark"
  }





&lt;/p&gt;

&lt;p&gt;

&lt;iframe class="tweet-embed" id="tweet-2009339263251566902-585" src="https://platform.twitter.com/embed/Tweet.html?id=2009339263251566902"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2009339263251566902-585');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2009339263251566902&amp;amp;theme=dark"
  }





&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Three v4
&lt;/h2&gt;

&lt;p&gt;Angular Three is a library from Chau Tran, which gives a deep integration of THREE.js into Angular. THREE.js is a very popular library for creating 3D graphics. Version 4 was released and the underlying renderer got completely rewritten.&lt;/p&gt;

&lt;p&gt;So if you are already using Angular Three, the blog post recommends that you treat version 4 as a complete fresh start.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://angularthree.org" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;angularthree.org&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  Community Shoutout: ngx-dev-toolbar
&lt;/h2&gt;

&lt;p&gt;Shoutout to the community for new libraries. Alfredo Perez released ngx-dev-toolbar, which gives you a nice UI to apply common tasks, like toggling features, switching languages, mocking the network, and so on.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/alfredoperez" rel="noopener noreferrer"&gt;
        alfredoperez
      &lt;/a&gt; / &lt;a href="https://github.com/alfredoperez/ngx-dev-toolbar" rel="noopener noreferrer"&gt;
        ngx-dev-toolbar
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A powerful development toolbar for Angular applications to improve your developer productivity directly in the browser.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Angular Toolbar&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/ngx-dev-toolbar" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a9f1d9812c2dc76a5c3364f55ba82119f2a160be23ee27ba54fe016286fad660/68747470733a2f2f62616467652e667572792e696f2f6a732f6e67782d6465762d746f6f6c6261722e737667" alt="npm version"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/ngx-dev-toolbar" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f9b97e9f97f87cdbb353313e5b30644225588e27048b6efe8014d5c6ea49d111/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f6e67782d6465762d746f6f6c6261722e737667" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://github.com/alfredoperez/ngx-dev-toolbar/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/aff024591238b7e91a90bd91195b0358a5c144f1988c5f6e0d33049c8a1e5c24/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f6c2f6e67782d6465762d746f6f6c6261722e737667" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://angular.io/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/28dd8cad29614d60a904fa9d2b091b3ed7f117bab27606455b53a822dff03d5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f416e67756c61722d31392532422d726564" alt="Angular"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A development toolbar for Angular 19+ applications that helps developers interact with the application more efficiently.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/alfredoperez/ngx-dev-toolbar/./docs/images/demo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Falfredoperez%2Fngx-dev-toolbar%2F.%2Fdocs%2Fimages%2Fdemo.gif" alt="Toolbar Demo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why ngx-dev-toolbar?&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Toggle feature flags without backend changes&lt;/li&gt;
&lt;li&gt;Simulate complete i18n environments (locale, timezone, currency, RTL)&lt;/li&gt;
&lt;li&gt;Test product features and subscription tiers&lt;/li&gt;
&lt;li&gt;Switch themes on the fly&lt;/li&gt;
&lt;li&gt;Change user sessions effortlessly&lt;/li&gt;
&lt;li&gt;Mock network requests in real-time&lt;/li&gt;
&lt;li&gt;Test permission-based UI without backend changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No more context switching or backend dependencies - everything you need is right in your browser!&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install ngx-dev-toolbar&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Add the toolbar to your &lt;code&gt;app.config.ts&lt;/code&gt; alongside your other providers:&lt;/p&gt;
&lt;div class="highlight highlight-source-ts notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;// app.config.ts&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-v"&gt;ApplicationConfig&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s1"&gt;isDevMode&lt;/span&gt; &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'@angular/core'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-s1"&gt;provideRouter&lt;/span&gt; &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'@angular/router'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-s1"&gt;provideToolbar&lt;/span&gt; &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'ngx-dev-toolbar'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;

&lt;span class="pl-k"&gt;export&lt;/span&gt; &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;appConfig&lt;/span&gt;: &lt;span class="pl-smi"&gt;ApplicationConfig&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
  &lt;span class="pl-c1"&gt;providers&lt;/span&gt;: &lt;span class="pl-kos"&gt;[&lt;/span&gt;
    &lt;span class="pl-en"&gt;provideRouter&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;appRoutes&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-en"&gt;provideToolbar&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-c1"&gt;enabled&lt;/span&gt;: &lt;span class="pl-en"&gt;isDevMode&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
&lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-ts notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;// main.ts&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/alfredoperez/ngx-dev-toolbar" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;&lt;em&gt;If you have written a new library or are organizing a conference, please let us know. We are going to announce it here.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>angular</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
