<?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: Tomasz Ducin</title>
    <description>The latest articles on DEV Community by Tomasz Ducin (@ducin).</description>
    <link>https://dev.to/ducin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1235019%2F8cecfa81-04ef-405f-860e-e08e3571ff7e.jpg</url>
      <title>DEV Community: Tomasz Ducin</title>
      <link>https://dev.to/ducin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ducin"/>
    <language>en</language>
    <item>
      <title>There are no simply "hot" Observables in RxJS</title>
      <dc:creator>Tomasz Ducin</dc:creator>
      <pubDate>Thu, 01 Feb 2024 12:47:13 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/there-are-no-hot-observables-in-rxjs-303i</link>
      <guid>https://dev.to/playfulprogramming-angular/there-are-no-hot-observables-in-rxjs-303i</guid>
      <description>&lt;p&gt;&lt;small&gt;Photo by &lt;a href="https://unsplash.com/@pawel_czerwinski?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Pawel Czerwinski&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/red-and-blue-wallpaper-6lQDFGOB1iw?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;So I caught your attention? 😈 Good! Because I want you to look at the &lt;em&gt;"HOT and COLD" Observables&lt;/em&gt; concept from a different perspective... it's one of the &lt;strong&gt;most confusing oversimplifications&lt;/strong&gt; I've had to deconstruct over and over again since quite a long time.&lt;/p&gt;

&lt;p&gt;Okay, to be fair... it is quite useful when we introduce RxJS to a &lt;strong&gt;complete beginner&lt;/strong&gt;. But as soon as they dive into real project usecases, e.g. &lt;strong&gt;late subscription&lt;/strong&gt; of a &lt;strong&gt;newly rendered&lt;/strong&gt; component that &lt;strong&gt;subscribes&lt;/strong&gt; to a (behavior? replay?) &lt;strong&gt;subject&lt;/strong&gt; which had &lt;strong&gt;already emitted something&lt;/strong&gt; - then the "&lt;em&gt;hot and cold&lt;/em&gt;" concept is... harmful.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/All_models_are_wrong" rel="noopener noreferrer"&gt;following aphorism&lt;/a&gt; illustrates it quite well:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;All models are wrong, but some are useful.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, I would add: &lt;em&gt;useful, but &lt;strong&gt;until a certain point!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://ducin.dev/there-are-no-simply-hot-observables-in-rxjs" rel="noopener noreferrer"&gt;👉 read original post and find more interesting content on my website&lt;/a&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Common ground
&lt;/h2&gt;

&lt;p&gt;Before we move on let's make sure we're all on the same page. What is a &lt;em&gt;hot observable&lt;/em&gt;? The &lt;a href="https://rxjs.dev/guide/glossary-and-semantics#hot" rel="noopener noreferrer"&gt;Rxjs.dev official docs&lt;/a&gt; define it the following way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;An observable is "hot", when its producer was created outside of the context of the subscribe action. [...]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some people &lt;/p&gt;

&lt;p&gt;⚠️ BTW there seems to be some &lt;em&gt;belief&lt;/em&gt; 😏 as if hot Observables are those Observables which "emit infinite amount of values". That's pure nonsense.&lt;/p&gt;

&lt;h2&gt;
  
  
  False dichotomy
&lt;/h2&gt;

&lt;p&gt;The "problem" with the "&lt;em&gt;hot and cold&lt;/em&gt;" concept is that it implicitly suggests that there are &lt;strong&gt;two types&lt;/strong&gt; of Observables. Only two. And yes, when you read the explanations (&lt;a href="https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html" rel="noopener noreferrer"&gt;like this legendary one by Thoughtram&lt;/a&gt;), you know that &lt;strong&gt;reality is more complex&lt;/strong&gt; 🙂 but when I join a team in order to do some &lt;a href="https://ducin.dev" rel="noopener noreferrer"&gt;frontend consultancy services&lt;/a&gt; (or run a &lt;a href="https://ducin.dev/trainings" rel="noopener noreferrer"&gt;Angular/Rx training&lt;/a&gt;), &lt;strong&gt;developers most often think in either-or&lt;/strong&gt;. Either hot or cold.&lt;/p&gt;

&lt;p&gt;I hope you are one of those truly passionate devs who dig into things, dive really deep, seek for understanding. You might already know that there are dozens of completely different types of "hot". But the majority of the industry isn't like this. &lt;strong&gt;We're all responsible for the concepts and metaphors we introduce&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So it depends on how we count these things... but as much as we dive into Rx internals, we'd find out there are &lt;strong&gt;at least 32 different types of hot streams&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  at least 32 different types of hot Observables? 😲
&lt;/h2&gt;

&lt;p&gt;Yep, you heard it right. In very short, 32 is a &lt;a href="https://en.wikipedia.org/wiki/Cartesian_product" rel="noopener noreferrer"&gt;Cartesian product&lt;/a&gt; of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 types of subjects (4)&lt;/li&gt;
&lt;li&gt;reset on error, boolean (2)&lt;/li&gt;
&lt;li&gt;reset on complete, boolean (2)&lt;/li&gt;
&lt;li&gt;reset on ref count 0, boolean (2)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
4*2*2*2 = 32&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we'd also take &lt;strong&gt;connectable streams&lt;/strong&gt; into account (&lt;a href="https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html" rel="noopener noreferrer"&gt;as in &lt;em&gt;Understanding publish, refCount and connect&lt;/em&gt;&lt;/a&gt;), there'd be even more  😈.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sh*t, what are all those things?! 😐
&lt;/h2&gt;

&lt;p&gt;These are separate characteristics of Subjects that have existed for a very long time already - and most probably you experienced them in some rather unclear circumstances, and haven't become aware of what's going on. For example, you might have noticed that, even though the &lt;strong&gt;reference counter&lt;/strong&gt; (number of active subscribers) have &lt;strong&gt;dropped to zero&lt;/strong&gt;, &lt;code&gt;share()&lt;/code&gt; used to recreate the underlying stream (e.g. a new HTTP request) whenever a new active subscription happened. &lt;strong&gt;But after replacing the &lt;code&gt;share()&lt;/code&gt; operator with &lt;code&gt;shareReplay()&lt;/code&gt;, it didn't&lt;/strong&gt;!. Even though the circumstances were the same... And this is NOT a specificity of either Subject or ReplaySubject. This is what so called "hot" is underneath. One term is just so wrong, if you want to get your head around it!&lt;/p&gt;
&lt;h2&gt;
  
  
  What? Please, stop 😥
&lt;/h2&gt;

