{"id":26864,"date":"2024-04-03T17:32:58","date_gmt":"2024-04-03T15:32:58","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=26864"},"modified":"2024-04-04T17:48:41","modified_gmt":"2024-04-04T15:48:41","slug":"angular-new-output-function","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/","title":{"rendered":"Angular new output()\u00a0function"},"content":{"rendered":"\n<p>During the latest months, <strong>Angular v17<\/strong> has introduced a set of new function-based APIs focused on enhancing Signal integration within components and directives. This includes <strong><a aria-label=\"Signal Inputs (opens in a new tab)\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/angular-signal-inputs\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">Signal Inputs<\/a><\/strong>, <strong><a aria-label=\"Model Inputs (opens in a new tab)\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/angular-model-inputs-two-way-binding-inputs-with-signals\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">Model Inputs<\/a><\/strong> and <strong><a aria-label=\"Signal Queries (opens in a new tab)\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/angular-signal-queries-simplifying-dom-querying\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">Signal Queries<\/a><\/strong>.<\/p>\n\n\n\n<p>Considering the full picture, we are only missing one core API to conclude this journey, and this article is dedicated to precisely that: <strong>Angular v17.3.0<\/strong> latest addition, the new <code><strong>output()<\/strong><\/code> function.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-new-output-nbsp-api\">The new output( )&nbsp;API<\/h2>\n\n\n\n<p>Similar to the function-based APIs introduced so far, you now have a brand-new <code><strong>output()<\/strong><\/code> function designed to replace the <strong>@Output<\/strong> decorator.<\/p>\n\n\n\n<p>To declare an output, you can now use the <code><strong>output()<\/strong><\/code> function when we declare a property of a component or directive:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Component, output, OutputEmitterRef } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@angular\/core'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-meta\">@Component<\/span>({\n<\/span><\/span><span class='shcb-loc'><span>  selector: <span class=\"hljs-string\">'my-component'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  standalone: <span class=\"hljs-literal\">true<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  template: <span class=\"hljs-string\">`&lt;button (click)=\"emitClick($event)\"&gt;Click here&lt;\/button&gt;`<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>})\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">class<\/span> MyComponent {\n<\/span><\/span><mark class='shcb-loc'><span>  buttonClick = output&lt;MouseEvent&gt;();\n<\/span><\/mark><mark class='shcb-loc'><span>  alias = output&lt;MouseEvent&gt;({ alias: <span class=\"hljs-string\">'aliasClick'<\/span> });\n<\/span><\/mark><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  emitClick(event: MouseEvent): <span class=\"hljs-built_in\">void<\/span> {\n<\/span><\/span><mark class='shcb-loc'><span>    <span class=\"hljs-keyword\">this<\/span>.buttonClick.emit(event);\n<\/span><\/mark><mark class='shcb-loc'><span>    <span class=\"hljs-keyword\">this<\/span>.alias.emit(event);\n<\/span><\/mark><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>As you can see from the example, this API also supports the <code><strong>alias<\/strong><\/code> property and exposes the <code><strong>emit()<\/strong><\/code> function.<\/p>\n\n\n\n<p>Furthermore, you can listen for the output event in the parent components, using Angular event binding syntax in the template:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">my-component<\/span><\/span>\n<\/span><\/span><mark class='shcb-loc'><span><span class=\"hljs-tag\">  (<span class=\"hljs-attr\">buttonClick<\/span>)=<span class=\"hljs-string\">\"myFunction($event)\"<\/span><\/span>\n<\/span><\/mark><mark class='shcb-loc'><span><span class=\"hljs-tag\">  (<span class=\"hljs-attr\">aliasClick<\/span>)=<span class=\"hljs-string\">\"myFunction($event)\"<\/span><\/span>\n<\/span><\/mark><span class='shcb-loc'><span><span class=\"hljs-tag\">\/&gt;<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>So far, everything works almost identically to <strong>@Output<\/strong> decorator-based outputs.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/720\/1*GlfnAIDEENv6tYJ8XpL9oQ.jpeg\" alt=\"\" style=\"width:400px\"\/><\/figure>\n<\/div>\n\n\n<p>Let\u2019s now move on to the <code><strong>subscribe()<\/strong><\/code> function, which brings some changes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-subscribe-to-outputs-programmatically\">How to subscribe to outputs programmatically<\/h3>\n\n\n\n<p>Using the <code><strong>output()<\/strong><\/code> function you get an instance of type <strong>OutputEmitterRef<\/strong>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>buttonClick: OutputEmitterRef&lt;MouseEvent&gt; = output&lt;MouseEvent&gt;();\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In addition to the already-mentioned <code><strong>emit()<\/strong><\/code> method, which has remained unchanged on the surface, this class also exposes a <code><strong>subscribe()<\/strong><\/code> method to listen to the event programmatically:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Component, Signal, effect, viewChild } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@angular\/core'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { MyComponent } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/my-component'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-meta\">@Component<\/span>({\n<\/span><\/span><span class='shcb-loc'><span>  selector: <span class=\"hljs-string\">'my-parent-component'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  standalone: <span class=\"hljs-literal\">true<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  imports: &#91;MyComponent],\n<\/span><\/span><span class='shcb-loc'><span>  template: <span class=\"hljs-string\">`&lt;my-component \/&gt;`<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>})\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">class<\/span> MyParentComponent {\n<\/span><\/span><span class='shcb-loc'><span>  myComponentRef: Signal&lt;MyComponent&gt; = viewChild.required(MyComponent);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">constructor<\/span>(<span class=\"hljs-params\"><\/span>) {\n<\/span><\/span><span class='shcb-loc'><span>    effect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n<\/span><\/span><mark class='shcb-loc'><span>      <span class=\"hljs-keyword\">this<\/span>.myComponentRef().myOutput.subscribe(<span class=\"hljs-function\">(<span class=\"hljs-params\"><span class=\"hljs-params\">event<\/span>: <span class=\"hljs-params\">MouseEvent<\/span><\/span>) =&gt;<\/span> {\n<\/span><\/mark><mark class='shcb-loc'><span>        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Manual subscription:'<\/span>, event);\n<\/span><\/mark><mark class='shcb-loc'><span>      });\n<\/span><\/mark><span class='shcb-loc'><span>    });\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The subscription generated by this class is not based on <strong>RxJs<\/strong>, so you can\u2019t use the <code><strong>pipe()<\/strong><\/code> function and operators. Nevertheless, it still exposes an <code><strong>unsubscribe()<\/strong><\/code> function to terminate it programmatically:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> subscription = <span class=\"hljs-keyword\">this<\/span>.myComponentRef().myOutput.subscribe(\n<\/span><\/span><span class='shcb-loc'><span> <span class=\"hljs-function\">(<span class=\"hljs-params\"><span class=\"hljs-params\">event<\/span>: <span class=\"hljs-params\">MouseEvent<\/span><\/span>) =&gt;<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>   <span class=\"hljs-comment\">\/\/ Unsubscribes to listen only the first event, if any<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>   subscription.unsubscribe();\n<\/span><\/mark><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>);\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>It is also automatically completed when the component, or directive, is destroyed.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/720\/1*sXF4p76YfhcGUGf1WNc86Q.jpeg\" alt=\"\" style=\"width:400px\"\/><\/figure>\n<\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-new-rxjs-interop-functions\">New rxjs-interop functions<\/h2>\n\n\n\n<p>To further enhance the capabilities of this new API, two additional functions have been introduced in the <strong>RxJs Interop<\/strong> package.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-outputfromobservable\">outputFromObservable( )<\/h3>\n\n\n\n<p>Thanks to the brand-new <code><strong>outputFromObservable()<\/strong><\/code> function, you can now create an output starting from an <strong>Observable<\/strong>.<\/p>\n\n\n\n<p>The generated output emits each new value emitted by the <strong>Observable<\/strong>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Component, OutputRef } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@angular\/core'<\/span>;\n<\/span><\/span><mark class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { outputFromObservable } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@angular\/core\/rxjs-interop'<\/span>;\n<\/span><\/mark><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { interval } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'rxjs'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-meta\">@Component<\/span>({\n<\/span><\/span><span class='shcb-loc'><span>  selector: <span class=\"hljs-string\">'my-timer-component'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  standalone: <span class=\"hljs-literal\">true<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  template: <span class=\"hljs-string\">`...`<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>})\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">class<\/span> MyTimerComponent {\n<\/span><\/span><mark class='shcb-loc'><span> timer: OutputRef&lt;<span class=\"hljs-built_in\">number<\/span>&gt; = outputFromObservable(interval(<span class=\"hljs-number\">1000<\/span>));\n<\/span><\/mark><mark class='shcb-loc'><span> timerAlias = outputFromObservable(interval(<span class=\"hljs-number\">1000<\/span>), { alias: <span class=\"hljs-string\">'timerChange'<\/span> });\n<\/span><\/mark><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Both the <strong>Observable<\/strong> and the output are automatically completed when the component, or directive, is destroyed.<\/p>\n\n\n\n<p>If an error occurs, the <strong>Observable<\/strong> is interrupted, consequently the output stops emitting and the error propagates (if not caught).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-outputtoobservable\">outputToObservable( )<\/h3>\n\n\n\n<p>Thanks to the new <code><strong>outputToObservable()<\/strong><\/code> function we can instead transform an output into an <strong>Observable<\/strong>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"TypeScript\" data-shcb-language-slug=\"typescript\"><span><code class=\"hljs language-typescript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Component, Signal, effect, viewChild } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@angular\/core'<\/span>;\n<\/span><\/span><mark class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { outputToObservable } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@angular\/core\/rxjs-interop'<\/span>;\n<\/span><\/mark><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { MyComponent } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/my-component'<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-meta\">@Component<\/span>({\n<\/span><\/span><span class='shcb-loc'><span>  selector: <span class=\"hljs-string\">'my-parent-component'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  standalone: <span class=\"hljs-literal\">true<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  imports: &#91;MyComponent],\n<\/span><\/span><span class='shcb-loc'><span>  template: <span class=\"hljs-string\">`&lt;my-component \/&gt;`<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>})\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">class<\/span> MyParentComponent {\n<\/span><\/span><span class='shcb-loc'><span>  myComponentRef: Signal&lt;MyComponent&gt; = viewChild.required(MyComponent);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">constructor<\/span>(<span class=\"hljs-params\"><\/span>) {\n<\/span><\/span><span class='shcb-loc'><span>    effect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n<\/span><\/span><mark class='shcb-loc'><span>      outputToObservable(<span class=\"hljs-keyword\">this<\/span>.myComponentRef().myOutput)\n<\/span><\/mark><mark class='shcb-loc'><span>        .subscribe(<span class=\"hljs-function\">(<span class=\"hljs-params\"><span class=\"hljs-params\">event<\/span>: <span class=\"hljs-params\">MouseEvent<\/span><\/span>) =&gt;<\/span> {\n<\/span><\/mark><mark class='shcb-loc'><span>          <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Manual subscription:'<\/span>, event);\n<\/span><\/mark><mark class='shcb-loc'><span>        });\n<\/span><\/mark><span class='shcb-loc'><span>    });\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">TypeScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">typescript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Again, both the <strong>Observable<\/strong> and the output are automatically completed when the component, or directive, is destroyed.<\/p>\n\n\n\n<p>Furthermore, due to the absence of errors in the outputs, the resulting <strong>Observable<\/strong> never emits error notifications.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-thanks-for-reading-so-far-nbsp\">Thanks for reading so far&nbsp;\ud83d\ude4f<\/h2>\n\n\n\n<p>I\u2019d like to know your feedback so please feel free to contact me for any. \ud83d\udc4b<\/p>\n\n\n\n<p>Then, if you really liked it,&nbsp;<strong>share it<\/strong>&nbsp;among your community, tech bros, and whoever you want. \ud83d\udc4b\ud83d\ude01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>During the latest months, Angular v17 has introduced a set of new function-based APIs focused on enhancing Signal integration within components and directives. This includes Signal Inputs, Model Inputs and Signal Queries. Considering the full picture, we are only missing one core API to conclude this journey, and this article is dedicated to precisely that:&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/\">Read more<\/a><\/p>\n","protected":false},"author":200,"featured_media":26900,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[20],"tags":[],"collections":[],"class_list":{"0":"post-26864","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-languages","8":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Angular new output()\u00a0function - Codemotion Magazine<\/title>\n<meta name=\"description\" content=\"Angular v17 has introduced new function-based APIs to improve Signal integration. Let&#039;s discover the new output() function!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular new output()\u00a0function\" \/>\n<meta property=\"og:description\" content=\"Angular v17 has introduced new function-based APIs to improve Signal integration. Let&#039;s discover the new output() function!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-04-03T15:32:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-04T15:48:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1080\" \/>\n\t<meta property=\"og:image:height\" content=\"608\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Davide Passafaro\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Davide Passafaro\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/\"},\"author\":{\"name\":\"Davide Passafaro\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/79170e2a1bfc41ddeaa10827ce803828\"},\"headline\":\"Angular new output()\u00a0function\",\"datePublished\":\"2024-04-03T15:32:58+00:00\",\"dateModified\":\"2024-04-04T15:48:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/\"},\"wordCount\":429,\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/image-2.png\",\"articleSection\":[\"Languages and frameworks\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/\",\"name\":\"Angular new output()\u00a0function - Codemotion Magazine\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/image-2.png\",\"datePublished\":\"2024-04-03T15:32:58+00:00\",\"dateModified\":\"2024-04-04T15:48:41+00:00\",\"description\":\"Angular v17 has introduced new function-based APIs to improve Signal integration. Let's discover the new output() function!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/image-2.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/image-2.png\",\"width\":1080,\"height\":608,\"caption\":\"Scopriamo la nuova funzione (output) di Angular.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/angular-new-output-function\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Languages and frameworks\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Angular new output()\u00a0function\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/Codemotion.Italy\\\/\",\"https:\\\/\\\/x.com\\\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/79170e2a1bfc41ddeaa10827ce803828\",\"name\":\"Davide Passafaro\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/Immagine-profilo-GDE-430kb-100x100.png\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/Immagine-profilo-GDE-430kb-100x100.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/Immagine-profilo-GDE-430kb-100x100.png\",\"caption\":\"Davide Passafaro\"},\"description\":\"My name is Davide Passafaro and I am Senior Frontend Engineer at Awork. I lead two developer communities in Rome, GDG Roma Citt\u00e0 and Angular Rome, and actively contribute to the tech community as a writer and speaker. When i shut down my computer I like to play board games and archery, not both together till now. I also like escape rooms and memes.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/davide-passafaro\\\/\"],\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/author\\\/davidepassafaro\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Angular new output()\u00a0function - Codemotion Magazine","description":"Angular v17 has introduced new function-based APIs to improve Signal integration. Let's discover the new output() function!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/","og_locale":"en_US","og_type":"article","og_title":"Angular new output()\u00a0function","og_description":"Angular v17 has introduced new function-based APIs to improve Signal integration. Let's discover the new output() function!","og_url":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2024-04-03T15:32:58+00:00","article_modified_time":"2024-04-04T15:48:41+00:00","og_image":[{"width":1080,"height":608,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png","type":"image\/png"}],"author":"Davide Passafaro","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Davide Passafaro","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/"},"author":{"name":"Davide Passafaro","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/79170e2a1bfc41ddeaa10827ce803828"},"headline":"Angular new output()\u00a0function","datePublished":"2024-04-03T15:32:58+00:00","dateModified":"2024-04-04T15:48:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/"},"wordCount":429,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png","articleSection":["Languages and frameworks"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/","url":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/","name":"Angular new output()\u00a0function - Codemotion Magazine","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png","datePublished":"2024-04-03T15:32:58+00:00","dateModified":"2024-04-04T15:48:41+00:00","description":"Angular v17 has introduced new function-based APIs to improve Signal integration. Let's discover the new output() function!","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png","width":1080,"height":608,"caption":"Scopriamo la nuova funzione (output) di Angular."},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/languages\/angular-new-output-function\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Languages and frameworks","item":"https:\/\/www.codemotion.com\/magazine\/languages\/"},{"@type":"ListItem","position":3,"name":"Angular new output()\u00a0function"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/79170e2a1bfc41ddeaa10827ce803828","name":"Davide Passafaro","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2026\/05\/Immagine-profilo-GDE-430kb-100x100.png","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2026\/05\/Immagine-profilo-GDE-430kb-100x100.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2026\/05\/Immagine-profilo-GDE-430kb-100x100.png","caption":"Davide Passafaro"},"description":"My name is Davide Passafaro and I am Senior Frontend Engineer at Awork. I lead two developer communities in Rome, GDG Roma Citt\u00e0 and Angular Rome, and actively contribute to the tech community as a writer and speaker. When i shut down my computer I like to play board games and archery, not both together till now. I also like escape rooms and memes.","sameAs":["https:\/\/www.linkedin.com\/in\/davide-passafaro\/"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/davidepassafaro\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-600x400.png","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-600x600.png","author_info":{"display_name":"Davide Passafaro","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/davidepassafaro\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png",1080,608,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-150x150.png",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-300x169.png",300,169,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-768x432.png",768,432,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-1024x576.png",1024,576,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png",1080,608,false],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2.png",1080,608,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-100x100.png",100,100,true],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-180x128.png",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-896x504.png",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-400x225.png",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-600x400.png",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/image-2-600x600.png",600,600,true]},"uagb_author_info":{"display_name":"Davide Passafaro","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/davidepassafaro\/"},"uagb_comment_info":0,"uagb_excerpt":"During the latest months, Angular v17 has introduced a set of new function-based APIs focused on enhancing Signal integration within components and directives. This includes Signal Inputs, Model Inputs and Signal Queries. Considering the full picture, we are only missing one core API to conclude this journey, and this article is dedicated to precisely that:&#8230;&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/26864","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/200"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=26864"}],"version-history":[{"count":2,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/26864\/revisions"}],"predecessor-version":[{"id":26953,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/26864\/revisions\/26953"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/26900"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=26864"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=26864"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=26864"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=26864"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}