<?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: Daniela Bonvini</title>
    <description>The latest articles on DEV Community by Daniela Bonvini (@danielabonvini).</description>
    <link>https://dev.to/danielabonvini</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%2F1154110%2F20076bfd-67d2-4e94-83bf-597ffecbd52d.jpeg</url>
      <title>DEV Community: Daniela Bonvini</title>
      <link>https://dev.to/danielabonvini</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danielabonvini"/>
    <language>en</language>
    <item>
      <title>Codemotion Milan 2025</title>
      <dc:creator>Daniela Bonvini</dc:creator>
      <pubDate>Wed, 22 Oct 2025 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/codemotion-milan-2025-3hk2</link>
      <guid>https://dev.to/sparkfabrik/codemotion-milan-2025-3hk2</guid>
      <description>&lt;p&gt;Highlights and reflections from Codemotion Milan 2025, covering key talks on testing strategies, modern CSS, Chrome DevTools, and AI prompt strategies.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.sparkfabrik.com" rel="noopener noreferrer"&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%2F48ggch57mw62gl6e063r.png" alt="SparkFabrik" width="311" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Codemotion Milan 2025: Highlights and Reflections
&lt;/h2&gt;

&lt;p&gt;Last week I had the chance to attend &lt;strong&gt;Codemotion Milan 2025&lt;/strong&gt;, and honestly, &lt;em&gt;it was a blast&lt;/em&gt;. Picture hundreds of developers, designers, and tech enthusiasts buzzing around packed rooms, debating over coffee, and getting genuinely excited about new ideas. It felt like the perfect mix of community, curiosity, and caffeine.&lt;/p&gt;

&lt;p&gt;The schedule was stacked with everything from frontend magic to backend mysteries, and testing strategies to AI, DevOps, and software architecture. After two days of sessions, demos, and hallway chats, a few talks really stuck with me; for their substance, their delivery, and the sparks they set off in my brain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Testing Strategy is Broken: Let’s Fix It! by Luise Freese
&lt;/h2&gt;