&lt;p&gt;No worries, by the end you'd &lt;strong&gt;understand all of that&lt;/strong&gt;. Stay with me. And I hope you'd see that, indeed, "hot and cold" is a seriously harmful oversimplification.&lt;/p&gt;
&lt;h2&gt;
  
  
  First things first
&lt;/h2&gt;

&lt;p&gt;We need to remind a couple of facts.&lt;/p&gt;
&lt;h3&gt;
  
  
  Fact 1: Notification Types
&lt;/h3&gt;

&lt;p&gt;Observable streams don't just emit values. Strictly speaking, there are 3 types of notifications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;next(value)&lt;/li&gt;
&lt;li&gt;error(error)&lt;/li&gt;
&lt;li&gt;complete()
and all operators, subjects, etc - everything in Rx processes all of them. Sometimes they just pass the notification through down to the downstream, sometimes they do more interesting things - but all 3 notifications are always involved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F53o2w0dt75hyui9rzg3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F53o2w0dt75hyui9rzg3j.png" alt="3 types of notifications in RxJS" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Fact 2: Unicasting and Multicasting
&lt;/h3&gt;

&lt;p&gt;All streams can typically serve only one consumer - all operators, higher-order streams, etc. Being able to emit notifications only to one target is called &lt;strong&gt;Unicasting&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;... all, except for Subjects - these are the only ones which can serve multiple consumers (and it's actually the main point why they exist...). This "ability" is called &lt;strong&gt;Multicasting&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwmt2ujfmdxkb19txjh1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwmt2ujfmdxkb19txjh1.png" alt="RxJS Multicasting" width="800" height="579"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Fact 3: observables are lazy by default
&lt;/h3&gt;

&lt;p&gt;It's a quite well known fact that, until an observable gets subscribed to, it doesn't emit a value. That's fair, since why producing items, if there'd be no one to consume them? Only when they're is some subscriber interested in the data, it makes sense to produce and emit the notifications.&lt;/p&gt;

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

&lt;p&gt;Yep, &lt;strong&gt;produce&lt;/strong&gt;...&lt;/p&gt;
&lt;h3&gt;
  
  
  Fact 4: producer-consumer pattern
&lt;/h3&gt;

&lt;p&gt;Let's take a look at the following stream:&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;second$&lt;/span&gt; &lt;span class="o"&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="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With no subscribers, the observable emits no events. But once the first subscriber arrives, a new interval (native &lt;code&gt;setInterval&lt;/code&gt;) gets created. However, when another subscriber arrives, there'd be &lt;strong&gt;a separate, competing&lt;/strong&gt; interval.&lt;/p&gt;

&lt;p&gt;Certainly, observables are clearly lazy in this case. But what I also want to highlight is that a stream like this one:&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;second$&lt;/span&gt; &lt;span class="o"&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="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;isn't actually something which is capable of emitting anything. &lt;strong&gt;NOT YET&lt;/strong&gt;...&lt;/p&gt;

&lt;p&gt;Now, be cautious. The difference is not only with &lt;strong&gt;naming&lt;/strong&gt;, but also with &lt;strong&gt;semantics&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;observable&lt;/strong&gt; - is something we can observe (subscribe to). Clear.&lt;/p&gt;

&lt;p&gt;However, a stream is something that emits values. Now let's get back to the point in time when we had no subscribers: any interval hasn't been created &lt;strong&gt;YET&lt;/strong&gt;. So we've got composition, we've got a stream - but it's &lt;strong&gt;dead&lt;/strong&gt;. There's &lt;strong&gt;nothing live that could actually turn the stream on&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streams do implement the producer-consumer model&lt;/strong&gt;. Depending on the scenario, there might be either 1 producer per 1 subscriber (cold), or 1 producer per multiple subscribers (at least 32 types of hot). There could be even more complex, though very rare scenarios, where multiple producers use a common subject (sink, proxy) which then passed all notifications through to all subscribers (many-to-many).&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;producer&lt;/strong&gt; could be anything that is the source that start emitting anything: or could be an &lt;strong&gt;interval or a timer&lt;/strong&gt;, but also &lt;strong&gt;HTTP request, event listener, or a websocket connection&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fact Summary
&lt;/h2&gt;

&lt;p&gt;So a subject is &lt;strong&gt;multicasting&lt;/strong&gt; events down to &lt;strong&gt;multiple subscribers&lt;/strong&gt;. In a typical scenario there's &lt;strong&gt;one shared producer underneath&lt;/strong&gt; (could be more, but that's rare).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without any subject, the stream will unicast&lt;/strong&gt;. For each subscriber, a new producer would be created instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to 🔥 hot 32 🔥
&lt;/h2&gt;

&lt;p&gt;So far so good, we've got the knowledge to champion all the possibilities.&lt;/p&gt;

&lt;p&gt;All these apply to situations where we do have a subject ("hot", after all).&lt;/p&gt;

&lt;h3&gt;
  
  
  reset on error
&lt;/h3&gt;

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

&lt;p&gt;If &lt;strong&gt;any of the producers emits an &lt;code&gt;ERROR&lt;/code&gt; notification&lt;/strong&gt; down to the subject - &lt;strong&gt;should it reset&lt;/strong&gt;? Reconnect? Or - in our terminology - should a new producer be recreated?&lt;/p&gt;

&lt;h3&gt;
  
  
  reset on complete
&lt;/h3&gt;

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

&lt;p&gt;Similar as above, but applies to &lt;code&gt;COMPLETE&lt;/code&gt; notification.&lt;/p&gt;

&lt;h3&gt;
  
  
  reset on ref count zero
&lt;/h3&gt;

&lt;p&gt;Imagine the subject initially had no subscribers. Then first subscriber came, then the second one. The subject counts all active subscribers all the time. Now, the subscribers go away, and as they unsubscribe, the counter (&lt;strong&gt;ref count&lt;/strong&gt;) goes down.&lt;/p&gt;

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

&lt;p&gt;And the question arises: &lt;strong&gt;if the &lt;code&gt;refCount&lt;/code&gt; drops to zero&lt;/strong&gt; (no active subscribers), &lt;strong&gt;should we keep the connection to the producer active&lt;/strong&gt;? In other words - shall we keep the producer live?&lt;/p&gt;

&lt;p&gt;Remember, of the producer is live, it will keep on emitting items according to its nature (e.g. interval will keep on doing its job).&lt;/p&gt;

&lt;h2&gt;
  
  
  Where did you get these from?
&lt;/h2&gt;

