{"id":26298,"date":"2024-01-05T05:00:00","date_gmt":"2024-01-05T04:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=26298"},"modified":"2024-07-22T14:20:06","modified_gmt":"2024-07-22T12:20:06","slug":"whats-new-in-angular-17","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/en\/whats-new-in-angular-17\/","title":{"rendered":"What&#8217;s new in Angular 17?"},"content":{"rendered":"\n<p>The Angular team is dedicated to releasing a new major version every six months. The latest version, 17, was released on November 8, 2023.<\/p>\n\n\n\n<p>Version 17 includes several new features, which I will introduce in the article, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>New Control Flow,<\/li>\n\n\n\n<li>Deferred Loading,<\/li>\n\n\n\n<li>Support For View Transitions API,<\/li>\n\n\n\n<li>Support for TypeScript 5.2.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>New Control Flow Syntax<\/strong><\/h2>\n\n\n\n<p>The new control flow, in my opinion, is the most crucial change in this release. After a long debate and consultation with the Angular community, the team is introducing a completely new @ \u2013 syntax. <\/p>\n\n\n\n<p>It provides the functionality of structural directives *ngIf, *ngFor, *ngSwitch with some extra features. Let\u2019s dive into some examples.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Example #1 \u2013 NgIf with the else option and the new syntax<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image1.png\"><img decoding=\"async\" width=\"622\" height=\"352\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image1.png\" alt=\"code\" class=\"wp-image-26299\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image1.png 622w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image1-300x170.png 300w\" sizes=\"(max-width: 622px) 100vw, 622px\" \/><\/a><\/figure>\n\n\n\n<p>As we can see, the old way of displaying some info up to some predicate was to use a *ngIf structural directive. The else block has to be implemented using another ng-template, and reference to that was set after the else keyword. <\/p>\n\n\n\n<p>The new syntax gives us a plain if-else control without adding extra templates.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Example #2 \u2013 Empty with @for loop<\/strong><\/h3>\n\n\n\n<p>With the new syntax comes a new feature \u2013 handling empty lists! Previously, to handle an empty list with proper information for the user, we had to create a separate ngTemplate and extra ngContainer to bind the <em>if <\/em>statement with its <em>else <\/em>option. <\/p>\n\n\n\n<p>With the new syntax, we can do the same more shortly by declaring <em>@empty <\/em>right after <em>for<\/em> block scope. It&#8217;s also worth mentioning that, in the past, when using the ngFor directive, we had the option to utilize a trackBy property and a recognition function to optimize rendering. The new syntax simplifies this process by requiring only the property name the track function will use for object recognition.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image2.png\"><img decoding=\"async\" width=\"562\" height=\"436\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image2.png\" alt=\"code\" class=\"wp-image-26303\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image2.png 562w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image2-300x233.png 300w\" sizes=\"(max-width: 562px) 100vw, 562px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Example #3 \u2013 Switch with @switch<\/strong><\/h3>\n\n\n\n<p>Switch syntax in a new version is very similar to the old implementation of NgSwitch.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image3.png\"><img decoding=\"async\" width=\"716\" height=\"728\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image3.png\" alt=\"code\" class=\"wp-image-26305\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image3.png 716w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image3-295x300.png 295w\" sizes=\"(max-width: 716px) 100vw, 716px\" \/><\/a><\/figure>\n\n\n\n<p>Here are a couple of reasons why the new flow syntax has been introduced.<\/p>\n\n\n\n<p>The previous implementation of the control flow was based on the zone-dependent application. Structural directives are strongly coupled with Change Detection mechanisms. Angular Team has decided to go in the direction of a zoneless application with a Signals implementation, and now it\u2019s making another step towards it.<\/p>\n\n\n\n<p>Therefore, the team has decided to create a new implementation of control flow, and the plan is to deprecate the current implementation of structural directives as ngIf and <em>ngFor<\/em> but not remove them &#8220;<em>until the ecosystem (including community-authored content) has switched over to the new control flow.\u201d<\/em> The NG Team has prepared an auto-migration scheme to facilitate incorporating new syntax changes. The only command that needs to be run is:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ng g @angular\/core:control-flow<\/pre>\n\n\n\n<p>Be aware that this schematic is still only a developer preview migration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Deferred Loading<\/strong><\/h2>\n\n\n\n<p>A defer block is The most exciting feature of a new control flow. The best way to show it\u2019s magic is just by presenting an example. <\/p>\n\n\n\n<p>Let\u2019s assume we have a simple pipe that capitalizes the input.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image4.png\"><img decoding=\"async\" width=\"588\" height=\"197\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image4.png\" alt=\"code\" class=\"wp-image-26308\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image4.png 588w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image4-300x101.png 300w\" sizes=\"(max-width: 588px) 100vw, 588px\" \/><\/a><\/figure>\n\n\n\n<p>By @defer block, the angular compiler knows it shouldn\u2019t immediately import that pipe (if it\u2019s not used elsewhere) while loading the component, but when the predicate is true. <\/p>\n\n\n\n<p>The chunk of javascript, including upperCasePipe, is downloaded when we click the button.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image5.gif\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image5.gif\" alt=\"giphy\" class=\"wp-image-26311\" width=\"600\" height=\"319\"\/><\/a><\/figure>\n\n\n\n<p>We can see how our application is chunked after a successful build \u2013 Angular CLI will display how many chunks can be fetched.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image6.png\"><img decoding=\"async\" width=\"1024\" height=\"363\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image6-1024x363.png\" alt=\"lazy chunk files\" class=\"wp-image-26313\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image6-1024x363.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image6-300x106.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image6-768x272.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image6.png 1045w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What if the connection is slow or broken?<\/strong><\/h2>\n\n\n\n<p>Angular handles that easily by providing possibilities to define the view during loading and in case of error.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image7.png\"><img decoding=\"async\" width=\"648\" height=\"292\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image7.png\" alt=\"code\" class=\"wp-image-26316\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image7.png 648w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image7-300x135.png 300w\" sizes=\"(max-width: 648px) 100vw, 648px\" \/><\/a><\/figure>\n\n\n\n<p>For example, if we turn on an offline mode:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image8.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image8.png\" alt=\"defer blocks\" class=\"wp-image-26318\" width=\"676\" height=\"212\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image8.png 680w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image8-300x94.png 300w\" sizes=\"(max-width: 676px) 100vw, 676px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image9.png\"><img decoding=\"async\" width=\"973\" height=\"97\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image9.png\" alt=\"defer block example\" class=\"wp-image-26320\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image9.png 973w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image9-300x30.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image9-768x77.png 768w\" sizes=\"(max-width: 973px) 100vw, 973px\" \/><\/a><\/figure>\n\n\n\n<p>But @defer control flow is much more powerful than it looks at first sight. We can connect the visibility of the component with some triggers.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image10.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image10.png\" alt=\"code\" class=\"wp-image-26322\" width=\"598\" height=\"243\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image10.png 598w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image10-300x122.png 300w\" sizes=\"(max-width: 598px) 100vw, 598px\" \/><\/a><\/figure>\n\n\n\n<p>Also, if we want to pass the responsibility to the browser, we can let the application manage to import code when a browser has finished its processes and is in an idle state.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image11.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image11.png\" alt=\"code\" class=\"wp-image-26324\" width=\"757\" height=\"201\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image11.png 755w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image11-300x79.png 300w\" sizes=\"(max-width: 757px) 100vw, 757px\" \/><\/a><\/figure>\n\n\n\n<p>This is particularly useful when you have heavy loadings that burden your page loading and user experience by slowing down features.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Difference between on and when<\/strong><\/h2>\n\n\n\n<p><strong>when:<\/strong> Some condition that triggers the change when it becomes true. After the change, it won&#8217;t revert to the previous condition even if the variable becomes false again.<\/p>\n\n\n\n<p><strong>on:<\/strong> Needs a predefined trigger that includes actions like interaction or entering the viewport. We\u2019re able to combine multiple triggers. <\/p>\n\n\n\n<p>Possible triggers:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>idle <\/strong>\u2013 triggered when the browser reaches an idle state,<\/li>\n\n\n\n<li><strong>hover <\/strong>\u2013 triggered when the mouse has hovered over a specified area,<\/li>\n\n\n\n<li><strong>immediate <\/strong>\u2013 triggered without any waiting,<\/li>\n\n\n\n<li><strong>timer(x) <\/strong>\u2013 triggered after a specified amount of time,<\/li>\n\n\n\n<li><strong>viewport <\/strong>\u2013 triggered when a specified element comes into the viewport, in other words, when it\u2019s visible to the user,<\/li>\n\n\n\n<li><strong>interaction <\/strong>\u2013 triggered when the user interacts with a specified element.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Why is it a crucial change? Advantages and disadvantages<\/strong><\/h2>\n\n\n\n<p>There are a couple of reasons why this change is a vast improvement for the Angular apps.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Chunk loading<\/strong><\/h3>\n\n\n\n<p>We could dynamically import the module&#8217;s code on demand by lazy loading modules. Right now, the Angular team has taken another step.<\/p>\n\n\n\n<p>By importing a chunk of code on demand \/ idle \/ interaction, we can enhance user experience by fastening the page and loading the component.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Ease way of placing placeholders, loading view, and error handlers <\/strong><\/h3>\n\n\n\n<p>The new syntax facilitates handling transition or failure states. Handling placeholders no longer needs other templates, interceptors, etc. Some problems with network traffic can also be handled with ease.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Support for view transitions API<\/strong><\/h2>\n\n\n\n<p>View Transitions API is a feature that enables the creation of animated transitions between different DOM states. Until now applications handled animations, transitions by writing specific css and js files.<br>View Transition API is a new way of handling animations. <\/p>\n\n\n\n<p><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/View_Transitions_API\" rel=\"nofollow\" >Full description of View Transitions API<\/a>.<\/p>\n\n\n\n<p><strong>All major browsers now support the feature.<\/strong> IIn November 2023, View Transitions API was available in:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Chrome,<\/li>\n\n\n\n<li>Edge,<\/li>\n\n\n\n<li>Opera,<\/li>\n\n\n\n<li>Samsung Browser.<\/li>\n<\/ul>\n\n\n\n<p>Configuration in Angular is straightforward. All we have to do is configure the router during the bootstrapping application:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image12.png\"><img decoding=\"async\" width=\"930\" height=\"517\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image12.png\" alt=\"code\" class=\"wp-image-26332\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image12.png 930w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image12-300x167.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image12-768x427.png 768w\" sizes=\"(max-width: 930px) 100vw, 930px\" \/><\/a><\/figure>\n\n\n\n<p>By providing this configuration, the default transition animation is visible:<\/p>\n\n\n\n<p>Without view Transition API:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image13.gif\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image13.gif\" alt=\"without view transition API\" class=\"wp-image-26334\" width=\"598\" height=\"318\"\/><\/a><\/figure>\n\n\n\n<p>With View Transition API:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image14.gif\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image14.gif\" alt=\"with view transition API\" class=\"wp-image-26337\" width=\"600\" height=\"319\"\/><\/a><\/figure>\n\n\n\n<p>We can customize the way the animation is going, e.g.:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image15.png\"><img decoding=\"async\" width=\"813\" height=\"545\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image15.png\" alt=\"code\" class=\"wp-image-26339\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image15.png 813w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image15-300x201.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image15-768x515.png 768w\" sizes=\"(max-width: 813px) 100vw, 813px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Support for TypeScript 5.2<\/strong><\/h2>\n\n\n\n<p>Angular 17 comes with support for TypeScript 5.2. What is included in that?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>The new use of keywords as a remedy for resource management<\/strong><\/h3>\n\n\n\n<p>Using keywords can measurably help to handle resources. In a nutshell, it is a new block of code that declares a disposable resource. When the variable to which the resource was assigned is not used anymore, the method [Symbol.dispose]() is invoked, releasing the help. <\/p>\n\n\n\n<p>Let\u2019s take a look. We have some <em>MockResourceHandler<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image16.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image16.png\" alt=\"code\" class=\"wp-image-26347\" width=\"627\" height=\"513\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image16.png 627w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image16-300x245.png 300w\" sizes=\"(max-width: 627px) 100vw, 627px\" \/><\/a><\/figure>\n\n\n\n<p>The old way of handling this resource would be to open it to try and finally block scope and to take closing connection in the final scope.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image17-1.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image17-1.png\" alt=\"code\" class=\"wp-image-26349\" width=\"787\" height=\"295\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image17-1.png 787w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image17-1-300x112.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image17-1-768x288.png 768w\" sizes=\"(max-width: 787px) 100vw, 787px\" \/><\/a><\/figure>\n\n\n\n<p>The new way requires changing the implementation of <em>MockResourceHandler<\/em>; the disposable interface and the [Symbol have to be implemented.dispose]() method has to be implemented as well.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image18.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image18.png\" alt=\"code\" class=\"wp-image-26351\" width=\"705\" height=\"209\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image18.png 707w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image18-300x89.png 300w\" sizes=\"(max-width: 705px) 100vw, 705px\" \/><\/a><\/figure>\n\n\n\n<p>Then, releasing resources will happen automatically on the method end:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image19.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image19.png\" alt=\"code\" class=\"wp-image-26355\" width=\"747\" height=\"168\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image19.png 747w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image19-300x67.png 300w\" sizes=\"(max-width: 747px) 100vw, 747px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Decorator Metadata<\/strong><\/h2>\n\n\n\n<p>When using decorator functions, they gain access to a fresh metadata attribute within the object. Once all decorators have been executed within or attached to a class, the object can be reached within the class through the<em> Symbol.metadata<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image20.png\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image20.png\" alt=\"code\" class=\"wp-image-26357\" width=\"655\" height=\"477\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image20.png 655w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/image20-300x218.png 300w\" sizes=\"(max-width: 655px) 100vw, 655px\" \/><\/a><\/figure>\n\n\n\n<p>More details in ECMAScript proposal <a href=\"https:\/\/github.com\/tc39\/proposal-decorator-metadata\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >you can find on GitHub<\/a>.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;26298&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;6&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 6)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;What\\u0026#039;s new in Angular 17?&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 6)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Angular team is dedicated to releasing a new major version every six months. The latest version, 17, was released &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/en\/whats-new-in-angular-17\/\">Continued<\/a><\/p>\n","protected":false},"author":557,"featured_media":26362,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1320],"tags":[2622,1590,1526,1422],"class_list":["post-26298","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hard-development","tag-digital-en","tag-tools","tag-guidebook","tag-angular-en"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/12\/Whats-new-in-Angular-17.jpg","category_names":["Hard development"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/26298"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/users\/557"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/comments?post=26298"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/26298\/revisions"}],"predecessor-version":[{"id":26361,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/26298\/revisions\/26361"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media\/26362"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media?parent=26298"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/categories?post=26298"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/tags?post=26298"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}