&lt;p&gt;Luise Freese is an amazing speaker, funny but insightful (and it doesn't hurt that she likes pink &lt;em&gt;and&lt;/em&gt; unicorns). I had the pleasure of seeing her speak last year, so I was &lt;em&gt;really&lt;/em&gt; looking forward to her session this time around.&lt;br&gt;
In this talk she took a refreshing look at what’s &lt;em&gt;wrong with&lt;/em&gt; how we usually approach &lt;em&gt;testing&lt;/em&gt;. Her point was simple but powerful: &lt;em&gt;stop testing everything&lt;/em&gt; just for the sake of it. Aiming for 100% coverage sounds good on paper, but often just creates a mountain of useless unit tests that never actually catch the things that break in production.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fcodemotion2025%2Fstages_codemotion2025.jpeg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fcodemotion2025%2Fstages_codemotion2025.jpeg" title="Three of the multiple stages of Codemotion Milan 2025 with the respective speakers presenting to the audience" alt="Three of the multiple stages of Codemotion Milan 2025 with the respective speakers presenting to the audience" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luise argued for a &lt;em&gt;smarter, leaner approach&lt;/em&gt; — fewer tests, but better ones. Focus on how your system behaves under pressure, on integration points, on what your users will actually notice when things go wrong. As she put it, users don’t care how many tests you’ve written; they care that the software works.&lt;/p&gt;

&lt;p&gt;It was one of those talks that make you rethink your day to day habits. I left the room thinking less about coverage reports and more about value.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fcodemotion2025%2Fluise_freeze_codemotion2025.jpeg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fcodemotion2025%2Fluise_freeze_codemotion2025.jpeg" title="Luise Freeze explaining testing strategies at Codemotion Milan 2025" alt="A person speaking in front of a crowd with a monitor behind them showing a slide about testing strategies" width="800" height="782"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Baseline Rhapsody: A Tale of Style &amp;amp; Motion by Emiliano Pisu
&lt;/h2&gt;

&lt;p&gt;Emiliano Pisu’s talk was basically a love letter to &lt;em&gt;modern CSS&lt;/em&gt;, and heaven knows if we need more CSS love in the developer community. He took us on a journey from the wild days of floats and tables to the sleek, expressive world of &lt;em&gt;container queries&lt;/em&gt;, &lt;em&gt;scroll-driven animations&lt;/em&gt;, and &lt;em&gt;CSS custom properties&lt;/em&gt;. His main message: we’re living in a golden age of frontend styling, and we should start acting like it.&lt;/p&gt;

&lt;p&gt;He introduced the new &lt;em&gt;Baseline standard&lt;/em&gt;, a sort of “truth table” for web features that tells you what’s &lt;em&gt;safe to use across browsers&lt;/em&gt; right now. No more endless guessing games or praying to the compatibility gods.&lt;/p&gt;

&lt;p&gt;What I loved most was Emiliano’s mix of technical depth and creative energy. He made CSS feel exciting again, and honestly, I walked out wanting to rebuild half our design system just to play with the new toys.&lt;/p&gt;

&lt;h2&gt;
  
  
  ChromeDevTools: Are You Confident in Your Expertise? by Luca Del Puppo
&lt;/h2&gt;

&lt;p&gt;This talk was like discovering hidden cheat codes in a game you’ve been playing for years. Luca Del Puppo took something every JavaScript dev uses daily, &lt;em&gt;Chrome DevTools&lt;/em&gt;, and showed us just how much more it can do when you dig deep.&lt;/p&gt;

&lt;p&gt;He demoed advanced debugging tricks, &lt;em&gt;performance profiling&lt;/em&gt;, and how to uncover sneaky issues like &lt;em&gt;layout thrashing&lt;/em&gt; and &lt;em&gt;memory leaks&lt;/em&gt;. It wasn’t just a feature tour, it was a hands on masterclass in how to actually &lt;em&gt;think&lt;/em&gt; with your tools.&lt;/p&gt;

&lt;p&gt;What made it memorable was Luca’s energy and real-world examples. You could tell he’s spent countless hours battling tough bugs, and he made us feel like we could take on anything with DevTools as our sidekick. I walked away with a bunch of new debugging tricks and a renewed appreciation for a tool I thought I’d already mastered.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fcodemotion2025%2Fhall_codemotion2025.jpeg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fcodemotion2025%2Fhall_codemotion2025.jpeg" title="Main hall of Codemotion Milan 2025" alt="People walking and talking in the main hall of Codemotion Milan 2025" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompt Strategies: Useful for AI (and Maybe for Everyday Life) by Francesco Sciuti
&lt;/h2&gt;

&lt;p&gt;Right before my train home, I managed to squeeze in part of Francesco Sciuti’s workshop &lt;em&gt;“Prompt Strategies: utile per l'AI e (forse) anche per l'uso quotidiano”&lt;/em&gt;, which roughly translates to &lt;em&gt;“Prompt Strategies: useful for AI (and maybe also for everyday life).”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It was less of a formal talk and more of a round table conversation. Francesco walked us through how to write prompts that actually make AI behave, how to get the answers you &lt;em&gt;want&lt;/em&gt;, in the &lt;em&gt;format&lt;/em&gt; you need, without the weird hallucinations or vague replies we’ve all seen. He shared practical examples, frameworks for structuring prompts clearly, and even a few thoughts on &lt;em&gt;Context Engineering&lt;/em&gt;. Basically, how to give an AI the right background to think straight.&lt;/p&gt;

&lt;p&gt;Sadly, I had to leave halfway through to catch my train, but what I saw was genuinely enlightening. It wasn’t just about AI — it was about &lt;em&gt;communication&lt;/em&gt;, &lt;em&gt;precision&lt;/em&gt;, and how &lt;em&gt;phrasing things clearly&lt;/em&gt; can make all the difference, whether you’re prompting a model or just talking to your team. Best new term of the year coined by Francesco: &lt;em&gt;Vibe Prototyping&lt;/em&gt;, instead of the old &lt;em&gt;Vibe Coding&lt;/em&gt;, which better represents how we can approach AI interactions in a more purposeful and cooperative way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fcodemotion2025%2Fcard_magic_codemotion2025.jpeg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fcodemotion2025%2Fcard_magic_codemotion2025.jpeg" title="A fake Magic: The Gathering card showing the text 'Codemotion'" alt="A fake Magic: The Gathering card showing the text 'Codemotion'" width="800" height="1120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Made These Talks Stand Out
&lt;/h2&gt;

&lt;p&gt;Looking back, the sessions that I liked more had a few things in common. They were &lt;em&gt;practical&lt;/em&gt;, &lt;em&gt;grounded&lt;/em&gt;, and a little &lt;em&gt;opinionated&lt;/em&gt;, the kind of talks that give you ideas to try the next morning, not just slides to bookmark and forget that are more like someone reading the documentation to you instead of explaining a new concept with their own voice and thoughts. They also had a strong personal touch — you could tell the speakers were passionate about their topics, and that enthusiasm was contagious.&lt;/p&gt;

&lt;p&gt;Codemotion Milan 2025 nailed that vibe. It wasn’t about chasing buzzwords or hyping the latest framework. It was about &lt;em&gt;building better software, with intention and creativity&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Overall, the event was a brilliant reminder that learning in tech doesn’t have to be dry or intimidating. It can be lively, surprising, and even a little fun. The mix of talks, workshops, and casual conversations made it clear that &lt;em&gt;the heart of any tech community is curiosity, collaboration, and a willingness to experiment&lt;/em&gt;. And Codemotion Milan 2025 had all of that and even more.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.sparkfabrik.com" rel="noopener noreferrer"&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%2F48ggch57mw62gl6e063r.png" alt="SparkFabrik" width="311" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>techevent</category>
      <category>codemotion</category>
      <category>community</category>
    </item>
    <item>
      <title>The Lord Of The Stores: A Quest For Angular State Mastery</title>
      <dc:creator>Daniela Bonvini</dc:creator>
      <pubDate>Thu, 04 Sep 2025 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/the-lord-of-the-stores-a-quest-for-angular-state-mastery-2j2g</link>
      <guid>https://dev.to/sparkfabrik/the-lord-of-the-stores-a-quest-for-angular-state-mastery-2j2g</guid>
      <description>&lt;p&gt;In the complex world of NgRx state management three powerful stores can guide us: Global Store, vast and unifying; Component Store, swift and precise; Signal Store, reactive and efficient. But wielding them unwisely leads to an unmanageable state. Join this journey through NgRx best practices, avoiding pitfalls, and mastering scalability. Will your app stand strong or fall into disorder? The fate of state management rests in your hands!&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.sparkfabrik.com" rel="noopener noreferrer"&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%2F48ggch57mw62gl6e063r.png" alt="SparkFabrik" width="311" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The framework has changed. I feel it in the code. I feel it in the builds. I smell it in the tech forums.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It began with the forging of the Great Stores. Three were given to Angular developers—structured, scalable, and reactive above all else.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;The &lt;strong&gt;Global Store&lt;/strong&gt;, vast and powerful. The &lt;strong&gt;Component Store&lt;/strong&gt;, lightweight and precise. And the &lt;strong&gt;Signal Store&lt;/strong&gt;, fresh and efficient.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For within these stores was bound the power to manage state, to bring order to applications. Each with its own strengths, each suited for different needs.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Because the world of state management is treacherous, and without guidance, chaos can still arise. For the time will soon come when NgRx will shape the fortunes of all devs.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fhobbits_crossing.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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fhobbits_crossing.png" title="a danger road sign but inside of it is an hobbit silhouette and at the bottom the writing 'Danger hobbits crossing'" alt="a danger road sign but inside of it is an hobbit silhouette and at the bottom the writing 'Danger hobbits crossing'" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Obligatory disclaimer&lt;/strong&gt;: as you may have noticed after this slightly weird intro, in this article I will reference Lord Of The Rings lore, but if you’re not a fan of the movies or books don’t worry, of course it’s not needed to understand the explained concepts. (Although, I &lt;em&gt;strongly&lt;/em&gt; suggest you to watch/read it, as it is an amazing saga).&lt;/p&gt;




&lt;h2&gt;
  
  
  An Unexpected Journey
&lt;/h2&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fgandalf-confused.jpg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fgandalf-confused.jpg" title="Gandalf confused reading a scroll with 'component store' written on it" alt="Gandalf confused reading a scroll with 'component store' written on it" width="512" height="256"&gt;&lt;/a&gt;&lt;br&gt;
The idea for this article came to me after I discussed with my team the option to start using a state management library for our application. At the time we used services that mimicked store slices and we wanted to switch them into full-fledged NgRx stores.&lt;/p&gt;

&lt;p&gt;Until that moment I had only used the &lt;strong&gt;Global Store&lt;/strong&gt;, heard of the &lt;strong&gt;Signal Store&lt;/strong&gt; and didn’t even know the &lt;strong&gt;Component Store&lt;/strong&gt; existed, until I read the NgRx official documentation (see, someone &lt;em&gt;does RTFM&lt;/em&gt; sometimes).&lt;/p&gt;

&lt;p&gt;As we didn’t have any specific requests on what to use, we were open to any one of them.&lt;/p&gt;

&lt;p&gt;We took some time researching, and I found out that, as far as I know, there are no articles or videos directly comparing the differences between these stores, their use cases, and their pros and cons.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Feasy_state_management.jpg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Feasy_state_management.jpg" title="Gandalf telling Theoden how easy state management is" alt="Gandalf telling Theoden how easy state management is" width="570" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fast forward a couple of months later and a lot of material revised, and here we are: I hope my findings will help someone in a similar position to mine figure out a little bit easier which store to choose for their own case.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fvilya_card.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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fvilya_card.png" title="A TCG card showing the ring Vilya" alt="A TCG card showing the ring Vilya" width="424" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Global Store – Vilya, The Ring of Air
&lt;/h2&gt;

&lt;p&gt;Let’s start with the &lt;strong&gt;Global Store&lt;/strong&gt;, the most powerful option, associated with &lt;em&gt;Vilya&lt;/em&gt;, the ring given to Elrond, symbolizing wisdom and governance.&lt;/p&gt;

&lt;p&gt;Likewise, the Global Store manages large state in applications, providing structure and predictability. It is &lt;strong&gt;ideal for apps with complex state that multiple components must access and update&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, this power comes with &lt;strong&gt;complexity&lt;/strong&gt;: it requires a solid understanding of reducers, actions, effects, and RxJS, which adds to the learning curve. It demands boilerplate code and many interconnected parts, which can be overwhelming, especially for smaller apps or simpler state needs.&lt;/p&gt;

&lt;p&gt;But this union of actions and effects is the Global Store’s strength, enabling features like &lt;strong&gt;time-travel debugging with native Redux DevTools&lt;/strong&gt; integration. Developers can step backward and forward in the application’s state history, making changes easier to trace and debug.&lt;/p&gt;

&lt;p&gt;Having matured over many years, the Global Store also offers an &lt;strong&gt;opinionated and structured&lt;/strong&gt; way of managing state, helping teams organize logic across files and maintain consistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Global Store – Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Best for large-scale apps with complex state shared across multiple components&lt;/td&gt;
&lt;td&gt;High complexity (reducers, actions, effects, selectors) + RxJS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easier debugging using time-travel with Redux DevTools&lt;/td&gt;
&lt;td&gt;Steep learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mature: opinionated and structured way of managing state&lt;/td&gt;
&lt;td&gt;Lots of boilerplate code to interconnect everything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Too much overhead for smaller applications&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Example of use cases:&lt;/strong&gt; large apps with complex, shared business logic (multi-step forms, shopping carts shared across multiple features) or global data like feature flags, notifications, or permissions.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fnenya_card.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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fnenya_card.png" title="A TCG card showing the ring Nenya" alt="A TCG card showing the ring Nenya" width="429" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Nenya – The Ring of Water, The Component Store
&lt;/h2&gt;

&lt;p&gt;Then comes the &lt;strong&gt;Component Store&lt;/strong&gt;, the underdog of the state management world, yet full of potential. I associate it with Nenya, Galadriel’s ring, symbolizing preservation and stability.&lt;/p&gt;

&lt;p&gt;The Component Store works seamlessly with the Global Store without conflict, allowing effective &lt;strong&gt;state management with minimal changes&lt;/strong&gt; to your codebase. You can see it like a &lt;strong&gt;service managing state with Subjects&lt;/strong&gt;, but with added clarity and best practices.&lt;/p&gt;

&lt;p&gt;It’s a &lt;strong&gt;lightweight solution&lt;/strong&gt; ideal for &lt;strong&gt;managing local component&lt;/strong&gt; or feature module state, promoting modularity and isolation. It supports multiple &lt;strong&gt;independent instances&lt;/strong&gt; of the same component, maintaining &lt;strong&gt;clean separation of concerns&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Its API is &lt;strong&gt;simpler than that of the Global Store&lt;/strong&gt;, as it doesn't require actions or reducers, making it easier to learn. However, it lacks developer tool support like time-travel debugging since it doesn't utilize trackable actions.&lt;/p&gt;

&lt;p&gt;Trade-offs include &lt;strong&gt;scalability challenges&lt;/strong&gt;: state, updaters, selectors, and effects typically reside in the same file, which can become difficult to manage as logic increases. Also, since state is tied to the component lifecycle, it is removed when the component is destroyed, making it &lt;strong&gt;inappropriate for persistent or shared state&lt;/strong&gt; across components.&lt;/p&gt;

&lt;p&gt;In summary, the Component Store offers store-like benefits without the Global Store's complexity.&lt;/p&gt;

&lt;p&gt;Now, I must make a small confession: lately the NgRx team has put on the component store page a note saying that &lt;em&gt;they consider the signal store the new default for local state management&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fngrx_signals_new_default.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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fngrx_signals_new_default.png" title="A notice saying that they recommend the signal store for managing local state" alt="A notice saying that they recommend the signal store for managing local state" width="800" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But&lt;/em&gt;, I nevertheless wanted to talk about component store as a lot of people may be &lt;strong&gt;stuck on older versions&lt;/strong&gt; of Angular and may not be able to easily upgrade to signals and signal store usage.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fnpm_downloads.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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fnpm_downloads.png" title="The number of downloads of the various Angular versions from npm" alt="The number of downloads of the various Angular versions from npm" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see from &lt;a href="https://www.npmjs.com/package/@angular/core?activeTab=versions" rel="noopener noreferrer"&gt;npm&lt;/a&gt;, still hundreds of thousands of people download Angular to versions less than 17 (signal store was released with NgRx version 17). But these same people may still be in need of a smaller store for their state management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Component Store – Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lightweight solution for local component state&lt;/td&gt;
&lt;td&gt;Low scalability as everything is in the same file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple independent instances of the same component allowing separation of concerns&lt;/td&gt;
&lt;td&gt;No permanent state, as it is reset on component destruction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Simple syntax and state management (no actions or reducers)&lt;/td&gt;
&lt;td&gt;No Redux DevTools time-travel debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Example of use cases:&lt;/strong&gt; managing a form’s input values, validation, and submission state, or controlling the visibility and behavior of a modal within a component.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fnarya_card.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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fnarya_card.png" title="A TCG card showing the ring Narya" alt="A TCG card showing the ring Narya" width="423" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Narya – The Ring of Fire, The Signal Store
&lt;/h2&gt;

&lt;p&gt;And lastly, the &lt;strong&gt;Signal Store&lt;/strong&gt;, represented by Narya, Gandalf’s ring of courage and action.&lt;/p&gt;

&lt;p&gt;It reflects the NgRx team’s bold shift toward &lt;strong&gt;simplicity and performance&lt;/strong&gt;. Built on Angular signals, it provides &lt;strong&gt;reactive and efficient state management&lt;/strong&gt;, removing unnecessary recalculations with a &lt;strong&gt;straightforward syntax&lt;/strong&gt; that you can use right away.&lt;/p&gt;

&lt;p&gt;In this store, &lt;strong&gt;state properties are signals&lt;/strong&gt;, allowing components to access them directly without selectors or boilerplate code. Its lightweight design and optional RxJS support make it ideal for modern Angular apps that want to reduce complexity and bundle size.&lt;/p&gt;

&lt;p&gt;However, it is still new, so official &lt;strong&gt;guidelines are limited&lt;/strong&gt;. Features like selector composition, route guard integration, and DevTools support are still being developed. The Signal Store also &lt;strong&gt;forces you to use signals&lt;/strong&gt; or convert Observables into signals. This makes it best suited for &lt;strong&gt;small to medium-scale features&lt;/strong&gt; or isolated domains, while large-scale applications may still prefer the Global Store.&lt;/p&gt;

&lt;p&gt;One downside is that the Signal Store &lt;strong&gt;does not support Redux DevTools yet&lt;/strong&gt;. This means you lose features like time-travel debugging and state inspection.&lt;/p&gt;

&lt;p&gt;There is an &lt;strong&gt;unofficial alternative&lt;/strong&gt;, the &lt;a href="https://ngrx-toolkit.angulararchitects.io/docs/with-devtools" rel="noopener noreferrer"&gt;Angular Architects NgRx Toolkit&lt;/a&gt; browser extension, which offers partial support but does not fully match the Redux DevTools experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signal Store – Pros and Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;State properties as signals (no selectors)&lt;/td&gt;
&lt;td&gt;Still new, with limited official guidelines and documentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plug and play (simple syntax and small bundle size)&lt;/td&gt;
&lt;td&gt;Advanced features are still evolving&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Optional RxJS use&lt;/td&gt;
&lt;td&gt;Obligatory use of signals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good for reactive programming&lt;/td&gt;
&lt;td&gt;Best suited for small to medium-scale apps; not yet ideal for large-scale or enterprise apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extreme composability (you choose which features to use)&lt;/td&gt;
&lt;td&gt;No out-of-the-box Redux DevTools&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Example of use cases:&lt;/strong&gt; managing UI-related states like toggles, modals, filters, and tabs where reactive updates are needed but complexity is low.&lt;/p&gt;




&lt;h2&gt;
  
  
  Choosing the Right Ring and Power
&lt;/h2&gt;

&lt;p&gt;We now have a better understanding of what each store can give us. But we still need to make a choice to understand which one is &lt;strong&gt;the right power for us&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Like the Elves wielding their rings wisely, developers must choose the right store for the right situation, as we know that &lt;em&gt;the wrong power in the wrong hands can lead to disastrous consequences&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fsauron.jpeg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fsauron.jpeg" title="The eye of Sauron" alt="The eye of Sauron" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We must avoid at all costs the temptation of using &lt;strong&gt;too much&lt;/strong&gt; or &lt;strong&gt;too little power&lt;/strong&gt; just because we &lt;em&gt;like&lt;/em&gt; one of the stores. Using a Global Store when local state would be better overcomplicates a simple problem. Conversely, sometimes a simple service+subjects/signals is all you need instead of any store at all.&lt;/p&gt;

&lt;p&gt;The choice between NgRx stores depends primarily on your &lt;strong&gt;project's complexity&lt;/strong&gt;, &lt;strong&gt;team size&lt;/strong&gt;, and &lt;strong&gt;growth expectations&lt;/strong&gt;. The &lt;em&gt;Global Store&lt;/em&gt; excels at enterprise-level applications. The &lt;em&gt;Signal Store&lt;/em&gt; offers a simpler alternative for smaller projects. The &lt;em&gt;Component Store&lt;/em&gt; provides a balanced approach suitable for medium-sized applications or feature modules.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fstore_diagram.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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fstore_diagram.png" title="A diagram showing the various choices for choosing the right store" alt="A diagram showing the various choices for choosing the right store" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider starting with the &lt;strong&gt;simplest solution&lt;/strong&gt; that meets your needs and &lt;strong&gt;scaling up&lt;/strong&gt; as your application grows.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fthe_one_ring.jpg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fthe_one_ring.jpg" title="The one ring" alt="The one ring" width="700" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  One Store to Bind All State
&lt;/h2&gt;

&lt;p&gt;But what if you want more power, more control, and you cannot choose between the three rings? Well, you also have the choice to &lt;strong&gt;combine them&lt;/strong&gt; to balance their respective flaws and strengths.&lt;/p&gt;

&lt;p&gt;For example, you can use the &lt;em&gt;Global Store&lt;/em&gt; for managing global state across the application, employ the &lt;em&gt;Component Store&lt;/em&gt; for encapsulating state within specific features, and integrate the &lt;em&gt;Signal Store&lt;/em&gt; where reactive and functional updates are most beneficial.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fthree_rings_power.jpg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fthree_rings_power.jpg" title="The three rings combining together their strengths" alt="The three rings combining together their strengths" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These stores were deliberately made to &lt;strong&gt;work well together&lt;/strong&gt;. The complexity lies not in the implementation but in ensuring your team agrees on conventions and enforces them during reviews. Otherwise, wrongful mixes could lead to painful refactors.&lt;/p&gt;

&lt;p&gt;Having said that, I made a little &lt;a href="https://stackblitz.com/edit/fellowship-dashboard" rel="noopener noreferrer"&gt;task management dashboard on Stackblitz&lt;/a&gt;,&lt;br&gt;
to have a visual reference on how the code works.&lt;/p&gt;

&lt;p&gt;This is just a simple app to show how you can intertwine all of the aforementioned stores. Of course using all three is a bit too much, especially for this kind of small project, but this is obviously just an example to show how they can easily work together if the need arises. Usually I would suggest using only &lt;strong&gt;two of them together&lt;/strong&gt;: &lt;strong&gt;one for managing global properties&lt;/strong&gt; and &lt;strong&gt;one for managing component properties&lt;/strong&gt;.&lt;br&gt;
This dashboard has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A global quest assigner (managed by the &lt;em&gt;Global Store&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;A status card specifically for each member (managed by the &lt;em&gt;Component Store&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;A reactive search input (managed by the &lt;em&gt;Signal Store&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Fifth Age: The Age of NgRx State Management
&lt;/h2&gt;

&lt;p&gt;With the information we acquired we now know that these three stores &lt;strong&gt;bring order to the Middle Earth of state management&lt;/strong&gt;, but only if used wisely. &lt;em&gt;No one store rules them all — each has its own purpose.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Additionally, we now know that you can combine what they can do, to be even more powerful. But it is up to you to avoid the temptation of &lt;strong&gt;abusing their power&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fgaladriel_meme.jpeg" 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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fgaladriel_meme.jpeg" title="Galadriel saying that she passed the test" alt="Galadriel saying that she passed the test" width="649" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now go into the world and use your power wisely, as the fate of Angular state management now rests in your hands.&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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fthe_end_hobbit.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%2Ftech.sparkfabrik.com%2Fimages%2Fcontent%2Fthe-lord-of-the-stores%2Fthe_end_hobbit.gif" title="The closing door of an hobbit home" alt="The closing door of an hobbit home" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.sparkfabrik.com" rel="noopener noreferrer"&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%2F48ggch57mw62gl6e063r.png" alt="SparkFabrik" width="311" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ngrx</category>
      <category>statemanagement</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Public speaking is like eating chillies</title>
      <dc:creator>Daniela Bonvini</dc:creator>
      <pubDate>Mon, 01 Jul 2024 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/public-speaking-is-like-eating-chillies-2jlg</link>
      <guid>https://dev.to/sparkfabrik/public-speaking-is-like-eating-chillies-2jlg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This past year, after some soul searching and &lt;em&gt;a lot&lt;/em&gt; of nudging from some of the people around me, I finally took the big step and &lt;strong&gt;started giving public talks at tech conferences&lt;/strong&gt;. I started small, first at a local meetup group, then in front of my coworkers via video call, and finally in person in front of real people.&lt;/p&gt;

&lt;p&gt;In my clearly clickbait title, I compared this experience to eating chili peppers, which is one of the things I both love and fear most when I accidentally drop way too many chili flakes into a dish I just cooked.&lt;br&gt;
Why a culinary example? Well, for one thing, I like to cook, and for another, I'm Italian, so I guess it's written somewhere in our constitution that it's my civic duty to speak in food metaphors.&lt;/p&gt;

&lt;p&gt;I think it's an apt comparison: that first moment when you take that first bite of food, knowing full well that you've put &lt;em&gt;way too much&lt;/em&gt; seasoning on it, but you eat it anyway. And after the initial pain of too much spice, you realize that all in all, the dish now has &lt;strong&gt;more flavor&lt;/strong&gt; and &lt;strong&gt;more oomph&lt;/strong&gt;. But more than that, you're secretly proud of yourself for &lt;strong&gt;overcoming the fear of the initial discomfort&lt;/strong&gt;.&lt;br&gt;
Then there is the second time, when you do it again with another dish, where you have once again miscalculated the ingredients. Which is somehow made worse because you already know the initial pain, but at the same time you know the amazing amount of flavor and spiciness that would follow.&lt;br&gt;&lt;br&gt;
Well, this applies perfectly to public speaking, at least for me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zar5hcgcgfpzxmeurkj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zar5hcgcgfpzxmeurkj.jpeg" alt="A person speaking in front of a crowd of chilli peppers" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The first bite
&lt;/h2&gt;

&lt;p&gt;At my first local meetup talk, I was so scared that I &lt;em&gt;almost&lt;/em&gt; ran away, pretending to be sick. But then I persevered and delivered the talk I had prepared, and in the end I felt proud, both because it went well, but mostly because I did it by &lt;strong&gt;pushing through the fear of failure&lt;/strong&gt;.&lt;br&gt;
Then came another occasion of public speaking and, as in my culinary example from earlier, I was, if possible, even more frightened than before. But I persevered, and once again, overcoming the stage fright, came the satisfaction, both in myself and in what I had done.&lt;/p&gt;

&lt;p&gt;I won't sugarcoat it, that initial "&lt;em&gt;pain&lt;/em&gt;" never goes away. The majority of public speakers I have talked to say that they always get nervous, regardless of their years of experience. But they go through with it, knowing that the final morsel will be totally worth the initial suffering. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There must be a reason why it is a popular trope that in order to grow you have to get out of your comfort zone.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And believe me, I know it's easier said than done; I'm extremely socially awkward, to the point where I'm afraid to even make phone calls to people or places I don't know, but trying to get over that initial discomfort with public speaking has really helped me get a little more comfortable around new people. I'm still not a party animal, but I'm starting to understand that the more you project a feeling of being relaxed to the outside world, the more your mind is tricked into thinking you're really relaxed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhw6bns3fciwugsft6kq0.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhw6bns3fciwugsft6kq0.jpeg" alt="The roll safe meme with a caption that says 'Can't be anxious if you think you're not anxious" width="600" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lately I have been feeling a little &lt;strong&gt;bolder&lt;/strong&gt; in my everyday life and people around me have been telling me that it shows that I feel &lt;strong&gt;more confident&lt;/strong&gt; and that I am speaking a lot more without being prompted. Another speaker at a conference even said that I was an extrovert and seemed perfectly at ease on stage. &lt;em&gt;Me&lt;/em&gt;. &lt;em&gt;Can you believe that&lt;/em&gt;?&lt;br&gt;
I spent most of my teenage years being told I needed to talk more, smile more, get out more, so it feels incredible to be told the opposite.&lt;/p&gt;

&lt;p&gt;In addition to the increased self-esteem, being a speaker at these kinds of events is a great way to meet other incredibly talented people who you'll most likely see at other conferences later on, thus reducing the subsequent anxiety of not knowing anyone. It's also incredibly &lt;strong&gt;good for networking&lt;/strong&gt;: I've had the opportunity to talk face-to-face with people I would never have had the chance to talk to otherwise, and to ask for advice on various topics, and I've always been treated with the utmost kindness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The aftertaste
&lt;/h2&gt;

&lt;p&gt;What saddens me is that &lt;strong&gt;I see the most fear of speaking at these conferences coming from junior developers, especially female ones&lt;/strong&gt;. They are convinced that they are not good enough to be at these events because most of the speakers are already well-known or super skilled.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What they never think about is that precisely because they are a part of the tech world that is rarely represented at conferences, the reason to be that person is to become an &lt;strong&gt;inspiration to others&lt;/strong&gt; in a similar position. So those other people can think, "&lt;em&gt;hey, look at that, it's not impossible, I could do that too&lt;/em&gt;".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my personal experience, I would never have started on this path if I hadn't been part of a company that encourages participation in these events, and if I hadn't had some friends and colleagues who have achieved great things just through sheer dedication, doing things that I didn't think were possible for "&lt;em&gt;normal&lt;/em&gt;" people (&lt;em&gt;aka not senior developers or not already famous&lt;/em&gt;). Or even just for having people with the confidence in me that I lacked at that moment, but needed to embark on this adventure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I hope that these words will give some of you reading the same kind of support that I have received.&lt;/strong&gt;&lt;br&gt;
That if you are teetering on the edge of trying, but not finding the courage to send out a call for papers, that my words may inspire you to take the first step on the other side of public speaking.&lt;/p&gt;

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

&lt;p&gt;With my silly cooking example, I want to send a message to all the people who are curious about public speaking but don't think they are extroverted enough, good enough, knowledgeable enough, whatever enough to deserve to do it, to &lt;strong&gt;at least try it once&lt;/strong&gt;. And if after the initial discomfort you can feel the rewarding spiciness that comes afterward, then trust me, you are hooked for life.&lt;/p&gt;

&lt;p&gt;And if not, that's okay too, at least you tried, and now you'll certainly have a better understanding of yourself, and you can still be proud that you at least tried, and peacefully know that it wasn't for you, without any regrets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So go on, take that first spicy bite and get out of your comfort zone&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>publicspeaking</category>
      <category>community</category>
      <category>events</category>
    </item>
    <item>
      <title>How (not) to contribute to open source</title>
      <dc:creator>Daniela Bonvini</dc:creator>
      <pubDate>Thu, 25 Jan 2024 09:00:00 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/how-not-to-contribute-to-open-source-77k</link>
      <guid>https://dev.to/sparkfabrik/how-not-to-contribute-to-open-source-77k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The idea of contributing to open source projects is often presented as an easy task that anyone can do. However, in reality, it can be a very challenging journey. Despite hearing countless times that contributing to open source is simple, it wasn't until I tried it myself that I realized this was not the case. In this text, I will share my own experience with open source contribution to provide an honest and informative account of what it truly entails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy5t1eu7cg97qs2bk3ar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy5t1eu7cg97qs2bk3ar.png" alt="Tidus standing in front of Zanarkand ruins for the last time in Final Fantasy X" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Act 1: The grand illusion
&lt;/h2&gt;

&lt;p&gt;In the beginning, I started to ask my colleagues for tips on where to start, and they pretty unanimously said to search for issues with &lt;strong&gt;for beginners&lt;/strong&gt; or &lt;strong&gt;help wanted&lt;/strong&gt; tags, maybe in some of the projects I was already using at work. Well, I thought, that's easy. I got a short list of the libraries I was using and/or I was interested in and started digging into their &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; repositories. I combed dozens of open issues, but either they had no &lt;strong&gt;good first issue&lt;/strong&gt; tag, or the more accessible things got snatched lightning fast.&lt;/p&gt;

&lt;p&gt;So I went back to those who had suggested this route and asked for advice again, and this time they told me that I probably couldn't look in the famous libraries, where the competition was too fierce; I had to find my hidden gem in smaller projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxons6gx8tr1wu32xyy9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxons6gx8tr1wu32xyy9.jpg" alt="Toad telling Mario that his issue is in another repo" width="534" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I restarted my search, feeling slightly disgruntled. While it's nice to offer help, it's even better if that help is given to a prestigious library that you can boast about to other developers. It's natural to want to showcase our accomplishments, especially to those who understand our work. My parents only see value in my ability to fix their phones, so let me have this one thing.&lt;/p&gt;

&lt;p&gt;I then perused less-known libraries, confident that I would be lucky this time. But I wasn't.&lt;br&gt;
All I could find were libraries with complicated tasks, even the ones marked &lt;strong&gt;for beginners&lt;/strong&gt;, in which the tag was very much misplaced, as in you had to know the codebase exceptionally well to fix even the minor stuff.&lt;br&gt;
So &lt;em&gt;OF COURSE&lt;/em&gt; I rolled up my sleeves, drew upon my inner strength, and found the perfect fix, after which everybody hailed me as the best contributor in the world.&lt;/p&gt;

&lt;p&gt;Yes, no, of course not, otherwise we wouldn't be here. I quit. Just like that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mteoqvmzlq2bo5k26xx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mteoqvmzlq2bo5k26xx.jpeg" alt="Godzilla returning to the sea saying nope" width="796" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Act 2: Reality check
&lt;/h2&gt;

&lt;p&gt;Let's jump a few months ahead, and the OS itch returned to me. I have a friend who makes videos about OS. He was doing one on Hacktoberfest &lt;sup id="fnref1"&gt;1&lt;/sup&gt;, saying that there were no physical prizes to discourage issue-taking spammers this year. This was my long-awaited chance, I was certain!&lt;/p&gt;

&lt;p&gt;So I went to the Hacktoberfest site and combed the &lt;strong&gt;starting&lt;/strong&gt; section. There, I found a link to a site that collected issues suited for first-timers, grouped by project. If they were included in the most famous site for the most famous OS event of the year, they certainly must be what I was looking for, right?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhv54pwr7nrm5o40s65h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhv54pwr7nrm5o40s65h.jpg" alt="padme-dev asking anakin-github if it has beginner friendly prs" width="503" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first, I tried filtering by language, trying JavaScript, and looking at some of the open issues. Even worse than with my previous attempt months before, I couldn't even find the issues this time: they were snatched so fast that the site wasn't always updated on time, so it listed things already being worked upon or even fixed and merged.&lt;br&gt;
So I narrowed my search and went where only the bravest engineers dare to go: CSS fixes.&lt;br&gt;
But even doing so, I was again faced with the problem of finding only &lt;em&gt;not-really-for-beginners-beginners-tagged&lt;/em&gt; issues. So, once more, I gave up.&lt;/p&gt;

&lt;p&gt;Third time's the charm, and now I was fixated on having to make at least one OS contribution, so after Hacktoberfest was over, I tried another of the many tips I had been given previously: fix the documentation and find typos or bugs even before an issue is opened.&lt;/p&gt;

&lt;p&gt;This was pure coincidence; I was researching &lt;a href="https://angular.dev/guide/signals#writable-signals" rel="noopener noreferrer"&gt;Angular's Signals&lt;/a&gt;, and I knew that the &lt;em&gt;.mutate()&lt;/em&gt; function was taken out of the APIs. (For context, this was just a couple of days from the announcement).&lt;br&gt;
I checked the documentation and, lo and behold, it was still there. I thought this was my chance for glory: a small, not-yet-mainstream documentation fix in a famous project. So I rushed over to the &lt;a href="https://github.com/angular" rel="noopener noreferrer"&gt;Angular GitHub&lt;/a&gt;, and I'm sure you've guessed it: It was already fixed and just waiting to be merged in. And it was snatched just before I checked, so double the annoyance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Act 3: The Hidden Gem
&lt;/h2&gt;

&lt;p&gt;That was the last straw; cumulatively, I had spent more time looking for something to do than actually doing it. But I really wanted to contribute!&lt;br&gt;
So a few more months went by, until one day I met an Italian open source maintainer and long-time speaker, Giorgio Boa, who by the way was &lt;a href="https://www.youtube.com/live/P2WVTBjh00E?si=U97cCjlNZFPtmFUZ" rel="noopener noreferrer"&gt;a guest on our podcast Continuous Delivery&lt;/a&gt;, and asked him for advice, saying that I wanted to be part of the OS world. He said he was working on a small library of &lt;a href="https://qwik.builder.io/" rel="noopener noreferrer"&gt;Qwik&lt;/a&gt; components and could help me if I wanted. I gladly accepted, and we found an issue that seemed pretty straightforward.&lt;br&gt;
A few days after our conversation, I followed the little README guide to install everything required, and...nothing worked. So, after a few bad words, a lot of doubt about my skills as an engineer, and self pep talks to overcome my shyness about asking for help, I contacted Giorgio again. Even with his help, at first we had some trouble figuring out what was going wrong, but in the end I finally had a working setup.&lt;/p&gt;

&lt;p&gt;Eventually, I finally had time to start working on it. It seemed easy; Boa had already given me some tips on how to get started, so I got half the work done in a short time. But then the problems started. After going in circles for about a day, I finally gave in. I did the scariest thing of all: I once again asked for help, admitting that I had no idea what was going wrong. We tried to look at it together, but we couldn't find the problem right away. So I committed the part that I did that worked, and the next day Giorgio fixed the other half and merged my very first PR into the &lt;a href="https://github.com/qwikifiers/qwik-storefront-ui" rel="noopener noreferrer"&gt;Qwik Storefront&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqr6gaihdm7vtz109oaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqr6gaihdm7vtz109oaf.png" alt="Tom from The Office saying that the merged pr is beautiful" width="522" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, in the end, I finally got what I wanted: a published contribution in a good library, but I couldn't stop wondering if it was all worth it.&lt;br&gt;
I was proud of it, of course, even though I needed some help. But I wanted more out of my work.&lt;br&gt;
In the beginning I felt like a fraud for not contributing to OS, but in the end even contributing, or trying to contribute, made me feel like a fraud for not knowing enough and being more of a burden to a senior contributor than an additional help.&lt;/p&gt;

&lt;p&gt;Looking back at it now, I think my biggest mistake was trying to do it for the hype, trying to conform to what everybody else around me said I should be doing and not because I really believed in what I was doing and why.&lt;br&gt;
It doesn't really matter what anyone else says or does, because at the end of the day it's your time that's being spent solving these issues, and that time has to mean something to you if it's being taken away from other parts of your life.&lt;/p&gt;

&lt;p&gt;I haven't resolved any other issues since then, and for now that's ok for me. I want to resolve an issue all by myself next time, but I want to be sure to do it for the right reasons this time, to avoid any unnecessary stress.&lt;br&gt;
Knowing that this time, if I do go back and contribute, it won't be for the "glory" or the FOMO (Fear Of Missing Out), but for the kindness I've been shown, and which I hope to one day give back to a fellow developer in need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: The Truth Unveiled
&lt;/h2&gt;

&lt;p&gt;So am I saying you shouldn't contribute to OS? Well, of course not. But I am stressing the importance of doing it because you really want to, or because you think the project you are working with will benefit from your contribution, not because everyone else is doing it and telling you how important it is, or because you really want a free T-shirt. As we've seen, helping in OS is not a walk in the park, so you must engage in it knowing what you're really getting into to avoid unnecessary frustration.&lt;/p&gt;

&lt;p&gt;If you enter this world fully aware of what you're up against, you'll find it easier to accept the difficulties that come with trying to start contributing to open source. It will also give you the mental strength to accept failure when the problem you thought was beginner-friendly turns out to be much more treacherous than you thought.&lt;br&gt;
What will be different is your reaction in front of this problem, as you will now know that there's no shame in not being able to close a beginner-tagged issue or even in asking somebody more skilled than you for help. Even though you'd have to ask two, three, or a hundred times. Just know that it is ok to fail and to need support and it doesn't make you any less of a developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Post Scriptum
&lt;/h3&gt;

&lt;p&gt;This post offers my personal viewpoint on contributing to open source software, with the awareness that alternative methods of contribution, such as identifying and reporting bugs or translating documentation into other languages, exist but may be less widely known to those who are new to open source communities. Rather than purporting to present the definitive truth, the aim of this post is to provide a different angle on the difficulties that beginners may encounter when trying to make their mark in this world of contribution. The text conveys a thought-provoking perspective while upholding the utmost respect for individuals who consistently contribute to the open-source world.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt;: we also wrote a reply to this post that you can find &lt;a href="https://dev.to/sparkfabrik/how-and-why-to-contribute-to-open-source-1i9a"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Footnotes
&lt;/h4&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://hacktoberfest.com/" rel="noopener noreferrer"&gt;Hacktoberfest&lt;/a&gt; is an annual worldwide event held during the month of October. The event encourages open source developers to contribute to repositories for the whole month.&lt;br&gt;
Up until 2022, if 4 of your PRs got merged, you would receive a free t-shirt and sometimes other swag, which created utter chaos, with loads of fake or useless pull requests being spammed all over the GitHub universe. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>opensource</category>
      <category>web</category>
      <category>development</category>
      <category>community</category>
    </item>
    <item>
      <title>Angular Signals: what's all the fuss about?</title>
      <dc:creator>Daniela Bonvini</dc:creator>
      <pubDate>Tue, 12 Sep 2023 09:33:29 +0000</pubDate>
      <link>https://dev.to/sparkfabrik/angular-signals-whats-all-the-fuss-about-3hm5</link>
      <guid>https://dev.to/sparkfabrik/angular-signals-whats-all-the-fuss-about-3hm5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the last couple of months the word &lt;a href="https://angular.io/guide/signals" rel="noopener noreferrer"&gt;signals&lt;/a&gt; has been said a lot in the Angular communities. Everybody already seems to either love them madly or reject them passionately.&lt;br&gt;&lt;br&gt;
But for those of us who are late to the hype train: what are they? And what can they do or not do?&lt;br&gt;&lt;br&gt;
Worry no more with FOMO as by the end of this article you will have a more comprehensive idea of where signals come from, how they work, and more importantly how they fit into the RxJS observables world.&lt;/p&gt;
&lt;h2&gt;
  
  
  Genesis
&lt;/h2&gt;

&lt;p&gt;Let's start with the basics: why were they created? One may think that it was just a matter of "let's add a new feature to the framework", but it's not that simple. And it's not even a matter of &lt;em&gt;copying&lt;/em&gt; what other frameworks are doing, as signals are not a new concept, they have been around for a while, and they are used in other libraries like &lt;a href="https://preactjs.com/guide/v10/signals/" rel="noopener noreferrer"&gt;Preact&lt;/a&gt; or frameworks like &lt;a href="https://www.solidjs.com/docs/latest/api#createsignal" rel="noopener noreferrer"&gt;SolidJS&lt;/a&gt;. Indeed, SolidJS author himself says signals have been around "&lt;a href="https://dev.to/this-is-learning/the-evolution-of-signals-in-javascript-8ob"&gt;since the dawn of declarative JavaScript Frameworks&lt;/a&gt;".&lt;br&gt;&lt;br&gt;
This is not a case of "monkey see, monkey do", but rather a case of &lt;em&gt;"let's see what we can do better"&lt;/em&gt;.&lt;br&gt;
The reasoning behind these changes can be well represented by this quote by the tech lead of the Angular team, Alex Rickabaugh:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The nature of web applications is always evolving, the performance requirements evolve, the web platform itself is evolving. So Angular needs to be stable, but not stagnant”. And so signals were born.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a matter of fact, for the last decade, Angular's team listened to the users' most requested features to improve the developer experience. Amongst other things, some reoccurring requests concerned the necessity to &lt;strong&gt;simplify&lt;/strong&gt; the usage of Angular, requiring &lt;strong&gt;less boilerplate&lt;/strong&gt; code, augmented &lt;strong&gt;performances&lt;/strong&gt;, more &lt;strong&gt;reactivity&lt;/strong&gt;, and &lt;strong&gt;finer control&lt;/strong&gt; over the components.&lt;br&gt;&lt;br&gt;
(Following this &lt;a href="https://github.com/angular/angular/discussions/49090" rel="noopener noreferrer"&gt;link&lt;/a&gt; you will find the PR that answered these requests, introducing signals for the first time.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbw63nx379ah66mzmwrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbw63nx379ah66mzmwrg.png" alt="Ikea signals meme" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Change detection
&lt;/h3&gt;

&lt;p&gt;To gain a better understanding of these requests, we must first digress a little bit, explaining a fundamental concept of Angular: &lt;a href="https://angular.io/guide/change-detection" rel="noopener noreferrer"&gt;change detection&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
At the time of writing the framework uses a library called &lt;em&gt;zone.js&lt;/em&gt; to control the various changes of state inside the application.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Zone.js&lt;/em&gt; tracks all the browser's events and every time it sees that something has changed, it starts a change detection cycle, in which it checks the components tree of the app to see if something has been modified, updating the views that need to be updated. On the one hand, this behavior is extremely useful because it automatically manages these checks, on the other hand, it underperforms because it constantly checks &lt;strong&gt;all&lt;/strong&gt; of the components, sometimes even when there is no need to update anything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k264acxvyz8744ttkhn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k264acxvyz8744ttkhn.gif" alt="Zone.js change detection gif" width="312" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An alternative strategy can be to use &lt;em&gt;zone.js with OnPush&lt;/em&gt; in every component. This makes it so that the component that uses it is not checked during a change detection cycle unless explicitly marked with the &lt;code&gt;markForCheck()&lt;/code&gt; function.&lt;br&gt;&lt;br&gt;
This behavior may seem similar to the one before, but the main difference is that &lt;code&gt;markForCheck()&lt;/code&gt; doesn't automatically trigger the change detection for its component, but it just marks it to be checked on the next change detection cycle scheduled by zone.js .&lt;br&gt;&lt;br&gt;
The downside to this strategy is that it marks not just the component that raised the &lt;code&gt;markForCheck()&lt;/code&gt; flag, but &lt;strong&gt;also its parent nodes&lt;/strong&gt;. So we have fewer components checked than before, but there is still some, let's say over-checking spillage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18ypvvldeflfu5fjcwoo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18ypvvldeflfu5fjcwoo.gif" alt="Zone.js with onpush change detection gif" width="284" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With &lt;em&gt;signals&lt;/em&gt;, however, change detection is much more precise, indicating &lt;strong&gt;only&lt;/strong&gt; the component, or components, that have undergone some changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb2r5uaig4lpb9yhiqswa.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb2r5uaig4lpb9yhiqswa.gif" alt="Signals change detection gif" width="250" height="245"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  But what is a signal?
&lt;/h2&gt;

&lt;p&gt;A signal can be seen as a box around a value, and it can alert interested consumers when its value changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47c7j94pijfcaxu1rhfv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47c7j94pijfcaxu1rhfv.png" alt="Box with value" width="427" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can contain every kind of value, from primitive ones to more complex data structures. The value of a signal is always read using a getter function, which is what allows Angular to track when it has been used.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Side note:&lt;/strong&gt; as a signal contains a value, it must always be initialized, or by default, it will be equal to &lt;code&gt;undefined&lt;/code&gt;, which is not ideal.&lt;/p&gt;

&lt;p&gt;A signal can be of one of two categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://angular.io/guide/signals#computed-signals" rel="noopener noreferrer"&gt;Writable&lt;/a&gt;, which contains a value that can be directly edited&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://angular.io/guide/signals#writable-signals" rel="noopener noreferrer"&gt;Computed&lt;/a&gt;, in which the value is derived from other signals; in this case, we can't directly modify the computed value but this type has the added plus that it has a lazy approach. This means that its value will be re-evaluated not when the signals it checks are updated, but when a consumer tries to read the derived computed value, which makes it useful to do complex operations like array filtering.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Signals VS observables
&lt;/h2&gt;

&lt;p&gt;By now, the more careful reader would probably start to think &lt;em&gt;"By this explanation, signals seem to be a copy of RxJS observables, as they seem to do the same thing, so are we reinventing the wheel here ?"&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
To answer this question we need to open another small parenthesis before continuing, to get a clearer context for the ones among us who don't know what observables are.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is an observable?
&lt;/h3&gt;

&lt;p&gt;An &lt;a href="https://rxjs.dev/guide/observable" rel="noopener noreferrer"&gt;observable&lt;/a&gt; is a collection of objects which can be observed in time, they are part of alibrary called &lt;a href="https://rxjs.dev/guide/overview" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt; which is often used in tandem with the Angular framework to manage asynchronous events. Unlike a normal array it does not keep memory of the elements, it just emits them.&lt;br&gt;&lt;br&gt;
To get a silly visual aid: we can imagine an observable as a fast food employee manning the drive-through window: it just knows that it has to deliver bags of objects to consumers as time passes, in an uninterrupted line of customers that go by during the day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sqd412rsfu9a1cugtkn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sqd412rsfu9a1cugtkn.png" alt="Observable as a drive through employee delivering data object to consumer" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As much as they can work with synchronous data, observables shine in working with asynchronous events (clicking on keyboard keys, mouse clicks, HTTP calls responses) or notifications (a completed or failed process). But they are not perfect, as observables require a manual subscription, and of course a manual un-subscription. Moreover, the data is not readily available but has to be extracted from the emitted values stream first.&lt;br&gt;
On the other hand, signals don't need a manual subscription, or more precisely, they have an implicit quasi-subscription automatically managed when a consumer starts listening to a signal's value.&lt;br&gt;
In addition, a signal can be called and read directly, immediately obtaining the value it encapsulates.&lt;br&gt;
These may seem like minor differences, but for &lt;em&gt;simpler&lt;/em&gt; actions signals require much less code and, more importantly, less RxJS experience, which can be extremely powerful but also really difficult for new (and even not-so-new) devs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Are we going to use only signals?
&lt;/h2&gt;

&lt;p&gt;So, the one-million-dollar question is: are signals better than observables?&lt;br&gt;
Well, it depends.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuwm9yoenydihkj8wpp9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuwm9yoenydihkj8wpp9.jpg" alt="It depends written over oranges apples meme" width="746" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you need to observe (no pun intended) values that change with time, without knowing when they do change, so asynchronously, you will be better off using observables. Instead, if time isn't something you need to keep in the equation, you will need only signals, which are simpler to use.&lt;br&gt;
Realistically, in the future, we will most likely use signals for most use cases, and only in some particular circumstances we will need all the power of observables.&lt;/p&gt;

&lt;p&gt;Having reflected upon these differences, you can see how titles that claim that the end of RxJS in favor of signals is imminent are just click-bait. It's just a matter of knowing when to use the right tool for the right job.&lt;br&gt;
More so, the RxJS team, seeing the big picture, has already implemented two functions that allow the &lt;a href="https://angular.io/api/core/rxjs-interop" rel="noopener noreferrer"&gt;interoperability between signals and observables&lt;/a&gt;:&lt;br&gt;
&lt;code&gt;toObservable()&lt;/code&gt;and &lt;code&gt;toSignal()&lt;/code&gt;, allowing the management of complex data flux or asynchronous data without having to give up the usage of signals.&lt;br&gt;
I want to highlight this point, as I think it's one of the key concepts of Angular and its libraries: to always allow retro compatibility, letting new and old functionalities live side-by-side without the risk of breaking anything, which is not to be taken for granted. So let's keep feuds to important matters, like if you can add heavy cream to a carbonara sauce (pro tip: never).&lt;/p&gt;
&lt;h2&gt;
  
  
  Practical examples
&lt;/h2&gt;

&lt;p&gt;Here are some practical examples before and after the usage of signals. They were made by &lt;a href="https://www.youtube.com/@deborah_kurata" rel="noopener noreferrer"&gt;Deborah Kurata&lt;/a&gt;, an amazing tech content creator. At this &lt;a href="https://github.com/DeborahK/Angular-Signals" rel="noopener noreferrer"&gt;GitHub link&lt;/a&gt; you will find the GitHub repository in which you can find her complete project.&lt;br&gt;
These examples are based upon a shopping app, in which we can add items to a cart, and then we can see the total price of the items in the cart. On the left we have the observables version, on the right the signals one. (&lt;strong&gt;Note:&lt;/strong&gt; here I will call the signals version "after" and the observables one "before" for simplicity's sake. Also, the code is simplified for the sake of brevity, but the full code is available in the GitHub repo. Last but not least, instead of &lt;em&gt;Observable&lt;/em&gt; observables, here are used &lt;em&gt;Subject&lt;/em&gt; observables; &lt;a href="https://rxjs.dev/guide/subject" rel="noopener noreferrer"&gt;an RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers&lt;/a&gt;, so for simplicity's sake I will refer to them just as &lt;em&gt;observables&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Let's start with something simple: the differences in the HTML and TS files of the cart-total component. The differences are not huge, but they are there. Especially in the HTML file, in the &lt;em&gt;before&lt;/em&gt; version, we have to use the async pipe to subscribe to the observable, while in the &lt;em&gt;after&lt;/em&gt; version we can just call the signal directly; this can make a difference in streamlining the code if we have to use other pipes, as in the case of &lt;code&gt;| number&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cart-total.component.html before&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card border-secondary"&lt;/span&gt;
  &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"(cartItems$ | async)?.length; else noItems"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-header text-secondary fw-bold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cart Total&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Subtotal:&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{subTotal$ | async | number:'1.2-2'}}
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Delivery:&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;
        &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right"&lt;/span&gt;
        &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"deliveryFee$ | async as deliveryFee"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{deliveryFee | number:'1.2-2'}}
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;
        &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right;color:red"&lt;/span&gt;
        &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"!(deliveryFee$ | async)"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Free
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Estimated Tax:&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{tax$ | async | number:'1.2-2'}}
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Total:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;{{totalPrice$ | async | number:'1.2-2'}}&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cart-total.component.html after&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card border-secondary"&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"cartItems().length; else noItems"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-header text-secondary fw-bold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cart Total&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Subtotal:&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{subTotal() | number:'1.2-2'}}
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Delivery:&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right"&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"deliveryFee()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{deliveryFee() | number:'1.2-2'}}
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;
        &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right;color:red"&lt;/span&gt;
        &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"!deliveryFee()"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Free
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Estimated Tax:&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{tax() | number:'1.2-2'}}
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;Total:&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-4"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:right"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;{{totalPrice() | number:'1.2-2'}}&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cart-total.component.ts before&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CartTotalComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cartItems$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartItems$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;subTotal$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subTotal$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;deliveryFee$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deliveryFee$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;tax$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tax$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;totalPrice$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalPrice$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cart-total.component.ts after&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CartTotalComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cartService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CartService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;cartItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartItems&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;subTotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subTotal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;deliveryFee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deliveryFee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;tax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;totalPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalPrice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most important differences, however, are in the cart service. In the &lt;em&gt;before&lt;/em&gt; version, we have to manually subscribe to the observable, and then manually un-subscribe from it, which is not ideal. Especially considering that we will have to do it for &lt;em&gt;all&lt;/em&gt; of the observables we use. In the &lt;em&gt;after&lt;/em&gt; version, we can just call the signal directly, and it will be automatically managed by Angular.&lt;br&gt;
Another important difference is that in the &lt;em&gt;before&lt;/em&gt; version we have to manually manage the initialization of the observables, while in the &lt;em&gt;after&lt;/em&gt; version we can just initialize the signals with the value we want them to have.&lt;br&gt;
Also, in the &lt;em&gt;before&lt;/em&gt; version, if we need to derive a value from other values, we have to use RxJS functions concatenated by .pipe(), which can make the code difficult to read for someone who doesn't know this library very well, while in the &lt;em&gt;after&lt;/em&gt; version we can just use the &lt;code&gt;computed()&lt;/code&gt; signal type, resulting in a much easier to understand code. We can also see how in the &lt;em&gt;before&lt;/em&gt; version we have to use the &lt;code&gt;next()&lt;/code&gt; function to update the value of the observable, specifying an action, while in the &lt;em&gt;after&lt;/em&gt; version we can just update the value of the signal directly. Lastly, in the &lt;em&gt;after&lt;/em&gt; version we don't need the &lt;code&gt;modifyCart()&lt;/code&gt; function, as we can just update the value of the signal directly in the function, making following the flow of data more fluid.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cart.service.ts before&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CartService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Add item action&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;itemSubject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;itemAction$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asObservable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;cartItems$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemAction$&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;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;itemAction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifyCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;itemAction&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;shareReplay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Total up the extended price for each item&lt;/span&gt;
  &lt;span class="nx"&gt;subTotal$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartItems$&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;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cost_in_credits&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Delivery is free if spending more than 100,000 credits&lt;/span&gt;
  &lt;span class="nx"&gt;deliveryFee$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subTotal$&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;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;999&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="c1"&gt;// Tax could be based on shipping address zip code&lt;/span&gt;
  &lt;span class="nx"&gt;tax$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subTotal$&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;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;10.75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="c1"&gt;// Total price&lt;/span&gt;
  &lt;span class="nx"&gt;totalPrice$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;combineLatest&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subTotal$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deliveryFee$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tax$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;st&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;st&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="c1"&gt;// Add the vehicle to the cart as an Action&amp;lt;CartItem&amp;gt;&lt;/span&gt;
  &lt;span class="nf"&gt;addToCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Vehicle&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Remove the item from the cart&lt;/span&gt;
  &lt;span class="nf"&gt;removeFromCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;updateInCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;update&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Return the updated array of cart items&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;modifyCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CartItem&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;CartItem&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Determine if the item is already in the cart&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemInCart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemInCart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If so, update the quantity&lt;/span&gt;
        &lt;span class="nx"&gt;itemInCart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantity&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;items&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;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;itemInCart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;itemInCart&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;update&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;items&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;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cart.service.ts after&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CartService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Manage state with signals&lt;/span&gt;
  &lt;span class="nx"&gt;cartItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CartItem&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="c1"&gt;// Total up the extended price for each item&lt;/span&gt;
  &lt;span class="nx"&gt;subTotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cartItems&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cost_in_credits&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Delivery is free if spending more than 100,000 credits&lt;/span&gt;
  &lt;span class="nx"&gt;deliveryFee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subTotal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;999&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="c1"&gt;// Tax could be based on shipping address zip code&lt;/span&gt;
  &lt;span class="nx"&gt;tax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subTotal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;10.75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Total price&lt;/span&gt;
  &lt;span class="nx"&gt;totalPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subTotal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deliveryFee&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Add the vehicle to the cart&lt;/span&gt;
  &lt;span class="c1"&gt;// If the item is already in the cart, increase the quantity&lt;/span&gt;
  &lt;span class="nf"&gt;addToCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Vehicle&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cartItems&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;findIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;===&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="c1"&gt;// Not already in the cart, so add with default quantity of 1&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartItems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Already in the cart, so increase the quantity by 1&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartItems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&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;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Remove the item from the cart&lt;/span&gt;
  &lt;span class="nf"&gt;removeFromCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Update the cart with a new array containing&lt;/span&gt;
    &lt;span class="c1"&gt;// all but the filtered out deleted item&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartItems&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;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;updateInCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Update the cart with a new array containing&lt;/span&gt;
    &lt;span class="c1"&gt;// the updated item and all other original items&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartItems&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;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;items&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;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Now that we can see the big picture we can reflect on the initial users' requests made to the Angular team and it will be clear that they have been heard and answered.&lt;br&gt;&lt;br&gt;
Thanks to signals we will have more simplicity in usage to track values for changes in the apps, especially for those who are beginning to work with the framework, greatly reducing boilerplate code.&lt;br&gt;
They will give the apps more &lt;strong&gt;reactivity&lt;/strong&gt;, giving a &lt;strong&gt;boost to performances&lt;/strong&gt; more than even the zone.js + onPush strategy could, without losing any functionality. They will allow much &lt;strong&gt;finer control&lt;/strong&gt; over single components and the value changes inside them, automatically managing the subscription/un-subscription part.&lt;br&gt;&lt;br&gt;
But, as we have seen, signals will not replace observables completely, they will instead co-exist with them in harmony.&lt;br&gt;&lt;br&gt;
Let's make &lt;del&gt;love&lt;/del&gt; code, not war.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>signal</category>
      <category>webdev</category>
      <category>web</category>
    </item>
  </channel>
</rss>