&lt;p&gt;Now comes my favorite part 😁 - source code: let's dive into RxJS &lt;code&gt;ShareReplay&lt;/code&gt; sources. This one is especially good to look at, add it specifies config parameters exposed by the &lt;code&gt;share&lt;/code&gt; operator:&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;shareReplay&lt;/code&gt; is just a specialized version of &lt;code&gt;share&lt;/code&gt;. Apart from accepting config (as input parameters) and preparing the new config (to be passed to &lt;code&gt;share&lt;/code&gt;) - apart from that, &lt;code&gt;shareReplay()&lt;/code&gt; just calls &lt;code&gt;share()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;connector&lt;/code&gt; is a function that returns a subject - with whatever type, potentially even having some subscribers already (not common, though possible).&lt;/p&gt;

&lt;p&gt;And the &lt;code&gt;resetOnError&lt;/code&gt;, &lt;code&gt;resetOnComplete&lt;/code&gt; and &lt;code&gt;resetOnCountZero&lt;/code&gt; are things we've already gone through 🙃All in all, we can determine all these.&lt;/p&gt;

&lt;h1&gt;
  
  
  How important is reading the source code?
&lt;/h1&gt;

&lt;p&gt;Sometimes not that much. But this time - extremely important! Imagine all these situations where you use &lt;code&gt;share()&lt;/code&gt;/&lt;code&gt;shareReplay()&lt;/code&gt; and you hope &lt;em&gt;it should be ok&lt;/em&gt;. NO! Think about all these usecases, such as switching routes (navigation), potentially causing &lt;code&gt;refCount&lt;/code&gt; zero for a short while. Or receiving &lt;code&gt;complete&lt;/code&gt; which &lt;em&gt;might&lt;/em&gt; unintentionally break your app logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  How hot 🔥 are your streams?
&lt;/h2&gt;

&lt;p&gt;Being hot is about &lt;strong&gt;multicasting&lt;/strong&gt; (sharing the connection with the producer or, in practice, &lt;strong&gt;sharing the producer&lt;/strong&gt;). But I hope your agree with me that the following scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing the same producer no matter what&lt;/li&gt;
&lt;li&gt;and/or sharing the producer unless &lt;code&gt;RESET&lt;/code&gt; emitted&lt;/li&gt;
&lt;li&gt;and/or sharing the producer unless &lt;code&gt;COMPLETE&lt;/code&gt; emitted&lt;/li&gt;
&lt;li&gt;and/or sharing unless all subscribers are gone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... all have &lt;strong&gt;completely different runtime behavior&lt;/strong&gt;. Failing to acknowledge the difference might lead to serious bugs and/or unintentional behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  One more case
&lt;/h2&gt;

&lt;p&gt;As previously said, there are more than 32 different types of "hotness". How come? We already mentioned &lt;a href="https://rxjs.dev/api/index/function/connectable" rel="noopener noreferrer"&gt;connectable observables&lt;/a&gt;. But there's one more, &lt;strong&gt;slightly exotic, though technically doable&lt;/strong&gt;. And that is: an observable that gets the values from a producer who has been created totally outside of the context of any observables whatsoever. Imagine just a producer which, whenever creating a new thing, it calls a function - it will keep on doing that no matter if any observables and/or subscribers are there or not. If a new subscriber arrives, the void function just gets replaced (or added, depending on the implementation) to feed the subscriber. Anyway, the lifespan of the producer doesn't depend on subscribers and, especially, &lt;em&gt;producer is not created within the subscription context&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That's just an exotic example, but all in all, don't stick to the &lt;code&gt;32&lt;/code&gt; number. Remember that &lt;strong&gt;there are dozens of different flavors of "&lt;em&gt;hotness&lt;/em&gt;"&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;The terms &lt;strong&gt;unicasting&lt;/strong&gt;/&lt;strong&gt;multicasting&lt;/strong&gt; precisely define whether a subject is being used or not. Only this is already way more precise than "&lt;em&gt;cold and hot&lt;/em&gt;" distinction.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;cold stream is a lazy, unicasted stream&lt;/strong&gt; which &lt;strong&gt;creates a new producer per each subscriber.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But when it comes to hot streams, they &lt;strong&gt;could be lazy&lt;/strong&gt; or not (remember &lt;em&gt;Connectable&lt;/em&gt;), they &lt;strong&gt;could share the producer&lt;/strong&gt; unless some circumstances happen. Last but not least, &lt;strong&gt;different subject types&lt;/strong&gt; apply completely different emission strategies. It's all so damn different that it's pure madness to throw it all into one bag. One bag that discourages many people from diving deeper.&lt;/p&gt;

&lt;p&gt;So now, whenever you need to introduce a Subject, don't just choose between &lt;code&gt;share()&lt;/code&gt; and &lt;code&gt;shareReplay&lt;/code&gt; (also trying to figure out why is there no &lt;code&gt;shareBehavior()&lt;/code&gt; one?!). Think about all 32 conditions - one of those is the one you're looking for, e.g&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;stream$&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;share&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;connector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BehaviorSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INITIAL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;resetOnError&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="na"&gt;resetOnComplete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resetOnRefCountZero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;And when we revisit the official definition of a "&lt;em&gt;hot observable&lt;/em&gt;":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;An observable is "hot", when its producer was created outside of the context of the subscribe action. [...]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the definition determines &lt;strong&gt;neither the behavior nor the lifespan&lt;/strong&gt; of the producer, which make a &lt;strong&gt;huge difference&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My strong recommendation&lt;/strong&gt;: as soon as one has grasped the idea of Observables, use more precise terms and &lt;strong&gt;stop using the ambiguous &lt;em&gt;"hot" (and cold) streams&lt;/em&gt; metaphor&lt;/strong&gt;. It introduces false dichotomy and pretends that &lt;strong&gt;things are simple&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The more we know, the more we understand they aren't.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  I want to give special thanks to &lt;a href="https://twitter.com/niklas_wortmann" rel="noopener noreferrer"&gt;Jan-Niklas Wortmann&lt;/a&gt; and &lt;a href="https://twitter.com/cytrowski" rel="noopener noreferrer"&gt;Bartosz Cytrowski&lt;/a&gt; for proof reading this article 💪
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/tomasz_ducin" rel="noopener noreferrer"&gt;Follow me on twitter&lt;/a&gt; for more frontend (js, ts, react, angular etc.) deep dives!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Should .ng component authoring format get dropped? 😱</title>
      <dc:creator>Tomasz Ducin</dc:creator>
      <pubDate>Fri, 26 Jan 2024 10:12:48 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/should-ng-component-authoring-format-get-dropped-45kc</link>
      <guid>https://dev.to/playfulprogramming-angular/should-ng-component-authoring-format-get-dropped-45kc</guid>
      <description>&lt;p&gt;There's been quite some fire around the .ng component authoring format, introduced as experimental in AnalogJS meta-framework. You can listen more about it here:&lt;/p&gt;

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

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



 &lt;/p&gt;

&lt;p&gt;TL;DR; the community seems pretty divided. I don't want to state my opinion here, and I'm last to judge. But the fact is: a lot of hard work has been put into the experiment and, due to some controversies, the AnalogJS team is planning to drop the support entirely.&lt;/p&gt;

&lt;p&gt;Do you think it's a good idea?&lt;/p&gt;

&lt;p&gt;Vote in the poll&lt;/p&gt;

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

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



 &lt;/p&gt;

&lt;p&gt;and &lt;a href="https://github.com/analogjs/analog/pull/869" rel="noopener noreferrer"&gt;leave a comment under the PR&lt;/a&gt;. Thanks!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>analog</category>
    </item>
    <item>
      <title>Signals are VALUES, not EVENTS</title>
      <dc:creator>Tomasz Ducin</dc:creator>
      <pubDate>Thu, 18 Jan 2024 22:35:00 +0000</pubDate>
      <link>https://dev.to/ducin/signals-are-values-not-events-10bn</link>
      <guid>https://dev.to/ducin/signals-are-values-not-events-10bn</guid>
      <description>&lt;p&gt;Recent release of &lt;a href="https://github.com/angular/angular/releases/tag/17.1.0"&gt;Angular 17.1&lt;/a&gt; (yesterday, 18th January 2024), introduces &lt;strong&gt;Signal Inputs&lt;/strong&gt; (&lt;a href="https://dev.to/this-is-angular/diving-into-type-system-behind-angular-signal-inputs-2b88"&gt;read more about Angular Signal Input API here&lt;/a&gt;):&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;It's a good opportunity to rethink &lt;strong&gt;migrating from RxJS to Signals,&lt;/strong&gt; as more and more APIs are signal-based: the framework (&lt;a href="https://angular.io/guide/signals"&gt;signals, computeds, effects&lt;/a&gt; and the &lt;a href="https://angular.io/guide/rxjs-interop"&gt;rxjs-interop&lt;/a&gt;) and ecosystem (&lt;a href="https://ngrx.io/guide/signals/signal-store"&gt;NGRX signal store&lt;/a&gt;), as well as tons of experiments (&lt;a href="https://github.com/nartc/ngxtension-platform/pull/229"&gt;such as this one&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Photo by &lt;a href="https://unsplash.com/@alinnnaaaa?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Alina Grubnyak&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/low-angle-photography-of-metal-structure-ZiQkhI7417A?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




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

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



 &lt;/p&gt;

&lt;p&gt;The amount of positive reception of above tweet made me realize this topic &lt;strong&gt;needs more attention among the Angular community&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On one hand, we've all heard that &lt;strong&gt;signals won't &lt;em&gt;entirely&lt;/em&gt; replace RxJS&lt;/strong&gt; (especially that Angular is on the road to make RxJS optional in the future). On the other hand, the &lt;strong&gt;new reactive primitive&lt;/strong&gt; is taking the ecosystem by storm and, no wonder, it's easy to lose touch with the design principles and start &lt;strong&gt;overusing&lt;/strong&gt; signals everywhere. Just like redux used to be &lt;strong&gt;abused&lt;/strong&gt; at some point. Or like Observable Streams used to be &lt;strong&gt;abused&lt;/strong&gt;. Are we gonna share Georg Hegel's view, that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"&lt;em&gt;We learn from history that we don't learn from history.&lt;/em&gt;"&lt;/p&gt;
&lt;/blockquote&gt;

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

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



 &lt;/p&gt;

&lt;p&gt;&lt;small&gt;okay no more my tweets 😇&lt;/small&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Micro disclaimer
&lt;/h2&gt;

&lt;p&gt;I enjoy using signals, I enjoy using rxjs observables - so I'm no pro/against in any way. Also I enjoy using &lt;a href="https://mobx.js.org"&gt;MobX&lt;/a&gt; (doesn't &lt;a href="https://mobx.js.org/api.html"&gt;MobX API&lt;/a&gt; look familiar to you? 🙃), I enjoy &lt;a href="https://baconjs.github.io/"&gt;bacon&lt;/a&gt;... I enjoy pretty much all the tools that help me get my job done. My intention in this post to emphasize, again, that &lt;strong&gt;every tool has it's certain usecases&lt;/strong&gt;. And that &lt;strong&gt;excitement is the worst factor that could drive decision making in software development&lt;/strong&gt;. Cool down 🥶&lt;/p&gt;
&lt;h2&gt;
  
  
  Facts
&lt;/h2&gt;

&lt;p&gt;Let's start with revisiting the fundamental characteristics of signals and observable streams (they're mostly well known, so I'll just list them down):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sync/async

&lt;ul&gt;
&lt;li&gt;observables can do both &lt;strong&gt;sync and async&lt;/strong&gt; processing&lt;/li&gt;
&lt;li&gt;current signals implementation is capable of &lt;strong&gt;sync processing only&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;as a consequence, signals are &lt;strong&gt;unaware of the passage of time&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;some APIs will always be async&lt;/strong&gt; no matter what we prefer or believe in &lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt;, such as HTTP or browser events

&lt;ul&gt;
&lt;li&gt;replacing decorated &lt;code&gt;@Output()&lt;/code&gt; with signal-based &lt;code&gt;output()&lt;/code&gt; (not yet in v17.1) will be purely syntactic sugar, as events will be emitted underneath nevertheless&lt;/li&gt;
&lt;li&gt;squashing async processing into sync signals generates &lt;a href="https://twitter.com/tomasz_ducin/status/1746996356210684129"&gt;some non-trivial questions&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;subscriptions

&lt;ul&gt;
&lt;li&gt;RxJS requires manual (un)subscription handling&lt;/li&gt;
&lt;li&gt;signals handle (un)subscription 100% automatically&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;late subscriptions

&lt;ul&gt;
&lt;li&gt;both APIs handle late subscriptions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;values/emissions

&lt;ul&gt;
&lt;li&gt;signal &lt;strong&gt;always has a value&lt;/strong&gt; (like in &lt;code&gt;BehaviorSubject&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;observable streams &lt;strong&gt;might have values&lt;/strong&gt;, but streams with no emissions whatsoever are absolutely valid(&lt;code&gt;-------&amp;gt;&lt;/code&gt; - no &lt;code&gt;next&lt;/code&gt;, no &lt;code&gt;error&lt;/code&gt;, no &lt;code&gt;complete&lt;/code&gt;, nothing)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;re-implementing&lt;/strong&gt; RxJS features as signals one by one (like operators, subjects etc.) &lt;strong&gt;makes barely any sense&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;API

&lt;ul&gt;
&lt;li&gt;RxJS has ~100 operators, 4 subject types, 32 types of hot observables (expect a blogpost soon! 🔥), all unicasting/multicasting concepts, etc.&lt;/li&gt;
&lt;li&gt;signals have barely ~10 functions (signal, set, update, computed, effect, untracked, asReadonly, toSignal, toObservable, perhaps something more). Order of magnitude difference...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Readability
&lt;/h2&gt;

&lt;p&gt;I'll be honest - when people say they find something readable or not... or easy... or simple... I tell you: I don't care much 😉 people often forget that we have different background and experience. That readability has no way to be measured, and is purely 100% subjective. Like, my mother tongue is Polish and, surprise surprise, I can understand quite a lot from other Slavic languages. So what? So nothing. It would be strange if I didn't 🤷.&lt;/p&gt;

&lt;p&gt;And same here. I love signals from the first day. But that's mainly because I have commercial experience in MobX which is, conceptually, 1:1. For every person, a thing being readable or not is ultimately subjective and - my tiny recommendation here: don't pay too much attention to &lt;em&gt;readability&lt;/em&gt;. Unless you like &lt;a href="https://en.wikipedia.org/wiki/Law_of_triviality"&gt;bikeshedding&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Missing piece of understanding
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/synalx"&gt;Alex&lt;/a&gt; has once described signals the following way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A signal is a source of value.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That makes perfect sense. However, if I asked you the following question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What a signal is &lt;strong&gt;NOT&lt;/strong&gt;? What shall &lt;strong&gt;NOT&lt;/strong&gt; be represented as a signal?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What would be your answer?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/tomasz_ducin/status/1747610779065421843"&gt;Coding itself is rather simple, but software design is not&lt;/a&gt;. If we pick a &lt;a href="https://twitter.com/tomasz_ducin/status/1747676969343373539"&gt;wrong abstraction&lt;/a&gt; and keep on implementing things on top of it, then despite that our code might work as expected, we'd see things are unnecessarily harder than they should be. Within time we'd start fighting our code and design, more and more, and feel the need to refactor/rewrite some piece of an app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what a signal is NOT&lt;/strong&gt;? I suggest one of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;something that &lt;strong&gt;doesn't have a current value&lt;/strong&gt;, e.g. user events, browser events&lt;/li&gt;
&lt;li&gt;something that &lt;strong&gt;has a current value, but it's completely irrelevant&lt;/strong&gt;, an action that a user wants to reload a data-table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I want to draw a boundary between &lt;strong&gt;VALUES&lt;/strong&gt; and &lt;strong&gt;EVENTS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;All in all, I would rephrase the definition to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A signal is a source of value, but NOT a source of events.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Values are some DETAILS, characteristics that a thing can have
&lt;/h2&gt;

&lt;p&gt;We can always ask (&lt;em&gt;pull-based&lt;/em&gt;) what the value is. We can also be notified about a value which has changed (&lt;em&gt;push-based&lt;/em&gt;). That's why RxJS is a valid abstraction around pretty much everything that exists 😉. But still, &lt;strong&gt;if something has a value, you can always ask for it&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Events describe what has already HAPPENED or what will happen
&lt;/h2&gt;

&lt;p&gt;The events, on the other hand, are meant to notify (&lt;em&gt;push-based&lt;/em&gt;) others about something that happened. There is an important distinction between &lt;a href="https://en.wikipedia.org/wiki/Event_(computing)"&gt;&lt;strong&gt;events&lt;/strong&gt;&lt;/a&gt; (something has happened already) and &lt;a href="https://en.wikipedia.org/wiki/Command_pattern"&gt;&lt;strong&gt;commands&lt;/strong&gt;&lt;/a&gt; (something will happen and we pass a command to be executed) but it's a topic for another post.&lt;/p&gt;

&lt;p&gt;The distinction between &lt;strong&gt;VALUES&lt;/strong&gt; and &lt;strong&gt;EVENTS&lt;/strong&gt; is very clearly expressed in the &lt;em&gt;original&lt;/em&gt; &lt;code&gt;redux&lt;/code&gt; store API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;STATE&lt;/span&gt; &lt;span class="c1"&gt;// pull-based value accessor&lt;/span&gt;
&lt;span class="nx"&gt;store&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="nx"&gt;FN&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="c1"&gt;// push-based value accessor&lt;/span&gt;
&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ACTION&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="c1"&gt;// push-based event notification&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Couldn't events be values or vice versa?
&lt;/h2&gt;

&lt;p&gt;Someone might deny:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hey, but &lt;strong&gt;events&lt;/strong&gt; are objects, they might have payloads, and what is a payload if not a &lt;strong&gt;value&lt;/strong&gt;?! (object, primitive, whatever)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sure. Technically - yes, absolutely. But, taken to extreme, everything is a value. Even your mouse cursor's coordinate is a value. But when we do &lt;strong&gt;design&lt;/strong&gt;, we want to create mental models that are &lt;strong&gt;pragmatic&lt;/strong&gt;, help us &lt;strong&gt;put things in order&lt;/strong&gt;, and &lt;strong&gt;make other devs comfortable&lt;/strong&gt; within the design that we leave. Taking things to extreme doesn't help.&lt;/p&gt;

&lt;p&gt;It all depends on the &lt;strong&gt;terminology&lt;/strong&gt; we use and the &lt;strong&gt;context&lt;/strong&gt; of our &lt;strong&gt;reasoning&lt;/strong&gt;, so - &lt;em&gt;could events be values&lt;/em&gt; - both yes and both no.&lt;/p&gt;

&lt;p&gt;My strong recommendation is to focus on what is the &lt;strong&gt;intention&lt;/strong&gt; of how are we going to use a thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;are we going to access details of something (value)? or&lt;/li&gt;
&lt;li&gt;do we get notified that something has happened (or will happen)?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Community-driven signals APIs
&lt;/h2&gt;

&lt;p&gt;There would certainly be more and more signal-based APIs. It's worthwhile to consider which of the make sense and which don't. &lt;a href="https://twitter.com/mfpears"&gt;Mike&lt;/a&gt; sums it up perfectly:&lt;/p&gt;

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

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



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

&lt;p&gt;I want to focus on just ONE example, but do it very deep. In the react world (where I come from 😜) one of the mindshifting blogposts is &lt;a href="https://twitter.com/dan_abramov2"&gt;Dan Abramov&lt;/a&gt;'s &lt;a href="https://overreacted.io/making-setinterval-declarative-with-react-hooks/"&gt;&lt;em&gt;Making setInterval Declarative with React Hooks&lt;/em&gt;&lt;/a&gt;. I decided to pick &lt;code&gt;setInterval&lt;/code&gt; as well.&lt;/p&gt;

&lt;p&gt;So, could you make an async interval signal? Technically, yes, of course:&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;function&lt;/span&gt; &lt;span class="nf"&gt;intervalSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&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;idx&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&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="nx"&gt;idx&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&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="nx"&gt;interval&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;idx&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But should you? No. &lt;strong&gt;Totally No&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; Because, although technically we could easily make things work, we're mixing abstractions badly. &lt;strong&gt;Mixing abstractions will always have some shortcomings&lt;/strong&gt;. What are these?&lt;/p&gt;

&lt;h3&gt;
  
  
  Missing support
&lt;/h3&gt;

&lt;p&gt;We're also missing support for potentially important aspects. I hope many of you already thought: &lt;em&gt;why aren't you cleaning up the signal?!&lt;/em&gt; Great, so here we go:&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;function&lt;/span&gt; &lt;span class="nf"&gt;intervalSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&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;idx&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&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="nx"&gt;idx&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&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="nx"&gt;interval&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="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&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="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;idx&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;but hey, our implementation more complex and, as a consequence, longer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixes. Fixes everywhere.
&lt;/h3&gt;

&lt;p&gt;Have you noticed, that if we expose a &lt;code&gt;WritableSignal&lt;/code&gt; (signal still includes the &lt;code&gt;.set&lt;/code&gt;) method, then we're leaking encapsulation - probably overwriting the current &lt;em&gt;tick&lt;/em&gt; shouldn't be possible from outside of the signal. So, instead, it should be:&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&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="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asReadonly&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;But, trust me, we haven't exhausted all edge cases yet 😈&lt;/p&gt;

&lt;h3&gt;
  
  
  Signal Interval is pretending to be time-aware
&lt;/h3&gt;

&lt;p&gt;In the last version of the signal (interval + cleanup + asReadonly) there's still no simple API that allows us to modify the interval (time) length. In RxJS we could simply use a &lt;code&gt;switchMap&lt;/code&gt; which consumes the interval upstream:&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;intervalLength$&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;switchMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeLength&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeLength&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;Again, could we achieve the similar API with signals? Of course! (but I'm not falling down the rabbit hole 😏). Anyway, as the signal code gets more complex:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we should take potential edge cases into account, right? And most probably we're bikeshedding and it's far away from the business solutions we're expected to work on...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  API design
&lt;/h3&gt;

&lt;p&gt;We also need to &lt;a href="https://twitter.com/tomasz_ducin/status/1747610779065421843"&gt;carefully design APIs (again)&lt;/a&gt;. Potential breaking changes come into play. Also, how much of your application code should re responsible for platform-related things, like intervals, events, HTTP, etc?&lt;/p&gt;

&lt;p&gt;In case of changing the interval length, should we go one more setter callback?&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;function&lt;/span&gt; &lt;span class="nf"&gt;intervalSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;signal&lt;/span&gt;&lt;span class="p"&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="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;cleanup&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;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;setIntervalTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This seems simple, but the signal API has become rather callback-based. Perhaps wrapping interval with a signal would look better to use signals more:&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;function&lt;/span&gt; &lt;span class="nf"&gt;intervalSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;valueSignal&lt;/span&gt;&lt;span class="p"&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="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;cleanup&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;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;intervalTimeSignal&lt;/span&gt;&lt;span class="p"&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which one is better?&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrong Abstractions, AGAIN
&lt;/h3&gt;

&lt;p&gt;There's one important thing we will consider 😄 there might be situations, where we need to process values of the signals and a &lt;code&gt;signal&lt;/code&gt;/&lt;code&gt;computed&lt;/code&gt; fits here, since it can notify computeds further. But other times, it's fairly enough to make it an &lt;code&gt;effect&lt;/code&gt;, as the consumption would be placed within the effect function and there would be no further dependencies (nobody would have to react to the effect taking place. Potentially that could have been a better choice from the beginning...&lt;/p&gt;

&lt;p&gt;However, we can't guarantee that &lt;code&gt;effect&lt;/code&gt;s would be better than &lt;code&gt;signal&lt;/code&gt;s in all cases.&lt;/p&gt;

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

&lt;p&gt;Can you see, how many problems we're solving, which don't relate to our commercial project? 😐&lt;/p&gt;

&lt;p&gt;I hope we all clearly see that: &lt;strong&gt;if the problem-solution abstractions don't fit well, better not to implement the solution at all&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What's the conclusion? If a concept is beyond signals (doesn't fit there), like time, or events - &lt;strong&gt;don't make signals wrap it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, to sum it all up - what is the most important factor that differentiates &lt;strong&gt;VALUES&lt;/strong&gt; from &lt;strong&gt;EVENTS&lt;/strong&gt;? It's &lt;strong&gt;&lt;em&gt;TIME&lt;/em&gt;&lt;/strong&gt;. &lt;strong&gt;VALUES&lt;/strong&gt; don't care about time. &lt;strong&gt;EVENTS&lt;/strong&gt; do.&lt;/p&gt;

&lt;p&gt;Pay attention to time. As time is running out. ☠️&lt;/p&gt;




&lt;p&gt;&lt;a href="https://twitter.com/tomasz_ducin"&gt;Follow me on twitter&lt;/a&gt; for more frontend (js, ts, react, angular etc.) deep dives!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>architecture</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Angular @defer Interactive Examples</title>
      <dc:creator>Tomasz Ducin</dc:creator>
      <pubDate>Thu, 04 Jan 2024 15:12:01 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/angular-defer-interactive-examples-10mn</link>
      <guid>https://dev.to/playfulprogramming-angular/angular-defer-interactive-examples-10mn</guid>
      <description>&lt;p&gt;One of the Angular 17 awesome features shipped is the &lt;strong&gt;defer block&lt;/strong&gt; which allows to &lt;strong&gt;lazy load components, directives and pipes&lt;/strong&gt;, while configuring it on the &lt;strong&gt;template level&lt;/strong&gt; via &lt;code&gt;@defer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you already know the theory and want to &lt;strong&gt;get your hands dirty&lt;/strong&gt; with &lt;code&gt;@defer&lt;/code&gt;, here's an app you can see various usecases and combinations:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://ducin.github.io/angular-defer" rel="noopener noreferrer"&gt;ducin.github.io/angular-defer&lt;/a&gt;
&lt;/h1&gt;

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

&lt;p&gt;See how does application runtime and user interaction trigger &lt;code&gt;@defer&lt;/code&gt; and what certain bundles get loaded into the browser.&lt;/p&gt;

&lt;p&gt;It includes:&lt;/p&gt;

&lt;p&gt;⚡️ components, directives, pipes&lt;br&gt;
⚡️ multiple triggers and their combinations&lt;br&gt;
⚡️ practical usecases (🪗 accordion, 📦 npm package and many more)&lt;br&gt;
⚡️ analyze with devtools&lt;br&gt;
⚡️ explanations included&lt;/p&gt;

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

&lt;p&gt;Usecases implemented:&lt;br&gt;
⚡️ when condition: &lt;code&gt;@defer (when isVisible) {...}&lt;/code&gt;&lt;br&gt;
⚡️ on idle: &lt;code&gt;@defer (on idle) {...}&lt;/code&gt;&lt;br&gt;
⚡️ on viewport: &lt;code&gt;@defer (on viewport) {...}&lt;/code&gt;&lt;br&gt;
⚡️ on interaction: &lt;code&gt;@defer (on interaction) {...}&lt;/code&gt;&lt;br&gt;
⚡️ on hover: &lt;code&gt;@defer (on hover) {...}&lt;/code&gt;&lt;br&gt;
⚡️ on immediate: &lt;code&gt;@defer (on immediate) {...}&lt;/code&gt;&lt;br&gt;
⚡️ on timer: &lt;code&gt;@defer (on timer(2000ms)) {...}&lt;/code&gt;&lt;br&gt;
🪗 accordion: &lt;code&gt;@defer (on hover(accordion); on timer(5s)) {...}&lt;/code&gt; (&lt;strong&gt;before&lt;/strong&gt; accordion section gets clicked)&lt;br&gt;
👫 multiple deferrable&lt;br&gt;
📦 npm package: &lt;code&gt;&amp;lt;link rel="modulepreload" href="chunk-BYHJVGJ4.js"&amp;gt;&lt;/code&gt;&lt;br&gt;
🗃️ nested defer: &lt;code&gt;@defer (on timer(2s)) { @defer (on interaction) {...} }&lt;/code&gt;&lt;br&gt;
⏱️ prefetch: &lt;code&gt;@defer (on interaction; prefetch on idle) {...}&lt;/code&gt;&lt;br&gt;
🚚 loading vs placeholder: &lt;code&gt;placeholder (minimum 500ms) {...}&lt;/code&gt; &amp;amp; &lt;code&gt;@loading (minimum 1s; after 10ms) {...}&lt;/code&gt;&lt;br&gt;
💥 defer error: &lt;code&gt;@error {...}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So open your browser devtools &lt;code&gt;Network&lt;/code&gt; tab and have a play with the interactive examples 💪&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/tomasz_ducin" rel="noopener noreferrer"&gt;Follow me on twitter&lt;/a&gt; for more frontend (js, ts, react, angular etc.) deep dives!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
      <category>architecture</category>
      <category>performance</category>
    </item>
    <item>
      <title>Diving into Type System behind Angular Signal Inputs</title>
      <dc:creator>Tomasz Ducin</dc:creator>
      <pubDate>Thu, 28 Dec 2023 22:20:41 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/diving-into-type-system-behind-angular-signal-inputs-2b88</link>
      <guid>https://dev.to/playfulprogramming-angular/diving-into-type-system-behind-angular-signal-inputs-2b88</guid>
      <description>&lt;p&gt;&lt;em&gt;Original version of this writing has been published as a &lt;a href="https://twitter.com/tomasz_ducin/status/1740150999770378592" rel="noopener noreferrer"&gt;twitter thread&lt;/a&gt;. However, I was convinced by &lt;a class="mentioned-user" href="https://dev.to/eneajaho"&gt;@eneajaho&lt;/a&gt; to convert it into a blogpost&lt;/em&gt; 😎. &lt;em&gt;I decided to leave the original form: quick, easy-going and concise.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;As you may know, &lt;strong&gt;Signal Inputs&lt;/strong&gt; are coming to Angular in mid January 2024 in version 17.1. But we can actually play with them already, or at least, take a look at their &lt;em&gt;almost public&lt;/em&gt; API. In this post we'll take a deep dive into the type design of Signal Inputs internals, its consequences, and a lot of examples of Signal Inputs usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo code
&lt;/h2&gt;

&lt;p&gt;We're gonna expose what the Angular Team has hidden from us...&lt;/p&gt;

&lt;p&gt;🪄 &lt;strong&gt;the trick is&lt;/strong&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;ɵinput&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;input&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;don't do this at home 😈!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Following stackblitz allows you to see Signal Input declarations. Note that there's no Signal Input implementation within angular as of now (&lt;code&gt;v17.1.0-next.5&lt;/code&gt;), so we'll focus on declarations/public API only.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/angular-signal-inputs?embed=1&amp;amp;file=src%2Fmain.ts&amp;amp;view=editor" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  ToC
&lt;/h2&gt;

&lt;p&gt;🛠️ first - examples&lt;br&gt;
🥩 then - internals&lt;/p&gt;

&lt;p&gt;We'll analyze the examples from above stackblitz one by one, and later we'll analyze the internals &amp;amp; types underneath.&lt;/p&gt;
&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;We'll start with lots of examples. Take a look at the first one:&lt;/p&gt;

&lt;p&gt;🔍 initial value is used to infer the input's type, same as with ordinary signals:&lt;/p&gt;

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

&lt;p&gt;⚠️ Input Signals are &lt;strong&gt;READONLY&lt;/strong&gt;, which makes sense, since it's the parent component who can put new values (via templates) into the input signal, not us 😉&lt;/p&gt;

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

&lt;p&gt;One of my favorite design decisions:&lt;br&gt;
💪 taking advantage of (1) #typescript's possibilities and (2) applying best solutions from other frameworks. In this case: from React&lt;/p&gt;

&lt;p&gt;💜🩷💜 love it 🩷💜🩷&lt;/p&gt;

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

&lt;p&gt;Less exciting - and &lt;strong&gt;IMHO&lt;/strong&gt; it should be &lt;strong&gt;&lt;em&gt;avoided as much as possible&lt;/em&gt;&lt;/strong&gt; (since it decreases readability and the understanding of how components exchange data) - &lt;strong&gt;aliasing&lt;/strong&gt; is allowed:&lt;/p&gt;

&lt;p&gt;📡 aliased name is used by parent to pass the data&lt;br&gt;
🔐 the prop name is used internally (obviously)&lt;/p&gt;

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

&lt;p&gt;Another logical design decision:&lt;br&gt;
💪 since an input is &lt;strong&gt;REQUIRED&lt;/strong&gt;, passing initial value makes no sense 😉 so it's removed from the signature&lt;/p&gt;

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

&lt;p&gt;Here the &lt;code&gt;initialValue&lt;/code&gt; parameter is removed from the function (overload) signature. Or to be more precise - it's never added (never allowed) to be there 😉&lt;/p&gt;

&lt;p&gt;So, technically speaking, TypeScript would try to pass your initial as options object which obviously fails.&lt;/p&gt;

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

&lt;p&gt;And one more example - &lt;code&gt;transform&lt;/code&gt; is allowed only when passing both &lt;code&gt;ReadT&lt;/code&gt; and &lt;code&gt;WriteT&lt;/code&gt; type parameters. More on this later...&lt;/p&gt;

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

&lt;p&gt;Now let's see 🍖 some internals 🥩&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlup1h47o9ojcekmrjpi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlup1h47o9ojcekmrjpi.gif" alt="signal internals code" width="220" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get a broad overview of the direction, you might be interested in taking a look at the ➡️ &lt;a href="https://github.com/angular/angular/discussions/49682" rel="noopener noreferrer"&gt;Angular Team's &lt;em&gt;Sub-RFC 3: Signal-based Components&lt;/em&gt;&lt;/a&gt; which deals with, more or less, how to make use of signals in Angular Components. Also, you can ➡️ &lt;a href="https://github.com/angular/angular/tree/main/packages/core/src/authoring" rel="noopener noreferrer"&gt;take a look at the code itself&lt;/a&gt;. Anyway, let's dive into the internals!&lt;/p&gt;

&lt;p&gt;We've got 2 new signal symbols:&lt;/p&gt;

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

&lt;p&gt;it's the same usecase, as with the former unique Signal symbol - it allows to restrict compatibility across different (input) signals.&lt;/p&gt;

&lt;p&gt;For instance:&lt;br&gt;
✅ one can assign the &lt;code&gt;InputSignal&amp;lt;number, number&amp;gt;&lt;/code&gt; to an ordinary &lt;code&gt;Signal&amp;lt;number&amp;gt;&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Proof:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;need to make ordinary signal &lt;strong&gt;READONLY&lt;/strong&gt; so that TS compares 2 readonly signals (input signals are &lt;strong&gt;READONLY&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;where a string signal is expected, a string input signal is acceptable, since it has all required (needed) properties.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ but the other way round it fails, since an ordinary string signal doesn't have the brand read/write signals.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Reassigning signals, however, is not going to be anyhow common 😉. But the Angular compiler also makes use of the symbols internally.&lt;/p&gt;

&lt;p&gt;Now, this is where we get the signals API from. There's a completely &lt;strong&gt;separate implementation&lt;/strong&gt; for optional and required inputs. It's just exposed as a convenient API:&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;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The sad thing, however, is that currently we cannot see its runtime.&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;disclaimer: as mentioned above, ng v17.1 is expected very soon, this analysis uses &lt;code&gt;v17.0.1-next.5&lt;/code&gt;&lt;/em&gt;).&lt;/p&gt;

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

&lt;p&gt;Now let's take a look back at input transform:&lt;/p&gt;

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

&lt;p&gt;However, you might be wondering what the heck is going on with this function overload and the strange declaration at the bottom:&lt;/p&gt;

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

&lt;p&gt;First of all, if we pass &lt;code&gt;&amp;lt;ReadT&amp;gt;&lt;/code&gt; only, we &lt;strong&gt;can't&lt;/strong&gt; pass the input transform (that's the same as with current&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;Input&lt;/span&gt;
&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;transform&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;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvh6khfgiz8nt3160li1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvh6khfgiz8nt3160li1v.png" alt="signal internals code" width="800" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, if we pass &lt;strong&gt;both&lt;/strong&gt; &lt;code&gt;&amp;lt;ReadT, WriteT&amp;gt;&lt;/code&gt;, we can additionally pass the transform. Note that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ReadT&lt;/code&gt; is the expression type you want to use inside your component&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WriteT&lt;/code&gt; is the expression type that is passed from outside&lt;/li&gt;
&lt;/ul&gt;

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

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

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

&lt;p&gt;Going back to our nice declaration 🥴 let's focus on &lt;code&gt;inputFunction&lt;/code&gt; first:&lt;/p&gt;

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

&lt;p&gt;It has 3 overloads on its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;take no initial value and extend inner value with undefined&lt;/li&gt;
&lt;li&gt;take the initial value with &lt;code&gt;ReadT&lt;/code&gt; type param only (opts WITHOUT transform)&lt;/li&gt;
&lt;li&gt;take the initial value with both &lt;code&gt;ReadT, WriteT&lt;/code&gt; type params (opts WITH transform)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All usecases seen before 😎💪&lt;/p&gt;

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

&lt;p&gt;All in all we've got 3 overloads for the &lt;code&gt;prop = input()&lt;/code&gt; (optional)&lt;br&gt;
... and 2 overloads for the &lt;code&gt;prop = input.required()&lt;/code&gt; (required)&lt;/p&gt;

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

&lt;p&gt;Phew 😅 that was quite a lot. Hope you enjoyed that.&lt;/p&gt;

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

&lt;p&gt;We've seen quite a few examples on how certain usage of input signals affect underlying TypeScript types. Each usage depends on your specific needs in a specific situation. However, you should always pay attention to what types get declared/inferred in each case, as type-safety is one of the most important factors that form overall code quality.&lt;/p&gt;

&lt;p&gt;Underlying Signal Input types are very well defined, but it's always your responsibility to verify, whether a given input should be optional or required in the long run. &lt;strong&gt;Types should only reflect your design&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remember you can play with it &lt;a href="https://stackblitz.com/edit/angular-signal-inputs?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;on this stackblitz&lt;/a&gt;. It includes the code of all examples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/tomasz_ducin" rel="noopener noreferrer"&gt;Follow me on twitter&lt;/a&gt; for more frontend (js, ts, react, angular etc.) deep dives!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
