<?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>Forem: Florian Spier</title>
    <description>The latest articles on Forem by Florian Spier (@spierala).</description>
    <link>https://forem.com/spierala</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%2F400638%2F5d4cddd3-96c5-4d77-ab82-1a289d0e8ff8.jpeg</url>
      <title>Forem: Florian Spier</title>
      <link>https://forem.com/spierala</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/spierala"/>
    <language>en</language>
    <item>
      <title>Two-way bind a Signal Input object value with [(ngModel)]</title>
      <dc:creator>Florian Spier</dc:creator>
      <pubDate>Sat, 15 Feb 2025 11:11:00 +0000</pubDate>
      <link>https://forem.com/playfulprogramming-angular/two-way-bind-a-signal-input-object-value-with-ngmodel-1c2a</link>
      <guid>https://forem.com/playfulprogramming-angular/two-way-bind-a-signal-input-object-value-with-ngmodel-1c2a</guid>
      <description>&lt;p&gt;Recently, I encountered this challenge... Refactor a form component to &lt;a href="https://angular.dev/guide/signals" rel="noopener noreferrer"&gt;Angular Signals&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The old form component works like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The form data comes from a reactive state service &lt;/li&gt;
&lt;li&gt;The form data is an &lt;strong&gt;object&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The form data is cloned before it is passed to the form component&lt;/li&gt;
&lt;li&gt;The form component receives the form data via one classic &lt;a href="https://angular.dev/guide/components/inputs#declaring-inputs-with-the-input-decorator" rel="noopener noreferrer"&gt;decorator-based Angular @Input&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The form is a &lt;a href="https://angular.dev/guide/forms/template-driven-forms" rel="noopener noreferrer"&gt;template-driven form&lt;/a&gt; and uses &lt;a href="https://angular.dev/guide/forms/template-driven-forms#bind-input-controls-to-data-properties" rel="noopener noreferrer"&gt;[(ngModel)]&lt;/a&gt; to &lt;strong&gt;mutate&lt;/strong&gt; the form data object
&lt;/li&gt;
&lt;/ul&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&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; &lt;span class="na"&gt;[(ngModel)]=&lt;/span&gt;&lt;span class="s"&gt;"user.firstName"&lt;/span&gt; &lt;span class="nt"&gt;/&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;ul&gt;
&lt;li&gt;Clicking the save button would send the mutated object to the parent component via an Angular @Output&lt;/li&gt;
&lt;li&gt;The parent component updates the reactive state service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup works great in many of our applications.&lt;/p&gt;

&lt;p&gt;You can review this setup in this StackBlitz which showcases the basic principle: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-x5kjdtku?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Form with classic Angular @Input&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactor to Signal Input
&lt;/h2&gt;

&lt;p&gt;With &lt;a href="https://angular.dev/guide/components/inputs" rel="noopener noreferrer"&gt;Angular Signal Input&lt;/a&gt; we can make our component inputs reactive. This sounds great! &lt;/p&gt;

&lt;p&gt;FYI Signal Inputs are the recommended way for new projects. From the &lt;a href="https://angular.dev/guide/components/inputs#declaring-inputs-with-the-input-decorator" rel="noopener noreferrer"&gt;Angular docs&lt;/a&gt;: &lt;/p&gt;

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

&lt;p&gt;Let's refactor our classic Angular @Input to a Signal Input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Signal Input object value and [(ngModel)]
&lt;/h3&gt;

&lt;p&gt;The Signal Input receives an object of type User. We try to bind to the object properties with &lt;code&gt;[(ngModel)]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This code looks so nice 😍!&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&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;[(ngModel)]=&lt;/span&gt;&lt;span class="s"&gt;"user().firstName"&lt;/span&gt; 
  &lt;span class="nt"&gt;/&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;And in this StackBlitz everything seems to work: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-6zwfbthj?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Form with Signal Input - mutating Signal State&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ‼️ Danger Zone:
&lt;/h3&gt;

&lt;p&gt;But wait..., we have just entered the danger zone... ☢️ ☣️ ⚠️&lt;/p&gt;

&lt;p&gt;What is actually happening?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user()&lt;/code&gt; unwraps the Input Signal. We get hold of the raw user object&lt;/li&gt;
&lt;li&gt;This line of code &lt;code&gt;[(ngModel)]="user().firstName"&lt;/code&gt; will &lt;strong&gt;mutate&lt;/strong&gt; the user object (which is wrapped into a Signal) whenever the text input value changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ☢️ Mutating the Signal object ☣️
&lt;/h3&gt;

&lt;p&gt;Why is mutating the Signal state a bad idea? Because we are bypassing the Signals public API to update state. Normally we should only use the dedicated methods &lt;code&gt;set&lt;/code&gt; or &lt;code&gt;update&lt;/code&gt; in order to update the Signal state.&lt;/p&gt;

&lt;p&gt;Other developers might want to build other Signals on top of the &lt;code&gt;user&lt;/code&gt; Signal with Angular &lt;code&gt;computed&lt;/code&gt;. But computed will never be triggered because the &lt;code&gt;user&lt;/code&gt; Signal does not know about the user object mutations. This might be a surprising behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signal Inputs are read-only
&lt;/h3&gt;

&lt;p&gt;And yes, there is another reason, why using &lt;code&gt;[(ngModel)]&lt;/code&gt; on a Signal Input is at least strange. Signal Inputs are supposed to be read-only. They do not have a &lt;code&gt;set&lt;/code&gt; or &lt;code&gt;update&lt;/code&gt; method - so there is no official support for changing Signal Input state programmatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rescue
&lt;/h3&gt;

&lt;p&gt;Let's try to escape as fast as possible 🚀. What are possible solutions?&lt;/p&gt;

&lt;h2&gt;
  
  
  Linked Signal
&lt;/h2&gt;

&lt;p&gt;With &lt;a href="https://angular.dev/guide/signals/linked-signal#" rel="noopener noreferrer"&gt;Linked Signal&lt;/a&gt; we can create a writable &lt;em&gt;user&lt;/em&gt; Signal, which is updated automatically, whenever the user Signal Input receives a new value. At the same time we can update the Linked Signal with &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;editableUser&lt;/code&gt; is our Linked Signal...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserDetailComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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;editableUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;linkedSignal&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; 

  &lt;span class="nf"&gt;updateEditableUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editableUser&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;state&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;v&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;We also introduced a &lt;code&gt;updateEditableUser&lt;/code&gt; method which uses the public Signal API to update the Signal state: in this case we call the &lt;code&gt;update&lt;/code&gt; method of the Linked Signal.&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&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;[ngModel]=&lt;/span&gt;&lt;span class="s"&gt;"editableUser().firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;(ngModelChange)=&lt;/span&gt;&lt;span class="s"&gt;"updateEditableUser({firstName: $event})"&lt;/span&gt;
  &lt;span class="nt"&gt;/&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;[(ngModel)]&lt;/code&gt; has been split into &lt;code&gt;[ngModel]&lt;/code&gt; and &lt;code&gt;(ngModelChange)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[ngModel]="editableUser().firstName"&lt;/code&gt; will update the text input when the firstName property of the user object has been updated&lt;/li&gt;
&lt;li&gt;whenever the text input value changes, the ngModelChange callback (&lt;code&gt;updateEditableUser&lt;/code&gt;) will be executed and the Linked Signal will be updated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PROs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we use the public Signal API to update state&lt;/li&gt;
&lt;li&gt;we use Linked Signal which is a writable signal&lt;/li&gt;
&lt;li&gt;state changes happen explicitly in a dedicated method&lt;/li&gt;
&lt;li&gt;object clone is not needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CONs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is some boilerplate necessary: Linked Signal setup, ngModel, ngModelChange, method for state update&lt;/li&gt;
&lt;li&gt;At the moment, Linked Signal is still in developer preview (Angular 19)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;StackBlitz: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-yhhtnn73?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Form with Signal Input - Linked Signal&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Effect
&lt;/h2&gt;

&lt;p&gt;An alternative approach is using &lt;a href="https://angular.dev/guide/signals#effects" rel="noopener noreferrer"&gt;Angular &lt;code&gt;effect&lt;/code&gt;&lt;/a&gt; to listen to new values of the Signal input.&lt;br&gt;
When we receive a new value from the Input we assign the raw value to a local class property.&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;UserDetailComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_user&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;[(ngModel)]=&lt;/span&gt;&lt;span class="s"&gt;"user.firstName"&lt;/span&gt; 
  &lt;span class="nt"&gt;/&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;In the template we can mutate the raw object as we always did. &lt;/p&gt;

&lt;p&gt;PROs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The template is identical to our original old-school form component which used a classic Angular @Input&lt;/li&gt;
&lt;li&gt;We officially mutate a raw object (we do not bypass Signal APIs, we do not mutate the read-only Signal Input state).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CONs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user: User&lt;/code&gt; must be initialised: &lt;code&gt;user: User = new User();&lt;/code&gt; or we must tell TypeScript that user is always defined with &lt;code&gt;user!: User;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;cloning is needed (happens in the parent with the structuredClone pipe)&lt;/li&gt;
&lt;li&gt;naming challenge: &lt;code&gt;_user&lt;/code&gt; Signal, &lt;code&gt;'user'&lt;/code&gt; alias, &lt;code&gt;user&lt;/code&gt; property for the raw user object&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;StackBlitz: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-xqpmj63n?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Form with Signal Input - Effect&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  @let approach
&lt;/h2&gt;

&lt;p&gt;With &lt;a href="https://angular.dev/guide/templates/variables#local-template-variables-with-let" rel="noopener noreferrer"&gt;@let&lt;/a&gt;, we can declare variables in the template.&lt;/p&gt;

&lt;p&gt;Let's use @let to get the raw object from the user Signal Input. Additionally, we can also perform the clone with our structuredClone pipe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@let userClone = user() | structuredClone;

&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; 
    &lt;span class="na"&gt;[(ngModel)]=&lt;/span&gt;&lt;span class="s"&gt;"userClone.firstName"&lt;/span&gt; 
  &lt;span class="nt"&gt;/&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;TypeScript:&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;UserDetailComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;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;PROs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimum boilerplate, and smallest code change in comparison the old-school (@Input) form component&lt;/li&gt;
&lt;li&gt;@let is the single place to let the magic happen (unwrap the Signal, clone)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CONs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object value is required, it does not work with primitive values. See &lt;em&gt;Notes&lt;/em&gt; below for more details&lt;/li&gt;
&lt;li&gt;cloning is needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;StackBlitz: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-exuqjkss?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;Form with Signal Input - @let&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Object vs Primitive Values
&lt;/h3&gt;

&lt;p&gt;In the examples above, the component Input received an object value (the user object).&lt;br&gt;
The Linked Signal and Effect approaches would also work with Signal Inputs which use primitive values (string, boolean, number...).&lt;/p&gt;

&lt;p&gt;Let's have a look at the @let approach:&lt;br&gt;
&lt;a href="https://angular.dev/guide/templates/variables#assignability" rel="noopener noreferrer"&gt;@let variables are read-only&lt;/a&gt;... which means we can not reassign new values to a @let variable. Also, not via [(ngModel)]. If we try, then we can see this compile error:&lt;/p&gt;

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

&lt;p&gt;The @let approach requires an object value, which we can mutate.&lt;/p&gt;

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

&lt;p&gt;The "@let approach" seems to be the most straight-forward solution with a minimum of boilerplate.&lt;/p&gt;

&lt;p&gt;Effect and Linked Signal are also valid options, but require more setup.&lt;/p&gt;

&lt;p&gt;We are still evaluating which approach is most suited for our applications and this blogpost should help us to make a good decision.&lt;/p&gt;

&lt;p&gt;I hope that you enjoyed our short visit to the danger zone of mutating Signal state. What do you think of my escape strategies? I am sure there are even more options. Let me know in the comments.&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>10 Reasons for MiniRx Signal Store</title>
      <dc:creator>Florian Spier</dc:creator>
      <pubDate>Fri, 01 Mar 2024 12:33:11 +0000</pubDate>
      <link>https://forem.com/playfulprogramming-angular/10-reasons-for-minirx-signal-store-p8b</link>
      <guid>https://forem.com/playfulprogramming-angular/10-reasons-for-minirx-signal-store-p8b</guid>
      <description>&lt;p&gt;The &lt;a href="https://angular.dev/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt; renaissance is still ongoing. &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;MiniRx&lt;/a&gt; is part of that renaissance and released a new Signal-based state management library for Angular: &lt;strong&gt;&lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md" rel="noopener noreferrer"&gt;MiniRx Signal Store&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md" rel="noopener noreferrer"&gt;MiniRx Signal Store on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@mini-rx/signal-store" rel="noopener noreferrer"&gt;MiniRx Signal Store on NPM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are many reasons why MiniRx Signal Store is a great state management solution for Angular..., but these are the top ten reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;All-in-one solution&lt;/strong&gt;: With MiniRx Signal Store you get three well-defined state containers out of the box.

&lt;ul&gt;
&lt;li&gt;Manage &lt;strong&gt;global&lt;/strong&gt; state at large scale with the &lt;strong&gt;&lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md#redux-api" rel="noopener noreferrer"&gt;Store (Redux) API&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Manage &lt;strong&gt;global&lt;/strong&gt; state with a minimum of boilerplate using &lt;strong&gt;&lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md#feature-store-api" rel="noopener noreferrer"&gt;Feature Stores&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Manage &lt;strong&gt;local&lt;/strong&gt; component state with &lt;strong&gt;&lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md#component-store-api" rel="noopener noreferrer"&gt;Component Stores&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: All three state containers can be easily used together in your application. Depending on the use-case, you can choose the state container which suits your needs.
&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%2F3fpe701m2xa80s7c7c0o.png" alt=" " width="800" height="372"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Highly integrated&lt;/strong&gt;: MiniRx Signal Store was designed as an all-in-one solution from the beginning. This allows for a high level of integration:

&lt;ul&gt;
&lt;li&gt;Feature Store uses the Redux Store under the hood&lt;/li&gt;
&lt;li&gt;Feature Store state integrates into the global state object of the Redux Store&lt;/li&gt;
&lt;li&gt;Feature Store automatically uses all the extensions of the Redux Store (e.g. Redux DevTools extension, ImmutableState extension)&lt;/li&gt;
&lt;li&gt;Feature Store and Component Store share the same API&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Made for modern Angular&lt;/strong&gt;: MiniRx Signal Store uses modern Angular APIs (e.g. Signal, DestroyRef) and offers deep integration with Angular.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New Angular best practices:&lt;/strong&gt; MiniRx Signal Store implements and promotes new Angular best practices:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://angular.dev/guide/signals" rel="noopener noreferrer"&gt;Signals&lt;/a&gt; are used for (synchronous) state&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rxjs.dev/" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt; is used for events and asynchronous tasks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RxJS and Signals interop&lt;/strong&gt;: MiniRx Signal Store streamlines your usage of RxJS and Signals: e.g. &lt;code&gt;connect&lt;/code&gt; and &lt;code&gt;rxEffect&lt;/code&gt; understand both Signals and Observables&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/spierala/angular-state-management-comparison?tab=readme-ov-file#state-management-bundle-size-comparison-angular" rel="noopener noreferrer"&gt;&lt;strong&gt;Lightweight&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extendable&lt;/strong&gt;: MiniRx Signal Store comes with powerful extensions:

&lt;ul&gt;
&lt;li&gt;Immutable State Extension: Make your Signal state immutable to prevent mutating state accidentally.&lt;/li&gt;
&lt;li&gt;Redux DevTools Extension: inspect state and state changes at anytime in the Redux DevTools (available for the Redux Store and Feature Store).&lt;/li&gt;
&lt;li&gt;Undo Extension: Undo state changes.&lt;/li&gt;
&lt;li&gt;Logger Extension: Log actions and updated state in the JS console.&lt;/li&gt;
&lt;li&gt;You can easily create your own extensions!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OOP-style&lt;/strong&gt;: Your fellow fullstack Angular developers, who are used to object-oriented programming (Java, .NET, ...) will love MiniRx Signal Store. MiniRx Signal Store exposes TypeScript classes which can be extended or used with &lt;code&gt;new&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framework-agnostic code&lt;/strong&gt;: Although MiniRx Signal Store is an Angular library, your state management code is almost framework-agnostic. Signals are an internal implementation detail of the Signal Store. Therefore, you can easily refactor your state management layer to the original (RxJS-based) &lt;a href="https://mini-rx.io/" rel="noopener noreferrer"&gt;MiniRx Store&lt;/a&gt; and use it in whatever framework you want (e.g. Svelte).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  You can try MiniRx Signal Store today
&lt;/h3&gt;

&lt;p&gt;Install:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i @mini-rx/signal-store&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Documentation: &lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md" rel="noopener noreferrer"&gt;https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you like MiniRx Signal Store?
&lt;/h3&gt;

&lt;p&gt;Give it a star on GitHub:&lt;br&gt;
⭐ &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;MiniRx platform on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;Special thanks for reviewing this blog post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/PieterVanPoyer" rel="noopener noreferrer"&gt;Pieter van Poyer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>redux</category>
      <category>rxjs</category>
    </item>
    <item>
      <title>Introducing MiniRx Signal Store</title>
      <dc:creator>Florian Spier</dc:creator>
      <pubDate>Wed, 07 Feb 2024 08:30:57 +0000</pubDate>
      <link>https://forem.com/playfulprogramming-angular/introducing-minirx-signal-store-cbo</link>
      <guid>https://forem.com/playfulprogramming-angular/introducing-minirx-signal-store-cbo</guid>
      <description>&lt;p&gt;In Angular 16, we got a new cool and shiny reactive primitive: &lt;a href="https://angular.io/guide/signals" rel="noopener noreferrer"&gt;Signal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The introduction of Angular Signals is probably one of the most disruptive changes in recent years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RxJS is no more?&lt;/li&gt;
&lt;li&gt;Should I avoid RxJS and use Signals for everything? &lt;/li&gt;
&lt;li&gt;Can Signals and RxJS Observables co-exist?&lt;/li&gt;
&lt;li&gt;Are there new Angular best practices?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these questions in mind, MiniRx started exploring Signals, on the search for new Angular best practices.&lt;/p&gt;

&lt;p&gt;The result is a new Signal-based state management library:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MiniRx Signal Store&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signal Store is an &lt;strong&gt;Angular-only&lt;/strong&gt; state management library&lt;/li&gt;
&lt;li&gt;Signal Store &lt;strong&gt;embraces &lt;a href="https://angular.io/guide/signals" rel="noopener noreferrer"&gt;Angular Signals&lt;/a&gt;&lt;/strong&gt; and leverages &lt;strong&gt;Modern Angular APIs&lt;/strong&gt; internally&lt;/li&gt;
&lt;li&gt;Signal Store implements and promotes new &lt;strong&gt;Angular best practices&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Signals&lt;/strong&gt; are used for &lt;strong&gt;(synchronous) state&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RxJS&lt;/strong&gt; is used for events and &lt;strong&gt;asynchronous tasks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Signal Store &lt;strong&gt;streamlines your usage of &lt;a href="https://rxjs.dev/" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt; and &lt;a href="https://angular.io/guide/signals" rel="noopener noreferrer"&gt;Signals&lt;/a&gt;&lt;/strong&gt;: e.g. &lt;code&gt;connect&lt;/code&gt; and &lt;code&gt;rxEffect&lt;/code&gt; understand both Signals and Observables&lt;/li&gt;

&lt;li&gt;Signal Store is based on the same great concept as the original (RxJS-based) &lt;strong&gt;&lt;a href="https://mini-rx.io/" rel="noopener noreferrer"&gt;MiniRx Store&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;It is an &lt;strong&gt;all-in-one solution&lt;/strong&gt; for global and local state, complex and simple state&lt;/li&gt;
&lt;li&gt;You get three well-defined state containers: &lt;strong&gt;Store (Redux), Feature Store&lt;/strong&gt; and  &lt;strong&gt;Component Store&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Highly flexible&lt;/strong&gt;: Do you build complex and more simple features in the same application? You can choose the right state container individually for each feature.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Requirements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Angular &amp;gt;= 16&lt;/li&gt;
&lt;li&gt;RxJS &amp;gt;= 7.4.0&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Install
&lt;/h4&gt;

&lt;p&gt;To install the @mini-rx/signal-store package, use your package manager of choice:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install @mini-rx/signal-store&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  API documentation
&lt;/h4&gt;

&lt;p&gt;The MiniRx Signal Store API is documented in the &lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  New Angular best practices in MiniRx Signal Store
&lt;/h1&gt;

&lt;p&gt;The MiniRx Signal Store is implemented using new Angular best practices.&lt;br&gt;
At the same time MiniRx Signal Store also promotes these best practices in its new API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Signals&lt;/strong&gt; are used for &lt;strong&gt;(synchronous) state&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RxJS&lt;/strong&gt; is used for events and &lt;strong&gt;asynchronous tasks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's read on to understand why MiniRx Signal Store made this choice...&lt;/p&gt;
&lt;h2&gt;
  
  
  Signals
&lt;/h2&gt;

&lt;p&gt;In version 16, Angular introduced &lt;strong&gt;Signals&lt;/strong&gt; as a new &lt;strong&gt;reactive primitive&lt;/strong&gt;. Prior to this, &lt;strong&gt;RxJS&lt;/strong&gt; was the go-to tool for managing state in a reactive manner.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Signals?
&lt;/h3&gt;

&lt;p&gt;Signals in Angular have some advantages, compared to RxJS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write subscription-free code, even without using the &lt;code&gt;async&lt;/code&gt; pipe&lt;/li&gt;
&lt;li&gt;Easier to learn (no pipe, no operators, Signals are always synchronous)&lt;/li&gt;
&lt;li&gt;Easier to compose derived state from other Signals with &lt;code&gt;computed&lt;/code&gt; instead of RxJS &lt;code&gt;combineLatest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Signals may enable more efficient Angular Change Detection in the future&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Signals in MiniRx Signal Store
&lt;/h3&gt;

&lt;p&gt;Hopefully, you agree that Signals are the new best choice for state!&lt;/p&gt;

&lt;p&gt;MiniRx Signal Store definitely made the choice: it uses Angular Signal internally and exposes Signals via its public API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The global state object of the Redux Store (which is also used by the Feature Store) is implemented as Angular Signal&lt;/li&gt;
&lt;li&gt;public API: all three state containers have a &lt;code&gt;select&lt;/code&gt; method: it returns an Angular Signal&lt;/li&gt;
&lt;li&gt;Memoized selectors (used to select state from the global state object) are implemented using Angular &lt;code&gt;computed&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  RxJS
&lt;/h2&gt;

&lt;p&gt;You may ask: &lt;em&gt;Why do we still need RxJS? We have Signals now!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is true, we do not need RxJS anymore &lt;strong&gt;for state&lt;/strong&gt;: it is time to say goodbye to &lt;code&gt;BehaviorSubject&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;But there is still an area where RxJS shines: &lt;strong&gt;events&lt;/strong&gt; and &lt;strong&gt;asynchronous tasks&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Distinct events with RxJS Subject
&lt;/h3&gt;

&lt;p&gt;Signals are &lt;strong&gt;not suited for events&lt;/strong&gt;, because it is possible to miss events. See this little example using Angular &lt;code&gt;effect&lt;/code&gt;:&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/stackblitz-starters-ehyirs?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;StackBlitz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might expect to see all state changes logged in &lt;code&gt;effect&lt;/code&gt;, but that is not the case if Signal state is changed &lt;strong&gt;synchronously&lt;/strong&gt;...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RxJS Subject&lt;/strong&gt; is the better alternative: we are notified about &lt;strong&gt;every&lt;/strong&gt; event (also the synchronous ones). See this example:&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/stackblitz-starters-fbxfuk?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;StackBlitz&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Side effects and race-conditions
&lt;/h3&gt;

&lt;p&gt;When using RxJS-based streams, we can trigger side effects like API-calls and handle race-conditions with RxJS flattening operators (&lt;code&gt;mergeMap&lt;/code&gt;, &lt;code&gt;switchMap&lt;/code&gt;, &lt;code&gt;concatMap&lt;/code&gt;, &lt;code&gt;exhaustMap&lt;/code&gt;).&lt;/p&gt;
&lt;h3&gt;
  
  
  More operators
&lt;/h3&gt;

&lt;p&gt;There is no limit! RxJS has more than 100 &lt;a href="https://rxjs.dev/guide/operators" rel="noopener noreferrer"&gt;operators&lt;/a&gt; which can be used to manipulate your streams.&lt;br&gt;
But to be honest, even a small bunch of operators will take you far: &lt;code&gt;debounceTime&lt;/code&gt;, &lt;code&gt;distinctUntilChanged&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;catchError&lt;/code&gt;, etc&lt;/p&gt;
&lt;h3&gt;
  
  
  RxJS in MiniRx Signal Store
&lt;/h3&gt;

&lt;p&gt;Did you see the strengths of RxJS? &lt;/p&gt;

&lt;p&gt;MiniRx Signal Store made its choice... use RxJS for events and asynchronous tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Action stream of the (Redux) Store represents a stream of Events: it is implemented as RxJS Subject&lt;/li&gt;
&lt;li&gt;Effects: you can &lt;code&gt;pipe&lt;/code&gt; the Action stream to trigger API calls (and use flattening operators to handle race-conditions)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;rxEffect&lt;/code&gt; APIs of Feature Store and Component Store are based on RxJS Subject&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fun fact: even the Component Store uses a small Redux implementation... it has its own (RxJS Subject) Action stream.&lt;/p&gt;
&lt;h1&gt;
  
  
  RxJS and Signal Interop
&lt;/h1&gt;

&lt;p&gt;MiniRx Signal Store will help you to streamline the usage of RxJS Observables and Signals.&lt;br&gt;
The goal is to eliminate any conversion code in your application: say goodbye to &lt;code&gt;toSignal&lt;/code&gt; and to &lt;code&gt;toObservable&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;These MiniRx Signal Store APIs can handle both Observables and Signals:&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;rxEffect&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;rxEffect&lt;/code&gt; is used to trigger side effects like API calls in Feature Store and Component Store.&lt;br&gt;
There are three different ways to trigger the side effect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raw Value&lt;/li&gt;
&lt;li&gt;Signal&lt;/li&gt;
&lt;li&gt;Observable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following (Component Store) example uses an Angular Signal (Input) to trigger the API call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createComponentStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tapResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mini-rx/signal-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;switchMap&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BookService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../book.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BookDetail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookComponent&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;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createComponentStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&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;bookService&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;BookService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;bookId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Signal Input&lt;/span&gt;

  &lt;span class="nl"&gt;bookDetail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BookDetail&lt;/span&gt;&lt;span class="o"&gt;&amp;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="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;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="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Create an Effect&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;loadDetail&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;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rxEffect&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle race-condition with switchMap&lt;/span&gt;
    &lt;span class="nf"&gt;switchMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="k"&gt;return&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;bookService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBookDetail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;tapResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BookDetail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;})},&lt;/span&gt;
          &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Fetch detail for every new bookId Signal value&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;loadDetail&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;bookId&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;h3&gt;
  
  
  &lt;code&gt;connect&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Available in Feature Store, Component Store.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;connect&lt;/code&gt; you have the possibility to connect your store with external sources like Observables and Signals.&lt;br&gt;
This helps to make your store the Single Source of Truth for your state.&lt;/p&gt;

&lt;p&gt;We are connecting the Component Store to both Observable and Signal in this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CommonModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createComponentStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mini-rx/signal-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConnectComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createComponentStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;counter&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;counterFromObservable&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;// Will be updated via Observable&lt;/span&gt;
    &lt;span class="na"&gt;counterFromSignal&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;// Will be updated via Signal&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nl"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="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;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counterFromObservable&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counterFromSignal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&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;observableCounter$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Observable&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signalCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Signal&lt;/span&gt;

    &lt;span class="c1"&gt;// Connect external sources (Observables or Signals) to the Component Store&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;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;counterFromObservable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;observableCounter$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Observable&lt;/span&gt;
      &lt;span class="na"&gt;counterFromSignal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;signalCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Signal&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;signalCounter&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;v&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;v&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="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;increment&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;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  All-in-one solution
&lt;/h1&gt;

&lt;p&gt;With MiniRx Signal Store you get three well-defined state containers out of the box:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage &lt;strong&gt;global&lt;/strong&gt; state at large scale with the &lt;strong&gt;&lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md#redux-api" rel="noopener noreferrer"&gt;Store (Redux) API&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Manage &lt;strong&gt;global&lt;/strong&gt; state with a minimum of boilerplate using &lt;strong&gt;&lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md#feature-store-api" rel="noopener noreferrer"&gt;Feature Stores&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Manage &lt;strong&gt;local&lt;/strong&gt; component state with &lt;strong&gt;&lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md#component-store-api" rel="noopener noreferrer"&gt;Component Stores&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The MiniRx Signal Store API is documented in the &lt;a href="https://github.com/spierala/mini-rx-store/blob/master/libs/signal-store/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flexibility
&lt;/h2&gt;

&lt;p&gt;All three state containers can be easily used together in your application.&lt;br&gt;
Depending on the use-case, you can choose the state container which suits your needs.&lt;/p&gt;

&lt;p&gt;See here the most typical use-cases:&lt;/p&gt;

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

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

&lt;p&gt;These are exciting times for Angular: old best practices disappear, new ones have to be explored.&lt;br&gt;
You saw MiniRx exploring Signals and RxJS. MiniRx Signal Store is the result of that exploration.&lt;/p&gt;

&lt;p&gt;MiniRx Signal Store is an incredibly flexible state management solution:&lt;br&gt;
It does not matter if you manage global or local state, complex or simple state... MiniRx Signal Store has you covered!&lt;/p&gt;

&lt;p&gt;With its flexibility and new Angular best practices on board, MiniRx Signal Store will navigate you through modern Angular!&lt;/p&gt;

&lt;h2&gt;
  
  
  ⭐ MiniRx on GitHub
&lt;/h2&gt;

&lt;p&gt;Do you like MiniRx? Give it a GitHub star &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Demos
&lt;/h2&gt;

&lt;p&gt;MiniRx Signal Store was successfully tested in these projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/trungvose/angular-tetris/pull/45" rel="noopener noreferrer"&gt;Angular Tetris&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/trungvose/jira-clone-angular/pull/99" rel="noopener noreferrer"&gt;Angular Jira Clone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://signal-store-demo.mini-rx.io/" rel="noopener noreferrer"&gt;MiniRx Signal Store Demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Release
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@mini-rx/signal-store" rel="noopener noreferrer"&gt;MiniRx Signal Store 1.0.0&lt;/a&gt; was published today!&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;Special thanks for reviewing this blog post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tomasz Ducin: &lt;a href="https://twitter.com/tomasz_ducin" rel="noopener noreferrer"&gt;twitter&lt;/a&gt;, &lt;a href="http://ducin.dev" rel="noopener noreferrer"&gt;ducin.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>redux</category>
      <category>webdev</category>
      <category>rxjs</category>
    </item>
    <item>
      <title>MiniRx Signal Store for Angular - API Preview</title>
      <dc:creator>Florian Spier</dc:creator>
      <pubDate>Fri, 17 Nov 2023 15:14:47 +0000</pubDate>
      <link>https://forem.com/playfulprogramming-angular/minirx-signal-store-for-angular-api-preview-4e16</link>
      <guid>https://forem.com/playfulprogramming-angular/minirx-signal-store-for-angular-api-preview-4e16</guid>
      <description>&lt;p&gt;MiniRx &lt;strong&gt;Signal Store&lt;/strong&gt; is in the making...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤓 See the Signal Store &lt;strong&gt;RFC&lt;/strong&gt; on GitHub discussions: &lt;a href="https://github.com/spierala/mini-rx-store/discussions/188" rel="noopener noreferrer"&gt;https://github.com/spierala/mini-rx-store/discussions/188&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤓 Signal Store &lt;strong&gt;Pull Request&lt;/strong&gt; on GitHub: &lt;a href="https://github.com/spierala/mini-rx-store/pull/195" rel="noopener noreferrer"&gt;https://github.com/spierala/mini-rx-store/pull/195&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A pre-release version can be loaded from npm: &lt;a href="https://www.npmjs.com/package/@mini-rx/signal-store" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@mini-rx/signal-store&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What can we expect from MiniRx Signal Store?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Signal Store is an &lt;strong&gt;&lt;a href="https://angular.dev/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;-only&lt;/strong&gt; state management library&lt;/li&gt;
&lt;li&gt;Signal Store &lt;strong&gt;embraces &lt;a href="https://angular.io/guide/signals" rel="noopener noreferrer"&gt;Angular Signals&lt;/a&gt;&lt;/strong&gt; and leverages &lt;strong&gt;Modern Angular APIs&lt;/strong&gt; internally&lt;/li&gt;
&lt;li&gt;Signal Store is based on the same great concept as the original &lt;strong&gt;&lt;a href="https://mini-rx.io/" rel="noopener noreferrer"&gt;MiniRx Store&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Manage &lt;strong&gt;global&lt;/strong&gt; state at large scale with the &lt;strong&gt;Store (Redux) API&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Manage &lt;strong&gt;global&lt;/strong&gt; state with a minimum of boilerplate using &lt;strong&gt;Feature Stores&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Manage &lt;strong&gt;local&lt;/strong&gt; component state with &lt;strong&gt;Component Stores&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;MiniRx always tries to find the sweet spot between powerful, simple and &lt;a href="https://github.com/spierala/angular-state-management-comparison" rel="noopener noreferrer"&gt;lightweight&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Signal Store implements and promotes new &lt;strong&gt;Angular best practices&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Signals&lt;/strong&gt; are used for &lt;strong&gt;(synchronous) state&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RxJS&lt;/strong&gt; is used for events and &lt;strong&gt;asynchronous tasks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Signal Store helps to streamline your usage of &lt;a href="https://rxjs.dev/" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt; and &lt;a href="https://angular.io/guide/signals" rel="noopener noreferrer"&gt;Signals&lt;/a&gt;: e.g. &lt;code&gt;connect&lt;/code&gt; and &lt;code&gt;rxEffect&lt;/code&gt; understand both Signals and Observables&lt;/li&gt;

&lt;li&gt;Simple refactor: If you used MiniRx Store before, refactor to Signal Store will be pretty straight-forward: change the TypeScript imports, remove the Angular async pipes (and ugly non-null assertions (&lt;code&gt;!&lt;/code&gt;)) from the template&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  API Preview
&lt;/h1&gt;

&lt;p&gt;Let's have a closer look at the Signal Store API.&lt;/p&gt;

&lt;p&gt;Most APIs are very similar to the original MiniRx Store. We will focus here on the changed and new APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Component Store and Feature Store
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;FYI&lt;/em&gt; Feature Store and Component Store share the same API (just their internal working and their use-cases are different). &lt;/p&gt;

&lt;p&gt;In the examples below we look at Component Store, but you can expect the same API changes for Feature Store.&lt;/p&gt;

&lt;p&gt;All code examples can be found back in &lt;a href="https://stackblitz.com/edit/stackblitz-starters-6mbywk?file=src%2Fmain.ts" rel="noopener noreferrer"&gt;this StackBlitz&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  select
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;select&lt;/code&gt; is used to select state from your Component Store. &lt;/p&gt;

&lt;p&gt;You can probably guess it already..., the &lt;code&gt;select&lt;/code&gt; method returns an &lt;strong&gt;Angular Signal&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createComponentStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mini-rx/signal-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SelectDemoComponent&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;cs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createComponentStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;counter&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="nl"&gt;doubleCounter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="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;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&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;Read the Signal like this in the template:&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;pre&amp;gt;&lt;/span&gt;
  doubleCount: {{doubleCounter()}},
&lt;span class="nt"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;select&lt;/code&gt; method is exposed by Store, Feature Store and Component Store.&lt;/p&gt;

&lt;p&gt;StackBlitz demo: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-6mbywk?file=src%2Fselect-demo%2Fselect-demo.component.ts" rel="noopener noreferrer"&gt;SelectDemoComponent&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;del&gt;setInitialState&lt;/del&gt;
&lt;/h3&gt;

&lt;p&gt;There is no &lt;code&gt;setInitialState&lt;/code&gt; method anymore in Feature Store/Component Store for lazy state initialisation. &lt;br&gt;
An initialState is now always required by Feature Store and Component Store, which is more inline with native Angular Signals.&lt;/p&gt;
&lt;h3&gt;
  
  
  connect
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;connect&lt;/code&gt; method is new! With &lt;code&gt;connect&lt;/code&gt; you can &lt;strong&gt;connect&lt;/strong&gt; your store with external sources like &lt;strong&gt;Observables and Signals&lt;/strong&gt;.&lt;br&gt;
This helps to make your store the &lt;strong&gt;Single Source of Truth&lt;/strong&gt; for your state.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;FYI&lt;/em&gt; &lt;code&gt;setState&lt;/code&gt; does not support an Observable parameter anymore, use &lt;code&gt;connect&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ComponentStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createComponentStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mini-rx/signal-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;counterFromObservable&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="nl"&gt;counterFromSignal&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConnectDemoComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ComponentStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createComponentStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;counterFromObservable&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;counterFromSignal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&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;observableCounter$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Observable&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signalCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Signal&lt;/span&gt;

    &lt;span class="c1"&gt;// Connect external sources (Observables or Signals) to the Component Store&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;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;counterFromObservable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;observableCounter$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Observable&lt;/span&gt;
      &lt;span class="na"&gt;counterFromSignal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;signalCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Signal&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;signalCounter&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;v&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;v&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="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access the Signals in the Component template:&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="c"&gt;&amp;lt;!-- Access top level state properties easily from the cs.state Signal --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ng-container&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"cs.state() as state"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;
    counterFromRxJS: {{ state.counterFromObservable }}, 
    counterFromSignal: {{ state.counterFromSignal }}
  &lt;span class="nt"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ng-container&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;StackBlitz demo: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-6mbywk?file=src%2Fconnect-demo%2Fconnect-demo.component.ts" rel="noopener noreferrer"&gt;ConnectDemoComponent&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  rxEffect
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;effect&lt;/code&gt; method has been renamed to &lt;code&gt;rxEffect&lt;/code&gt; (to avoid confusion with the Angular Signal &lt;code&gt;effect&lt;/code&gt; function).&lt;/p&gt;

&lt;p&gt;Feature Store and Component Store expose the &lt;code&gt;rxEffect&lt;/code&gt; method to trigger side effects like API calls.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rxEffect&lt;/code&gt; returns a function which can be called later to start the side effect with an optional payload.&lt;/p&gt;

&lt;p&gt;In the following example you can see that you can trigger the side effect with &lt;strong&gt;a Raw Value, an Observable and of course a Signal&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormControl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactiveFormsModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createComponentStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tapResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mini-rx/signal-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;switchMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="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;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;cities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EffectDemoComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createComponentStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;cities&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;private&lt;/span&gt; &lt;span class="nx"&gt;fetchCitiesEffect&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;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rxEffect&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;switchMap&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filter&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;tapResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;cities&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
          &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;formControl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormControl&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;filterChangeObservable$&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;formControl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueChanges&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;filterChangeSignal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Observable&lt;/span&gt;
    &lt;span class="c1"&gt;// Every emission of the Observable will trigger the API call&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;fetchCitiesEffect&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;filterChangeObservable$&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Signal&lt;/span&gt;
    &lt;span class="c1"&gt;// The Signals initial value will immediately trigger the API call&lt;/span&gt;
    &lt;span class="c1"&gt;// Every new Signal value will trigger the API call&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;fetchCitiesEffect&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;filterChangeSignal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;triggerEffectWithSignal&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 Signal value&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;filterChangeSignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filterChangeSignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filterChangeSignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&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="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;triggerEffectWithRawValue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Trigger the API call with a raw value&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;fetchCitiesEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Phi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Component template:&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="c"&gt;&amp;lt;!-- Access top level state properties easily from the cs.state Signal --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ng-container&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"cs.state() as state"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Trigger Effect with RxJS Observable (FormControl.valueChanges):&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;[formControl]=&lt;/span&gt;&lt;span class="s"&gt;"formControl"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Search city..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;cities: {{state.cities | json}}&lt;span class="nt"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;  

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"triggerEffectWithSignal()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Trigger Effect with Signal&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"triggerEffectWithRawValue()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Trigger Effect with Raw Value&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ng-container&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;StackBlitz demo: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-6mbywk?file=src%2Feffect-demo%2Feffect-demo.component.ts" rel="noopener noreferrer"&gt;EffectDemoComponent&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Component Store destruction
&lt;/h3&gt;

&lt;p&gt;With Signal Store you can safely create a Component Store inside components. The Component Store will be automatically destroyed together with the component.&lt;/p&gt;

&lt;p&gt;This is possible because the Component Store uses Angular &lt;code&gt;DestroyRef&lt;/code&gt; internally.&lt;/p&gt;

&lt;p&gt;Example: Child component with a local Component Store. The child component visibility is toggled in the parent component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DestroyDemoChildComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Create a local Component Store&lt;/span&gt;
  &lt;span class="nx"&gt;cs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createComponentStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;counter&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="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Connect a RxJS timer to the Component Store&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;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;timer&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;timer emission:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// We can see the logging WHILE the ChildComponent is visible (see the JS console)&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;When the child component is destroyed, the Component Store will be destroyed as well. &lt;br&gt;
The cleanup logic of Component Store will be executed which unsubscribes from all internal subscriptions (which includes the timer subscription).&lt;/p&gt;

&lt;p&gt;StackBlitz demo: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-6mbywk?file=src%2Fdestroy-demo%2Fchild%2Fdestroy-demo-child.component.ts" rel="noopener noreferrer"&gt;DestroyDemoChildComponent&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Immutable Signal state
&lt;/h2&gt;

&lt;p&gt;When using Angular Signals you can bypass the Signal &lt;code&gt;update&lt;/code&gt; or &lt;code&gt;set&lt;/code&gt; methods and mutate state at anytime.&lt;/p&gt;

&lt;p&gt;This can cause unexpected behaviour and bugs.&lt;/p&gt;

&lt;p&gt;MiniRx Signal Store comes with the ImmutableState Extension to prevent mutations (which exists also in the original MiniRx Store).&lt;/p&gt;

&lt;p&gt;If you accidentally mutate the state, an error will be thrown in the JS console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ImmutableDemoComponent&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;signalState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;counter&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="nx"&gt;counterFromSignal&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;signalState&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;cs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createComponentStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;counter&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="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ImmutableStateExtension&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// FYI you could add extensions globally with `provideComponentStoreConfig` in main.ts&lt;/span&gt;
  &lt;span class="p"&gt;]});&lt;/span&gt;
  &lt;span class="nx"&gt;counterFromComponentStore&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;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// SIGNAL&lt;/span&gt;
  &lt;span class="c1"&gt;// valid state update&lt;/span&gt;
  &lt;span class="nf"&gt;incrementSignalCounter&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;signalState&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;state&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="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;// Signal Mutations&lt;/span&gt;
  &lt;span class="c1"&gt;// no error, you are entering danger zone, without knowing it&lt;/span&gt;
  &lt;span class="nf"&gt;mutateSignalA&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="nf"&gt;signalState&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;mutateSignalB&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;signalState&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;state&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;666&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;state&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;// COMPONENT STORE&lt;/span&gt;
  &lt;span class="c1"&gt;// valid state update&lt;/span&gt;
  &lt;span class="nf"&gt;incrementComponentStoreCounter&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;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="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;// Component Store Signal Mutations&lt;/span&gt;
  &lt;span class="c1"&gt;// As expected, mutating state will throw an error&lt;/span&gt;
  &lt;span class="nf"&gt;mutateComponentStoreSignalA&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;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;state&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;mutateComponentStoreSignalB&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;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;666&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;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;StackBlitz demo: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-6mbywk?file=src%2Fimmutable-demo%2Fimmutable-demo.component.ts" rel="noopener noreferrer"&gt;ImmutableDemoComponent&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Memoized Signal Selectors
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;createSelector&lt;/code&gt;, &lt;code&gt;createFeatureStateSelector&lt;/code&gt; and &lt;code&gt;createComponentStateSelector&lt;/code&gt; return a &lt;strong&gt;SignalSelector&lt;/strong&gt; function.&lt;br&gt;
Signal Selector functions take a Signal and return a Signal.&lt;/p&gt;

&lt;p&gt;You can pass Signal Selectors to the &lt;code&gt;select&lt;/code&gt; method of Store, Feature Store and Component Store.&lt;/p&gt;

&lt;p&gt;Signal Selectors are memoized for fewer computations of the projector function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fun fact&lt;/strong&gt;: Angular Signal &lt;code&gt;computed&lt;/code&gt; is used to implement Signal Selectors.&lt;/p&gt;

&lt;p&gt;Example: Selecting state from the Redux Store&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createFeatureStateSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Store&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@mini-rx/signal-store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TodosState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./todo-state&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Memoized SignalSelectors&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getFeature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createFeatureStateSelector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TodosState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getFeature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&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;getTodosDone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;todos&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="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;isDone&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;getTodosNotDone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;todos&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&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;isDone&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MemoizedSignalSelectorsDemoComponent&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;store&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;Store&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Store is provided in the main.js file&lt;/span&gt;
  &lt;span class="nl"&gt;todosDone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTodosDone&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;todosNotDone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTodosNotDone&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;Access the Signals in the Component template:&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;pre&amp;gt;&lt;/span&gt;DONE: {{ todosDone() | json }}&lt;span class="nt"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;NOT DONE: {{ todosNotDone() | json }}&lt;span class="nt"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;StackBlitz demo: &lt;a href="https://stackblitz.com/edit/stackblitz-starters-6mbywk?file=src%2Fmemoized-signal-selectors-demo%2Fmemoized-signal-selectors-demo.component.ts" rel="noopener noreferrer"&gt;MemoizedSignalSelectorsDemoComponent&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Store (Redux)
&lt;/h2&gt;

&lt;p&gt;Let's have a quick look at the API changes of the Store (Redux) API...&lt;/p&gt;

&lt;h3&gt;
  
  
  select
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;select&lt;/code&gt; is used to select state from your store. The &lt;code&gt;select&lt;/code&gt; method returns an Angular Signal.&lt;/p&gt;

&lt;p&gt;We can look again at the memoized selectors example to see &lt;code&gt;select&lt;/code&gt; in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createFeatureStateSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Store&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@mini-rx/signal-store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TodosState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./todo-state&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MemoizedSignalSelectorsDemoComponent&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;store&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;Store&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Store is provided in the main.js file&lt;/span&gt;
  &lt;span class="nl"&gt;todosDone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTodosDone&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;todosNotDone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTodosNotDone&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;h3&gt;
  
  
  createRxEffect
&lt;/h3&gt;

&lt;p&gt;The (Redux) Store effects API is pretty much unchanged. Just &lt;code&gt;createEffect&lt;/code&gt; has been renamed to &lt;code&gt;createRxEffect&lt;/code&gt;. The new name clearly indicates that the method is used in relation to RxJS Observables.&lt;/p&gt;

&lt;p&gt;Small example from the &lt;a href="https://github.com/spierala/mini-rx-store/discussions/188" rel="noopener noreferrer"&gt;Signal Store RFC&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;createRxEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;mapResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mini-rx/signal-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ofType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ts-action-operators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductsEffects&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;productService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProductsApiService&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;actions$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Actions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nx"&gt;loadProducts$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRxEffect&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;actions$&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;ofType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;mergeMap&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProducts&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;mapResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loadSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loadFail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="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;
  
  
  Standalone APIs
&lt;/h2&gt;

&lt;p&gt;MiniRx Signal Store got modern Angular standalone APIs.&lt;/p&gt;

&lt;p&gt;Here is a quick overview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;provideStore&lt;/code&gt;: Set up the Redux Store with reducers, metaReducers and extensions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;provideFeature&lt;/code&gt;: Add a feature state with a reducer (via the route config)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;provideEffects&lt;/code&gt;: Register effects (via the route config)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;provideComponentStoreConfig&lt;/code&gt;: Configure all Component Stores with the same config&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;FYI&lt;/em&gt; In module-based Apps you can still use the classic API: &lt;code&gt;StoreModule.forRoot()&lt;/code&gt;, &lt;code&gt;StoreModule.forFeature()&lt;/code&gt;, &lt;code&gt;EffectsModule.register()&lt;/code&gt; and &lt;code&gt;ComponentStoreModule.forRoot()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feedback
&lt;/h2&gt;

&lt;p&gt;We hope that you like the upcoming Signal Store! &lt;/p&gt;

&lt;p&gt;If you see things which could be better or different, please let us know and leave a comment.&lt;/p&gt;

&lt;p&gt;You can also contribute to Signal Store by commenting on the &lt;a href="https://github.com/spierala/mini-rx-store/discussions/188" rel="noopener noreferrer"&gt;RFC&lt;/a&gt; or &lt;a href="https://github.com/spierala/mini-rx-store/pull/195" rel="noopener noreferrer"&gt;Pull Request&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;Special thanks for reviewing this blog post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/PieterVanPoyer" rel="noopener noreferrer"&gt;Pieter van Poyer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>rxjs</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Angular and RxJS on Mastodon</title>
      <dc:creator>Florian Spier</dc:creator>
      <pubDate>Sat, 26 Nov 2022 07:12:58 +0000</pubDate>
      <link>https://forem.com/spierala/angular-and-rxjs-on-mastodon-7c3</link>
      <guid>https://forem.com/spierala/angular-and-rxjs-on-mastodon-7c3</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR&lt;/em&gt; While Elon Musk is doing his best to destroy Twitter, I created my new social media presence on Mastodon. &lt;a href="https://mas.to/@spierala" rel="noopener noreferrer"&gt;Follow me on Mastodon&lt;/a&gt; for great &lt;a href="https://angular.io/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt; and &lt;a href="https://rxjs.dev/" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt; content!&lt;/p&gt;

&lt;p&gt;I used to be quite &lt;a href="https://twitter.com/spierala" rel="noopener noreferrer"&gt;active on Twitter&lt;/a&gt; and found there a very nice Angular community. I learned a lot from the great people there and sometimes somebody could even learn from me. :) It was super cool and fun there!  &lt;/p&gt;

&lt;p&gt;But since Elon Musk took over, I have totally lost my motivation to post on Twitter. Twitter is not the same place anymore. And most importantly, the owner of my main social media platform shouldn't be &lt;a href="https://twitter.com/elonmusk" rel="noopener noreferrer"&gt;crazy&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Last Resort: Mastodon
&lt;/h2&gt;

&lt;p&gt;I find &lt;a href="https://joinmastodon.org/" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt; very interesting... It is &lt;a href="https://github.com/mastodon" rel="noopener noreferrer"&gt;open source&lt;/a&gt;. Everyone of us can help to shape it. No crazy person can ever own it.&lt;/p&gt;

&lt;p&gt;For me, it is time to move on, and Mastodon could be the right place.&lt;/p&gt;

&lt;p&gt;After hanging out on Mastodon for a few weeks, I can say: it feels great, a breath of fresh air! &lt;/p&gt;

&lt;h3&gt;
  
  
  I like
&lt;/h3&gt;

&lt;p&gt;Some things which I like about Mastodon:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;500 characters&lt;/strong&gt;: It is easier to write something useful with more insight. It feels much more like writing a small blog post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edit posts&lt;/strong&gt;: I used that a lot already :) Fixing typos or improving the content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeline without algorithm&lt;/strong&gt;. The timeline is just sorted chronologically. That gives me peace. You can also not see "likes" directly: You can not judge a post by its "likes/retweets" at first sight. The content matters more.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Room for improvement
&lt;/h3&gt;

&lt;p&gt;There are also some issues which should be mentioned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;More difficult to register&lt;/strong&gt;: You have to &lt;a href="https://joinmastodon.org/servers" rel="noopener noreferrer"&gt;find a Mastodon server&lt;/a&gt; which suits your needs. There are some criteria to consider: moderation, server rules, server location, interests of the users, number of users, how long does the server exist already, do I trust the server admin. Some people have a hard time to choose a server. I feel you!
But at the same time the server does not matter too much. You can move to another server whenever you want. &lt;/li&gt;
&lt;li&gt;It is &lt;strong&gt;not so straightforward to follow&lt;/strong&gt; people from other Mastodon servers. You have to visit your own Mastodon server and copy paste their Mastodon handle in the search input.&lt;/li&gt;
&lt;li&gt;There is still a &lt;strong&gt;lack of interaction&lt;/strong&gt;, but that should be a question of time. In my early Twitter days, I was shouting into the void as well :)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My Angular and RxJS content on Mastodon
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://mas.to/@spierala" rel="noopener noreferrer"&gt;My posts on Mastodon&lt;/a&gt; are mostly about &lt;a href="https://mas.to/@spierala/tagged/angular" rel="noopener noreferrer"&gt;Angular&lt;/a&gt; and &lt;a href="https://mas.to/@spierala/tagged/rxjs" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a small selection of my more interesting posts on Mastodon:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mas.to/@spierala/109511021779304584" rel="noopener noreferrer"&gt;1000 ways to restrict an Angular form input&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mas.to/@spierala/109399006762686297" rel="noopener noreferrer"&gt;Stop using Angular Shared Modules, use SCAMs (Single Component Angular Modules)!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mas.to/@spierala/109386553571759360" rel="noopener noreferrer"&gt;Netanel Basal is the Banksy of the Angular community...&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mas.to/@spierala/109352749878645689" rel="noopener noreferrer"&gt;Another round of Reactive Forms vs Template Driven Forms in Angular&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mas.to/@spierala/109341425550749309" rel="noopener noreferrer"&gt;Should you unsubscribe from Http Observables in Angular?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mas.to/@spierala/109316090415147379" rel="noopener noreferrer"&gt;Show-casing my latest reactive state management library: Local Redux Store&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mas.to/@spierala/109307507209694963" rel="noopener noreferrer"&gt;Did I find a RxJS anti-pattern for fetching data? Or is it best practice? ;)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mas.to/@spierala/109630499110542357" rel="noopener noreferrer"&gt;How would you add cancellation to a series of chained API calls in RxJS?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Angular community on Mastodon
&lt;/h3&gt;

&lt;p&gt;Several well-known people from the Angular community are present on Mastodon already! Find them back in this post:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mas.to/@spierala/109353671553937924" rel="noopener noreferrer"&gt;A thread about finding Angular people on Mastodon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the replies to the post you can find even more!&lt;/p&gt;

&lt;p&gt;And you? I hope to see you soon on &lt;a href="(https://joinmastodon.org/)"&gt;Mastodon&lt;/a&gt; as well! Together we can make Mastodon a great place!&lt;/p&gt;

&lt;p&gt;Florian&lt;/p&gt;

</description>
      <category>github</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>MiniRx Feature Store vs. NgRx Component Store vs. Akita</title>
      <dc:creator>Florian Spier</dc:creator>
      <pubDate>Tue, 30 Nov 2021 07:44:29 +0000</pubDate>
      <link>https://forem.com/playfulprogramming-angular/minirx-feature-store-vs-ngrx-component-store-vs-akita-4983</link>
      <guid>https://forem.com/playfulprogramming-angular/minirx-feature-store-vs-ngrx-component-store-vs-akita-4983</guid>
      <description>&lt;p&gt;&lt;strong&gt;MiniRx "Feature Stores"&lt;/strong&gt; offer &lt;strong&gt;simple yet powerful state management&lt;/strong&gt;.&lt;br&gt;
How does &lt;strong&gt;MiniRx Feature Store&lt;/strong&gt; compare to &lt;strong&gt;@ngrx/component-store&lt;/strong&gt; and &lt;strong&gt;@datorama/akita&lt;/strong&gt;? 10 rounds in the &lt;strong&gt;fighting ring&lt;/strong&gt; will bring clarity!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I am the maintainer of MiniRx Store, I try to be fair, but it can be difficult from time to time.&lt;br&gt;
To be clear: Component Store and Akita are great state management libraries. It will be an intense fight, but I will make sure that nobody gets hurt!&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What is MiniRx?
&lt;/h2&gt;

&lt;p&gt;MiniRx is a full-blown &lt;strong&gt;Redux&lt;/strong&gt; Store powered by &lt;strong&gt;RxJS&lt;/strong&gt;: It includes actions, reducers, meta reducers, memoized selectors, effects and Redux DevTools support.&lt;/p&gt;

&lt;p&gt;The Redux pattern is great to manage state at large scale, but it forces us to write boilerplate code (actions, reducers, dispatch actions). This can be overkill for simple features in your application.&lt;/p&gt;

&lt;p&gt;For that reason, MiniRx &lt;strong&gt;Feature Store&lt;/strong&gt; offers a more simple form of state management: we can &lt;strong&gt;bypass Redux boilerplate&lt;/strong&gt; and interact &lt;strong&gt;directly&lt;/strong&gt; with a corresponding &lt;strong&gt;feature state&lt;/strong&gt; with the &lt;code&gt;FeatureStore&lt;/code&gt; API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;setState()&lt;/code&gt; update the feature state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;select()&lt;/code&gt; select state from the feature state object as RxJS Observable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;effect()&lt;/code&gt; run side effects like API calls and update feature state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;undo()&lt;/code&gt; easily undo setState actions (requires the UndoExtension)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get state()&lt;/code&gt; imperatively get the current feature state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MiniRx scales nicely with your state management requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make hard things simple with the Redux &lt;code&gt;Store&lt;/code&gt; API&lt;/li&gt;
&lt;li&gt;Keep simple things simple with the &lt;code&gt;FeatureStore&lt;/code&gt; API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most cases you can default to the &lt;code&gt;FeatureStore&lt;/code&gt; API and fall back to the Redux &lt;code&gt;Store&lt;/code&gt; API to implement the really complex features in your application.&lt;/p&gt;
&lt;h4&gt;
  
  
  How does the Feature Store work?
&lt;/h4&gt;

&lt;p&gt;Feature Store uses Redux under the hood:&lt;br&gt;
Behind the scenes a Feature Store is creating a &lt;em&gt;feature reducer&lt;/em&gt; and a corresponding &lt;em&gt;setState&lt;/em&gt; action.&lt;br&gt;
The &lt;em&gt;feature reducer&lt;/em&gt; is registered in the Redux Store and the Feature Store state becomes part of the global state object.&lt;br&gt;
When calling &lt;code&gt;setState()&lt;/code&gt; the Feature Store dispatches its &lt;em&gt;setState&lt;/em&gt; action (with the new state as action payload) and the &lt;em&gt;feature reducer&lt;/em&gt; will update the feature state accordingly.&lt;/p&gt;

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

&lt;p&gt;See the &lt;code&gt;FeatureStore&lt;/code&gt; source &lt;a href="https://github.com/spierala/mini-rx-store/blob/3.0.0/projects/mini-rx-store/src/lib/feature-store.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Links
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;🤓 Learn more about MiniRx on the &lt;a href="https://mini-rx.io" rel="noopener noreferrer"&gt;docs site&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;MiniRx on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🚀 See it in action in the &lt;a href="https://angular-demo.mini-rx.io/" rel="noopener noreferrer"&gt;Angular Demo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤓 &lt;a href="https://mini-rx.io/docs/fs-quick-start" rel="noopener noreferrer"&gt;Feature Store docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🚀 &lt;a href="https://stackblitz.com/edit/mini-rx-store-basic-tutorial?file=index.ts" rel="noopener noreferrer"&gt;MiniRx Basic Tutorial on StackBlitz&lt;/a&gt;:
See how the Redux API and Feature Store API both add to the global state object&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  MiniRx Feature Store vs. NgRx Component Store vs. Akita
&lt;/h2&gt;

&lt;p&gt;Let's shed some light on &lt;strong&gt;MiniRx Feature Store&lt;/strong&gt; by sending it to the fighting ring together with two other popular state management libraries: &lt;strong&gt;@ngrx/component-store&lt;/strong&gt; and &lt;strong&gt;@datorama/akita&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The competitors
&lt;/h2&gt;
&lt;h4&gt;
  
  
  NgRx Component Store (13.0.1)
&lt;/h4&gt;

&lt;p&gt;Component Store is a library that helps to manage local/component state. It can be used as an alternative to the "Service with a Subject" approach. &lt;br&gt;
It is build on top of RxJS/ReplaySubject (see &lt;a href="https://github.com/ngrx/platform/blob/13.0.1/modules/component-store/src/component-store.ts#L52" rel="noopener noreferrer"&gt;here&lt;/a&gt;). Services which extend &lt;code&gt;ComponentStore&lt;/code&gt; expose state as RxJS Observables (using the &lt;code&gt;select&lt;/code&gt; method). With the methods &lt;code&gt;setState&lt;/code&gt; and &lt;code&gt;patchState&lt;/code&gt; the state can be updated.&lt;/p&gt;

&lt;p&gt;Docs: &lt;a href="https://ngrx.io/guide/component-store" rel="noopener noreferrer"&gt;https://ngrx.io/guide/component-store&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Akita (6.2.4)
&lt;/h4&gt;

&lt;p&gt;Akita describes itself as a "state management pattern": &lt;br&gt;
It offers a set of specialized classes like &lt;code&gt;Store&lt;/code&gt;, &lt;code&gt;Query&lt;/code&gt;, &lt;code&gt;EntityStore&lt;/code&gt; and more. &lt;br&gt;
Akita &lt;code&gt;Store&lt;/code&gt; is build on top of RxJS/BehaviorSubject (see &lt;a href="https://github.com/datorama/akita/blob/v6.2.0/libs/akita/src/lib/store.ts#L49" rel="noopener noreferrer"&gt;here&lt;/a&gt;). &lt;br&gt;
By using the Akita classes we can build a reactive state service which exposes state as RxJS Observables (using &lt;code&gt;select&lt;/code&gt; on a &lt;code&gt;Query&lt;/code&gt; instance). The &lt;code&gt;update&lt;/code&gt; method of &lt;code&gt;Store&lt;/code&gt; is used to update the state.&lt;/p&gt;

&lt;p&gt;Docs: &lt;a href="https://datorama.github.io/akita/" rel="noopener noreferrer"&gt;https://datorama.github.io/akita/&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  MiniRx Feature Store (3.0.0)
&lt;/h4&gt;

&lt;p&gt;MiniRx itself is a "hybrid" Store. It uses Redux and RxJS/BehaviorSubject (see &lt;a href="https://github.com/spierala/mini-rx-store/blob/3.0.0/projects/mini-rx-store/src/lib/store-core.ts#L30" rel="noopener noreferrer"&gt;here&lt;/a&gt;) under the hood and exposes the powerful Redux &lt;code&gt;Store&lt;/code&gt; API (which is very similar to &lt;a href="https://ngrx.io/guide/store" rel="noopener noreferrer"&gt;@ngrx/store&lt;/a&gt; and &lt;a href="https://ngrx.io/guide/effects" rel="noopener noreferrer"&gt;@ngrx/effects&lt;/a&gt;). &lt;br&gt;
At the same time MiniRx allows you to bypass the infamous Redux boilerplate with the &lt;code&gt;FeatureStore&lt;/code&gt; API. &lt;br&gt;
You can create a reactive state service by extending &lt;code&gt;FeatureStore&lt;/code&gt;. &lt;br&gt;
RxJS Observables (returned by the &lt;code&gt;select&lt;/code&gt; method) inform about state changes and the state can be changed by calling &lt;code&gt;setState&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Docs: &lt;a href="https://mini-rx.io/docs/fs-quick-start" rel="noopener noreferrer"&gt;https://mini-rx.io/docs/fs-quick-start&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mhhh..., this sounds all very similar, but where are the differences then? It's time to prepare the fighting ring! :)&lt;/p&gt;
&lt;h2&gt;
  
  
  FIGHT!
&lt;/h2&gt;

&lt;p&gt;10 rounds to go! &lt;/p&gt;
&lt;h3&gt;
  
  
  1. Basic Setup
&lt;/h3&gt;

&lt;p&gt;What does the basic setup of a &lt;strong&gt;reactive state service&lt;/strong&gt; look like?&lt;/p&gt;

&lt;p&gt;All setups share the same ingredients: A state interface and initial state. &lt;/p&gt;

&lt;p&gt;FYI: The state interface must be object-like: you can not state-manage just a plain &lt;code&gt;number&lt;/code&gt; or &lt;code&gt;string&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CounterState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;count&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CounterState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;The state service extends &lt;code&gt;FeatureStore&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterStateService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FeatureStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CounterState&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;count&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="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;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;increment&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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="nf"&gt;decrement&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MiniRx Feature Store has to provide the initial state and a &lt;em&gt;feature key&lt;/em&gt;: "counter". &lt;br&gt;
The key is used to register the "counter" state in the global state object.&lt;/p&gt;
&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;With Component Store we extend &lt;code&gt;ComponentStore&lt;/code&gt; and provide an initial state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterStateService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ComponentStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CounterState&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;count&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="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;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;increment&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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="nf"&gt;decrement&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Component Store setup looks very similar to Feature Store, however the feature key is not needed because every &lt;code&gt;ComponentStore&lt;/code&gt; instance lives independently.&lt;br&gt;
FYI: The Component Store initial state parameter is optional (see docs &lt;a href="https://ngrx.io/guide/component-store/initialization#lazy-initialization" rel="noopener noreferrer"&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;With Akita, we create two services: One extends &lt;code&gt;Store&lt;/code&gt; and the other one extends &lt;code&gt;Query&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;StoreConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterStateService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Store&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CounterState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;increment&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="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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="nf"&gt;decrement&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="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterQuery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CounterState&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;count&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="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;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CounterStateService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&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;The Akita setup is the most boilerplaty. Extending &lt;code&gt;Store&lt;/code&gt; is similar to the other setups. A feature key is provided via the &lt;code&gt;@StoreConfig&lt;/code&gt; decorator.&lt;br&gt;
To access the state you have to extend &lt;code&gt;Query&lt;/code&gt; and provide the &lt;code&gt;Store&lt;/code&gt; instance.&lt;br&gt;
Also, the components have to talk to both the &lt;code&gt;Query&lt;/code&gt; and the &lt;code&gt;Store&lt;/code&gt; instance in order to read and write state.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Bundle Sizes
&lt;/h3&gt;

&lt;p&gt;Regarding the basic setup..., let's look at the corresponding bundle sizes (using &lt;a href="https://www.npmjs.com/package/source-map-explorer" rel="noopener noreferrer"&gt;source-map-explorer&lt;/a&gt;). &lt;/p&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;combined: 152.39 KB&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;combined: 152.25 KB&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;combined: 151.61 KB&lt;/p&gt;

&lt;p&gt;Akita is the most lightweight, and MiniRx is almost 1 KB bigger. &lt;br&gt;
But keep in mind that MiniRx Feature Store uses Redux under the hood &lt;br&gt;
and the Redux API is always available. Using the MiniRx Redux API will not add much to the total bundle size.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1. Bundle Sizes when adding Redux
&lt;/h3&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store + Store API (Store + Effects) using &lt;a href="https://mini-rx.io/docs/angular#register-effects" rel="noopener noreferrer"&gt;Angular Integration (mini-rx-store-ng)&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;combined: 156.9 KB&lt;/p&gt;

&lt;h4&gt;
  
  
  NgRx Component Store + NgRx Store
&lt;/h4&gt;

&lt;p&gt;combined: 164.17 KB&lt;/p&gt;

&lt;h4&gt;
  
  
  NgRx Component Store + NgRx Store + NgRx Effects
&lt;/h4&gt;

&lt;p&gt;combined: 171.45 KB&lt;/p&gt;

&lt;p&gt;You can review the different setups in this repo and run source-map-explorer yourself: &lt;a href="https://github.com/spierala/mini-rx-comparison" rel="noopener noreferrer"&gt;https://github.com/spierala/mini-rx-comparison&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Local or global state
&lt;/h3&gt;

&lt;p&gt;How do the different store solutions relate to local (component state) and global state? What is the store lifespan?&lt;/p&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;MiniRx at its heart is a Redux Store with one global state object ("Single source of truth"). Also, MiniRx Feature Stores register a "slice" of state into the global state object.&lt;br&gt;
The focus of MiniRx is clearly global state which has the lifespan of the application.&lt;/p&gt;

&lt;p&gt;But Feature Stores are destroyable... Their state can be removed from the global state object. Therefore, Feature Stores can be used for "Local Component State", which has the lifespan of a component. &lt;/p&gt;

&lt;p&gt;See an example in the &lt;a href="https://angular-demo.mini-rx.io/#/counter" rel="noopener noreferrer"&gt;MiniRx Angular demo&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;Component Stores live independently and are not related to something like a global state (e.g. when using @ngrx/store). &lt;br&gt;
The lifespan of a Component Store can be bound to a component ("Local Component State"), but it can also take the lifespan of the application.&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;The Akita Stores live independently next to each other. There is no real global state. You can use Akita Stores (which are destroyable too) for "Local Component State" following &lt;a href="https://datorama.github.io/akita/docs/angular/local-state" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; from the Akita docs.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Redux DevTools
&lt;/h3&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;MiniRx can use Redux DevTools with the built-in &lt;a href="https://mini-rx.io/docs/ext-redux-dev-tools" rel="noopener noreferrer"&gt;Redux DevTools Extension&lt;/a&gt;. &lt;br&gt;
Every Feature Store state becomes part of the global state object, and it can be inspected with the Redux DevTools.&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;There is no official solution for Redux DevTools with Component Store.&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;Akita has a &lt;a href="https://datorama.github.io/akita/docs/enhancers/devtools" rel="noopener noreferrer"&gt;PlugIn for Redux DevTools support&lt;/a&gt;. &lt;br&gt;
FYI: The separate Store states are merged into one big state object to make all state inspectable with the Redux DevTools. See the Akita DevTools source &lt;a href="https://github.com/datorama/akita/blob/master/libs/akita/src/lib/devtools.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Cross-state selection
&lt;/h3&gt;

&lt;p&gt;How can we select state from other store instances and pull that state into our current store (state service)?&lt;/p&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;Every Feature Store state integrates into the global state object. Therefore, the corresponding feature states can be selected at anytime from the Redux &lt;code&gt;Store&lt;/code&gt;(!) instance using &lt;code&gt;store.select&lt;/code&gt;.&lt;br&gt;
Alternatively you can use RxJS combination operators like &lt;code&gt;combineLatest&lt;/code&gt; or &lt;code&gt;withLatestFrom&lt;/code&gt; to combine state from other Feature Stores with state Observables of your current Feature Store.&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;The Component Store &lt;code&gt;select&lt;/code&gt; method also accepts a bunch of Observables to depend on (see docs &lt;a href="https://ngrx.io/guide/component-store/read#combining-selectors" rel="noopener noreferrer"&gt;here&lt;/a&gt;). &lt;br&gt;
Of course these Observables can come from other services. Like this it is straight-forward to depend on (observable) state of other &lt;code&gt;ComponentStore&lt;/code&gt; instances.&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;Akita has &lt;code&gt;combineQueries&lt;/code&gt; to combine state from different &lt;code&gt;Query&lt;/code&gt; instances. &lt;code&gt;combineQueries&lt;/code&gt; is basically RxJS &lt;code&gt;combineLatest&lt;/code&gt;. &lt;br&gt;
See the Akita combineQueries source &lt;a href="https://github.com/datorama/akita/blob/master/libs/akita/src/lib/combineQueries.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6asoiza0ckl0o62s35wc.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6asoiza0ckl0o62s35wc.jpeg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Memoized Selectors
&lt;/h3&gt;

&lt;p&gt;Memoized selectors can help to improve performance by reducing the number of computations of selected state. &lt;br&gt;
The selectors API (&lt;code&gt;createSelector&lt;/code&gt;) is also great for Composition: Build selectors by combining existing selectors.&lt;/p&gt;

&lt;p&gt;Examples for memoized selectors: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ngrx.io/guide/store/selectors" rel="noopener noreferrer"&gt;NgRx Store selectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/reduxjs/reselect" rel="noopener noreferrer"&gt;Redux Reselect&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;MiniRx comes with memoized selectors out-of-the-box. &lt;br&gt;
You can use the same &lt;code&gt;createFeatureSelector&lt;/code&gt; and &lt;code&gt;createSelector&lt;/code&gt; functions for the Redux &lt;code&gt;Store&lt;/code&gt; API and for the &lt;code&gt;FeatureStore&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;Read more in the &lt;a href="https://mini-rx.io/docs/select-feature-state#memoized-selectors" rel="noopener noreferrer"&gt;Feature Store memoized selectors documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Example code of memoized selectors in the MiniRx Angular Demo: &lt;a href="https://github.com/spierala/mini-rx-angular-demo/blob/main/src/app/modules/todo/state/todos-state.service.ts#L29" rel="noopener noreferrer"&gt;Todos State Service&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;There is no official solution for Component Store. &lt;br&gt;
You could add @ngrx/store to use the memoized selectors, but it would probably be overkill to add the NgRx Redux Store just for that reason. Redux Reselect could be a better alternative.&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;No memoized selectors. You could most probably add Redux Reselect.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Effects
&lt;/h3&gt;

&lt;p&gt;Effects are used to trigger side effects like API calls. &lt;br&gt;
We can also handle race-conditions more easily within an Effect by using RxJS flattening operators (&lt;code&gt;switchMap&lt;/code&gt;, &lt;code&gt;mergeMap&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;MiniRx Feature Store has Effects (&lt;a href="https://mini-rx.io/docs/effects-for-feature-store" rel="noopener noreferrer"&gt;https://mini-rx.io/docs/effects-for-feature-store&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;FYI: Feature Store Effects have their equivalent in the Redux API of MiniRx: &lt;a href="https://mini-rx.io/docs/effects" rel="noopener noreferrer"&gt;https://mini-rx.io/docs/effects&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;Yes, there are Effects: &lt;a href="https://ngrx.io/guide/component-store/effect" rel="noopener noreferrer"&gt;https://ngrx.io/guide/component-store/effect&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;Yes, there are Effects: &lt;a href="https://datorama.github.io/akita/docs/angular/effects" rel="noopener noreferrer"&gt;https://datorama.github.io/akita/docs/angular/effects&lt;/a&gt;. &lt;br&gt;
Effects come with a separate package (@datorama/akita-ng-effects).&lt;br&gt;
The Effects API is not tied to a &lt;code&gt;Store&lt;/code&gt; instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Undo
&lt;/h3&gt;

&lt;p&gt;How can we undo state changes?&lt;/p&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;MiniRx has the &lt;a href="https://mini-rx.io/docs/ext-undo-extension" rel="noopener noreferrer"&gt;UndoExtension&lt;/a&gt; to support Undo of state changes. &lt;br&gt;
This is especially helpful if you want to undo optimistic updates (e.g. when an API call fails). Both the &lt;code&gt;FeatureStore&lt;/code&gt; and the Redux &lt;code&gt;Store&lt;/code&gt; API can undo specific state changes.&lt;br&gt;
Feature Store exposes the &lt;code&gt;undo&lt;/code&gt; method. &lt;/p&gt;

&lt;p&gt;Read more in the MiniRx docs: &lt;a href="https://mini-rx.io/docs/update-feature-state#undo-setstate-actions-with-undo" rel="noopener noreferrer"&gt;Undo a setState Action&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;No support for undo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;Akita has a State History PlugIn to undo state changes (&lt;a href="https://datorama.github.io/akita/docs/plugins/state-history/" rel="noopener noreferrer"&gt;https://datorama.github.io/akita/docs/plugins/state-history/&lt;/a&gt;). &lt;br&gt;
The API is much bigger than the one of Feature Store. But it seems to be difficult to undo a very specific state change (which is important when undoing optimistic updates).&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Immutable State
&lt;/h3&gt;

&lt;p&gt;Immutability is key when using state management: We only want to allow explicit state changes using the corresponding API (e.g. by using &lt;code&gt;setState&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt; or by dispatching an Action in Redux). &lt;br&gt;
Mutating state however, might lead to unexpected behavior and bugs.&lt;br&gt;
Immutable state helps to avoid such accidental state changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;MiniRx offers the &lt;a href="https://mini-rx.io/docs/ext-immutable" rel="noopener noreferrer"&gt;Immutable State Extension&lt;/a&gt; to enforce immutable data. &lt;br&gt;
When the &lt;code&gt;ImmutableStateExtension&lt;/code&gt; is added to the MiniRx Store both the Redux &lt;code&gt;Store&lt;/code&gt; API and the &lt;code&gt;FeatureStore&lt;/code&gt; API will use immutable data.&lt;br&gt;
The Immutable State Extension "deepfreezes" the global state when state is updated. Mutating state will throw an exception.&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;There is nothing in Component Store which can enforce immutability.&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;Akita "deepfreezes" the state object when state is updated (only in DEV mode). See the corresponding source code here: &lt;a href="https://github.com/datorama/akita/blob/v6.2.0/libs/akita/src/lib/store.ts#L181" rel="noopener noreferrer"&gt;https://github.com/datorama/akita/blob/v6.2.0/libs/akita/src/lib/store.ts#L181&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Framework-agnostic
&lt;/h3&gt;

&lt;h4&gt;
  
  
  MiniRx Feature Store
&lt;/h4&gt;

&lt;p&gt;MiniRx is framework-agnostic. You can use MiniRx with any framework or even without framework.&lt;/p&gt;

&lt;p&gt;See here the MiniRx Svelte Demo: &lt;a href="https://github.com/spierala/mini-rx-svelte-demo" rel="noopener noreferrer"&gt;https://github.com/spierala/mini-rx-svelte-demo&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Store
&lt;/h4&gt;

&lt;p&gt;Component Store is tied to Angular. Angular is a peer dependency in the &lt;a href="https://github.com/ngrx/platform/blob/13.0.1/modules/component-store/package.json#L25" rel="noopener noreferrer"&gt;package.json&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Akita
&lt;/h4&gt;

&lt;p&gt;Akita is also framework-agnostic. You can see in this article how Svelte and Akita play together: &lt;a href="https://netbasal.com/supercharge-your-svelte-state-management-with-akita-f1f9de5ef43d" rel="noopener noreferrer"&gt;Supercharge Your Svelte State Management with Akita&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg9baesmy5dexk6jh39m.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg9baesmy5dexk6jh39m.jpeg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, you made it! I hope that you had fun to watch this fight!&lt;/p&gt;

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

&lt;p&gt;All competitors showed their skills, none of them went to the ground!&lt;/p&gt;

&lt;p&gt;Who was your favorite?&lt;/p&gt;

&lt;p&gt;Give it a star on GitHub: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;MiniRx on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/ngrx/platform" rel="noopener noreferrer"&gt;NgRx on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/datorama/akita" rel="noopener noreferrer"&gt;Akita on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What did we not cover?
&lt;/h3&gt;

&lt;p&gt;For completeness, I want to list a few things that were out of scope for this fight: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Akita: EntityStore, Transactions, Akita Immer, Persist State, CLI&lt;/li&gt;
&lt;li&gt;Component Store: &lt;code&gt;updater&lt;/code&gt; method, &lt;code&gt;tapResponse&lt;/code&gt; operator&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  @rx-angular/state
&lt;/h4&gt;

&lt;p&gt;Another cool lib which goes into the same direction as NgRx Component Store:&lt;br&gt;
&lt;a href="https://github.com/rx-angular/rx-angular/blob/master/libs/state/README.md" rel="noopener noreferrer"&gt;https://github.com/rx-angular/rx-angular/blob/master/libs/state/README.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe see you in the next fight! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Special thanks for reviewing this blog post:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/diePartments" rel="noopener noreferrer"&gt;Michael Rutzer - diePartments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Articles which inspired me:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;There was once a legendary fight in 2018, organized by &lt;a href="https://twitter.com/orjandesmet" rel="noopener noreferrer"&gt;Orjan de Smet&lt;/a&gt;: &lt;a href="https://ordina-jworks.github.io/angular/2018/10/08/angular-state-management-comparison.html?utm_source=dormosheio&amp;amp;utm_campaign=dormosheio" rel="noopener noreferrer"&gt;NGRX VS. NGXS VS. AKITA VS. RXJS: FIGHT!&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Photos:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Photo by &lt;a href="https://unsplash.com/@attentieattentie?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Attentie Attentie&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/boxing-ring?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Photo by &lt;a href="https://unsplash.com/@single_lens_reflex?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Dan Burton&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/boxer-break?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Photo by &lt;a href="https://unsplash.com/@matthewapayne?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Matthew Payne&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/boxing-gloves?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>redux</category>
      <category>webdev</category>
      <category>rxjs</category>
    </item>
    <item>
      <title>Introducing MiniRx - Scalable reactive state management</title>
      <dc:creator>Florian Spier</dc:creator>
      <pubDate>Fri, 26 Feb 2021 13:07:13 +0000</pubDate>
      <link>https://forem.com/spierala/introducing-minirx-scalable-reactive-state-management-d7</link>
      <guid>https://forem.com/spierala/introducing-minirx-scalable-reactive-state-management-d7</guid>
      <description>&lt;h2&gt;
  
  
  Hello from MiniRx Store
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MiniRx Store&lt;/strong&gt; is the new kid on the reactive state management block. MiniRx will help you to manage state at large scale (with &lt;strong&gt;Redux&lt;/strong&gt;), but it also offers a simple form of state management: &lt;strong&gt;Feature Stores&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's get a quick overview:&lt;/p&gt;

&lt;h3&gt;
  
  
  Global
&lt;/h3&gt;

&lt;p&gt;MiniRx Store is a &lt;strong&gt;global&lt;/strong&gt;, application-wide solution to manage state in &lt;strong&gt;JavaScript&lt;/strong&gt; and &lt;strong&gt;TypeScript&lt;/strong&gt; applications. &lt;/p&gt;

&lt;h3&gt;
  
  
  Reactive
&lt;/h3&gt;

&lt;p&gt;MiniRx is powered by &lt;strong&gt;&lt;a href="https://github.com/ReactiveX/rxjs" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt;&lt;/strong&gt; and exposes &lt;strong&gt;state as RxJS Observables&lt;/strong&gt;. The Observables emit when their selected state changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalable
&lt;/h3&gt;

&lt;p&gt;MiniRx is a full-blown &lt;strong&gt;Redux&lt;/strong&gt; Store: It includes actions, reducers, meta reducers, memoized selectors and redux dev tools support.&lt;br&gt;
However, with MiniRx &lt;strong&gt;Feature Stores&lt;/strong&gt; we can &lt;strong&gt;bypass Redux boilerplate&lt;/strong&gt;: update state straight away with &lt;code&gt;setState&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;MiniRx scales nicely with your state management requirements: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make hard things simple with the &lt;strong&gt;Redux&lt;/strong&gt; API&lt;/li&gt;
&lt;li&gt;Keep simple things simple with the &lt;strong&gt;Feature Store&lt;/strong&gt; API&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Quick Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🤓 Learn more about MiniRx on the &lt;a href="https://spierala.github.io/mini-rx-store/" rel="noopener noreferrer"&gt;Docs site&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;MiniRx on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🚀 See it in action on &lt;a href="https://stackblitz.com/edit/mini-rx-store-demo" rel="noopener noreferrer"&gt;StackBlitz&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The MiniRx DNA
&lt;/h2&gt;
&lt;h3&gt;
  
  
  NgRx
&lt;/h3&gt;

&lt;p&gt;MiniRx is inspired by &lt;a href="https://ngrx.io/" rel="noopener noreferrer"&gt;NgRx&lt;/a&gt;, which is a well known reactive Redux Store in the &lt;a href="https://angular.io/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt; world. MiniRx and NgRx look similar at first sight, but there are also important differences.&lt;/p&gt;
&lt;h3&gt;
  
  
  What do NgRx and MiniRx have in common?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Their names sound similar: try to speak them out loudly ;)&lt;/li&gt;
&lt;li&gt;Powered by &lt;strong&gt;RxJS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Both implement the &lt;strong&gt;Redux Pattern&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;State and actions are exposed as &lt;strong&gt;RxJS Observable&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What are the main differences?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MiniRx has no Angular dependency and is &lt;strong&gt;framework agnostic&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;MiniRx has &lt;strong&gt;Feature Stores&lt;/strong&gt; to manage feature state &lt;strong&gt;without Redux boilerplate&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;MiniRx is more &lt;strong&gt;lightweight&lt;/strong&gt; and admittedly does not cover every crazy use case of state management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it is these differences which explain the name "MiniRx".&lt;/p&gt;
&lt;h2&gt;
  
  
  Why MiniRx
&lt;/h2&gt;

&lt;p&gt;NgRx and the Redux pattern are well-suited for managing state at a large scale. But almost every application contains also features which require only a &lt;strong&gt;simple form of state management&lt;/strong&gt;. Then the Redux pattern with its actions and reducers quickly feels like &lt;strong&gt;overkill&lt;/strong&gt;. It would be great to have a state management solution which looks and feels a lot like NgRx, but it has to support simple state management too: &lt;strong&gt;Scalable state management&lt;/strong&gt;. It was time to create &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;MiniRx Store&lt;/a&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjybr0c4zsanlimdaltn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjybr0c4zsanlimdaltn.png" alt="Alt Text" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Bypass Redux boilerplate with Feature Stores
&lt;/h3&gt;

&lt;p&gt;MiniRx uses the Redux pattern to make state management explicit and predictable. The Redux pattern is very powerful, but it comes with some boilerplate code (mostly actions, reducers, dispatching actions). MiniRx allows us to bypass the Redux boilerplate for simple feature states: With &lt;strong&gt;Feature Stores&lt;/strong&gt; we can manage feature state directly &lt;strong&gt;without actions and reducer&lt;/strong&gt; (simply use &lt;code&gt;setState&lt;/code&gt; to update the feature state).&lt;/p&gt;
&lt;h3&gt;
  
  
  State Management which scales
&lt;/h3&gt;

&lt;p&gt;For simple features we can use Feature Stores. And Feature Stores can be quite powerful actually: You can use &lt;strong&gt;memoized selectors&lt;/strong&gt; (if you want to), you can create &lt;strong&gt;effects&lt;/strong&gt; for API calls (if you want to). MiniRx scales nicely with your needs.&lt;br&gt;
And you can always fall back to the Redux API in case that you have to manage huge and complex state.&lt;/p&gt;
&lt;h3&gt;
  
  
  Framework agnostic
&lt;/h3&gt;

&lt;p&gt;NgRx is a great reactive Store, but it currently only works in Angular. There are also other frontend frameworks like &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt; which embrace reactivity. It would be cool to do NgRx-style state management in Svelte! &lt;br&gt;
With MiniRx you can use whatever framework you want: you can build a &lt;strong&gt;framework-agnostic&lt;/strong&gt; state management layer for Angular today and move it to Svelte (or any other frontend framework) tomorrow.&lt;/p&gt;
&lt;h2&gt;
  
  
  MiniRx Key Concepts
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssx0l49baspywefsp141.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssx0l49baspywefsp141.PNG" alt="Alt Text" width="783" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The store is a single object which holds the global application state. It is the &lt;strong&gt;"single source of truth"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;State has a &lt;strong&gt;flat hierarchy&lt;/strong&gt; and is divided into &lt;strong&gt;"feature states"&lt;/strong&gt; (also called "slices" in Redux world)&lt;/li&gt;
&lt;li&gt;For each "feature state" we can decide to use the &lt;strong&gt;Redux API&lt;/strong&gt; with actions and a reducer or the &lt;strong&gt;Feature Store API&lt;/strong&gt; with &lt;code&gt;setState&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;State is exposed as &lt;strong&gt;RxJS Observable&lt;/strong&gt; (The Store exposes the &lt;strong&gt;global state&lt;/strong&gt;, while a Feature Store exposes a specific &lt;strong&gt;feature state&lt;/strong&gt;). &lt;/li&gt;
&lt;li&gt;State is &lt;strong&gt;read-only&lt;/strong&gt; (immutable) and can only be changed by dispatching actions (Redux API) or by using &lt;code&gt;setState&lt;/code&gt; (Feature Store API)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That was a long introduction! Let's dive into some code to see MiniRx in action...&lt;/p&gt;
&lt;h2&gt;
  
  
  Basic Tutorial
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Store (Redux API)
&lt;/h3&gt;

&lt;p&gt;MiniRx supports the classic Redux API with registering &lt;strong&gt;reducers&lt;/strong&gt; and dispatching &lt;strong&gt;actions&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;Observable state&lt;/strong&gt; can be selected with &lt;strong&gt;memoized selectors&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;createFeatureSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;createSelector&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mini-rx-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 1.) State interface&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CounterState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;count&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;// 2.) Initial state&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterInitialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CounterState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;count&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="c1"&gt;// 3.) Reducer&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;counterReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CounterState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;counterInitialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Action&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;CounterState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inc&lt;/span&gt;&lt;span class="dl"&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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="nl"&gt;default&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;state&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;// 4.) Get hold of the store instance and register root reducers&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;counterReducer&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// 5.) Create memoized selectors&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getCounterFeatureState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createFeatureSelector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CounterState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;getCounterFeatureState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 6.) Select state as RxJS Observable&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;count$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// 7.) Dispatch an action&lt;/span&gt;
&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// OUTPUT: count: 1&lt;/span&gt;
&lt;span class="c1"&gt;// OUTPUT: count: 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Feature Store API
&lt;/h3&gt;

&lt;p&gt;Feature Stores allow us to manage feature state &lt;strong&gt;without actions and reducers&lt;/strong&gt;. &lt;br&gt;
The API of a Feature Store is optimised to select and update a feature state directly with a &lt;strong&gt;minimum of boilerplate&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FeatureStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mini-rx-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 1.) State interface&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CounterState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;count&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;// 2.) Initial state&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterInitialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CounterState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterFeatureStore&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FeatureStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CounterState&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;// Select state as RxJS Observable&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="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;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counterFs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;counterInitialState&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 state with `setState`&lt;/span&gt;
  &lt;span class="nf"&gt;inc&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the "counterFs" feature store like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CounterFeatureStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./counter-feature-store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterFs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CounterFeatureStore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;counterFs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;counterFs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// OUTPUT: count: 11&lt;/span&gt;
&lt;span class="c1"&gt;// OUTPUT: count: 12&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The state of a Feature Store becomes part of the global state
&lt;/h3&gt;

&lt;p&gt;Every new Feature Store will show up in the global state with the corresponding feature key (e.g. "counterFs"):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//OUTPUT: {"counter":{"count":2},"counterFs":{"count":12}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;🚀 See MiniRx Store in action on &lt;a href="https://stackblitz.com/edit/mini-rx-store-demo" rel="noopener noreferrer"&gt;StackBlitz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Demo uses both the Redux API and the Feature Stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Todos: Feature Store&lt;/li&gt;
&lt;li&gt;Products and Cart: Redux&lt;/li&gt;
&lt;li&gt;User: Feature Store&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  More MiniRx Examples:
&lt;/h3&gt;

&lt;p&gt;These popular Angular demo applications show the power of MiniRx:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/spierala/angular-tetris-mini-rx" rel="noopener noreferrer"&gt;Angular Tetris with MiniRx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/spierala/jira-clone-angular" rel="noopener noreferrer"&gt;Angular Jira Clone using MiniRx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Coming soon: Angular Spotify using MiniRx&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;p&gt;Check out the &lt;a href="https://spierala.github.io/mini-rx-store/" rel="noopener noreferrer"&gt;docs&lt;/a&gt; for the full MiniRx API. &lt;/p&gt;

&lt;h3&gt;
  
  
  Show Your Support
&lt;/h3&gt;

&lt;p&gt;If you like MiniRx: Give it a ⭐ on &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;These projects, articles and courses helped and inspired me to create MiniRx:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://ngrx.io/" rel="noopener noreferrer"&gt;NgRx&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/datorama/akita" rel="noopener noreferrer"&gt;Akita&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/DanWahlin/Observable-Store" rel="noopener noreferrer"&gt;Observable Store&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/jurebajt/rxjs-observable-store" rel="noopener noreferrer"&gt;RxJS Observable Store&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/markostanimirovic/juliette" rel="noopener noreferrer"&gt;Juliette Store&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dev.to/avatsaev/simple-state-management-in-angular-with-only-services-and-rxjs-41p8"&gt;Basic State Management with an Observable Service&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.youtube.com/watch?v=hG7v7quMMwM" rel="noopener noreferrer"&gt;Redux From Scratch With Angular and RxJS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://medium.com/angular-in-depth/how-i-wrote-ngrx-store-in-63-lines-of-code-dfe925fe979b" rel="noopener noreferrer"&gt;How I wrote NgRx Store in 63 lines of code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://ordina-jworks.github.io/angular/2018/10/08/angular-state-management-comparison.html?utm_source=dormosheio&amp;amp;utm_campaign=dormosheio" rel="noopener noreferrer"&gt;NGRX VS. NGXS VS. AKITA VS. RXJS: FIGHT!&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://app.pluralsight.com/library/courses/angular-ngrx-getting-started/table-of-contents" rel="noopener noreferrer"&gt;Pluralsight: Angular NgRx: Getting Started&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://app.pluralsight.com/library/courses/rxjs-angular-reactive-development/table-of-contents" rel="noopener noreferrer"&gt;Pluralsight: RxJS in Angular: Reactive Development&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://app.pluralsight.com/library/courses/rxjs-getting-started/table-of-contents" rel="noopener noreferrer"&gt;Pluralsight: RxJS: Getting Started&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>rxjs</category>
      <category>redux</category>
    </item>
    <item>
      <title>Simple yet powerful state management in Angular with RxJS</title>
      <dc:creator>Florian Spier</dc:creator>
      <pubDate>Fri, 04 Sep 2020 11:22:41 +0000</pubDate>
      <link>https://forem.com/angular/simple-yet-powerful-state-management-in-angular-with-rxjs-4f8g</link>
      <guid>https://forem.com/angular/simple-yet-powerful-state-management-in-angular-with-rxjs-4f8g</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR&lt;/em&gt; Let’s create our own state management Class with just RxJS/BehaviorSubject (inspired by some well known state management libs). &lt;/p&gt;

&lt;h2&gt;
  
  
  Manage state with RxJS BehaviorSubject
&lt;/h2&gt;

&lt;p&gt;There are several great state management libraries out there to manage state in Angular: E.g. NgRx, Akita or NgXs. They all have one thing in common: They are based on RxJS Observables and the state is stored in a special kind of Observable: The BehaviorSubject. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why RxJS Observables?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Observables are first class citizens in Angular. Many of the core functionalities of Angular have a RxJS implementation (e.g. HttpClient, Forms, Router and more). Managing state with Observables integrates nicely with the rest of the Angular ecosystem.&lt;/li&gt;
&lt;li&gt;With Observables it is easy to inform Components about state changes. Components can subscribe to Observables which hold the state. These "State" Observables emit a new value when state changes. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is special about BehaviorSubject?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A BehaviorSubject emits its last emitted value to new/late subscribers &lt;/li&gt;
&lt;li&gt;It has an initial value&lt;/li&gt;
&lt;li&gt;Its current value can be accessed via the &lt;code&gt;getValue&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;A new value can be emitted using the &lt;code&gt;next&lt;/code&gt; method&lt;/li&gt;
&lt;li&gt;A BehaviorSubject is multicast: Internally it holds a list of all subscribers. All subscribers share the same Observable execution. When the BehaviorSubject emits a new value then the exact same value is pushed to all subscribers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Our own state management with BehaviorSubject
&lt;/h2&gt;

&lt;p&gt;So if all the big state management libs are using RxJS BehaviorSubject and Angular comes with RxJS out of the box... Can we create our own state management with just Angular Services and BehaviorSubject? &lt;/p&gt;

&lt;p&gt;Let's create a simple yet powerful state management Class which can be extended by Angular services.&lt;/p&gt;

&lt;h3&gt;
  
  
  The key goals are:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Be able to define a state interface and set initial state &lt;/li&gt;
&lt;li&gt;Straight forward API to update state and select state: &lt;code&gt;setState&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Selected state should be returned as an Observable. The Observable emits when selected state changes.&lt;/li&gt;
&lt;li&gt;Be able to use &lt;code&gt;ChangeDetectionStrategy.OnPush&lt;/code&gt; in our Components for better performance (read more on OnPush here: &lt;a href="https://netbasal.com/a-comprehensive-guide-to-angular-onpush-change-detection-strategy-5bac493074a4" rel="noopener noreferrer"&gt;"A Comprehensive Guide to Angular onPush Change Detection Strategy"&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The solution:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BehaviorSubject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;distinctUntilChanged&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs/operators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StateService&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BehaviorSubject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;state&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="k"&gt;return&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;state$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;();&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="na"&gt;initialState&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="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;state$&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;BehaviorSubject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;mapFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;state&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;K&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state$&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="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="na"&gt;state&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="nf"&gt;mapFn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="nf"&gt;distinctUntilChanged&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;state$&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="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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s have a closer look at the code above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The StateService expects a generic type &lt;code&gt;T&lt;/code&gt; representing the state interface. This type is passed when extending the StateService. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get state()&lt;/code&gt; returns the current state snapshot&lt;/li&gt;
&lt;li&gt;The constructor takes an initial state and initializes the BehaviorSubject.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;select&lt;/code&gt; takes a callback function. That function is called when &lt;code&gt;state$&lt;/code&gt; emits a new state. Within RxJS &lt;code&gt;map&lt;/code&gt; the callback function will return a piece of state. &lt;code&gt;distinctUntilChanged&lt;/code&gt; will skip emissions until the selected piece of state holds a new value/object reference.
&lt;code&gt;this.state$.asObservable()&lt;/code&gt; makes sure that the &lt;code&gt;select&lt;/code&gt; method returns an Observable (and not an &lt;code&gt;AnonymousSubject&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setState&lt;/code&gt; accepts a Partial Type. This allows us to be lazy and pass only some properties of a bigger state interface. Inside the &lt;code&gt;state$.next&lt;/code&gt; method the partial state is merged with the full state object. Finally the BehaviorSubject &lt;code&gt;this.state$&lt;/code&gt; will emit a brand new state object.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;Angular Services which have to manage some state can simply extend the StateService to select and update state.&lt;/p&gt;

&lt;p&gt;There is only one thing in the world to manage: TODOS! :) Let’s create a TodosStateService.&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TodoState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;selectedTodoId&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TodoState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;selectedTodoId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodosStateService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;StateService&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TodoState&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;todos&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;selectedTodo&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="o"&gt;&amp;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;select&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&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="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;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectedTodoId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Todo&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;todos&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;selectTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Todo&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;selectedTodoId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go through the TodosStateService Code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The TodosStateService extends &lt;code&gt;StateService&lt;/code&gt; and passes the state interface &lt;code&gt;TodoState&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The constructor needs to call &lt;code&gt;super()&lt;/code&gt; and pass the initial state&lt;/li&gt;
&lt;li&gt;The public Observables &lt;code&gt;todos$&lt;/code&gt; and &lt;code&gt;selectedTodo$&lt;/code&gt; expose the corresponding state data to interested consumers like components or other services&lt;/li&gt;
&lt;li&gt;The public methods &lt;code&gt;addTodo&lt;/code&gt; and &lt;code&gt;selectTodo&lt;/code&gt; expose a public API to update state.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Interaction with Components and Backend API
&lt;/h3&gt;

&lt;p&gt;Let’s see how we can integrate our TodosStateService with Angular Components and a Backend API:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Components call public methods of the TodosStateService to update state&lt;/li&gt;
&lt;li&gt;Components interested in state simply subscribe to the corresponding public Observables which are exposed by the TodosStateService.&lt;/li&gt;
&lt;li&gt;API calls are closely related to state. Quite often an API response will directly update the state. Therefore API calls are triggered by the TodosStateService. Once an API call has completed the state can be updated straight away using &lt;code&gt;setState&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;See a full blown TODOs App using the TodosStateService:&lt;br&gt;
&lt;a href="https://stackblitz.com/edit/rxjs-angular-state-manager?file=src/app/modules/todo/services/todos-state.service.ts" rel="noopener noreferrer"&gt;Stackblitz - Angular State Manager&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Immutable Data
&lt;/h3&gt;

&lt;p&gt;To benefit from &lt;code&gt;ChangeDetectionStrategy.OnPush&lt;/code&gt; in our components we have to make sure to NOT mutate the state.&lt;br&gt;
It is our responsibility to always pass a new object to the &lt;code&gt;setState&lt;/code&gt; method. If we want to update a nested property which holds an object/array, then we have to assign a new object/array as well.&lt;/p&gt;

&lt;p&gt;See the complete &lt;a href="https://stackblitz.com/edit/rxjs-angular-state-manager?file=src/app/modules/todo/services/todos-state.service.ts" rel="noopener noreferrer"&gt;TodosStateService (on Stackblitz)&lt;/a&gt; for more examples of immutable state updates. &lt;/p&gt;

&lt;p&gt;FYI&lt;br&gt;
There are libs which can help you to keep the state data immutable:&lt;br&gt;
&lt;a href="https://github.com/immerjs/immer" rel="noopener noreferrer"&gt;Immer&lt;/a&gt;&lt;br&gt;
&lt;a href="https://immutable-js.github.io/immutable-js/" rel="noopener noreferrer"&gt;ImmutableJS&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Template Driven Forms with two-way data binding
&lt;/h3&gt;

&lt;p&gt;Regarding immutable data... We have to be careful when pushing state into a Template Driven Form where the Form inputs are using &lt;code&gt;[(ngModel)]&lt;/code&gt;. When the user changes a Form input value then the state object will be mutated directly... &lt;br&gt;
But we wanted to stay immutable and change state only explicitly using &lt;code&gt;setState&lt;/code&gt;. Therefore it is a better alternative to use Reactive Forms. If it has to be Template Driven Forms then there is still a nice compromise: one-way data binding &lt;code&gt;[ngModel]&lt;/code&gt;. Another option is to (deeply) clone the form data... In that case you can still use &lt;code&gt;[(ngModel)]&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;async&lt;/code&gt; pipe for Subscriptions
&lt;/h3&gt;

&lt;p&gt;In most cases components should subscribe to the "State" Observables using the &lt;code&gt;async&lt;/code&gt; pipe in the template. The async pipe subscribes for us and will handle unsubscribing automatically when the component is destroyed. &lt;/p&gt;

&lt;p&gt;There is one more benefit of the async pipe:&lt;br&gt;
When components use the OnPush Change Detection Strategy they will update their View only in these cases automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if an &lt;code&gt;@Input&lt;/code&gt; receives a new value/object reference&lt;/li&gt;
&lt;li&gt;if a DOM event is triggered from the component or one of its children &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are situations where the component has neither a DOM event nor an @Input that changes. If that component subscribed to state changes inside the component Class, then the Angular Change Detection will not know that the View needs to be updated once the observed state emits.&lt;/p&gt;

&lt;p&gt;You might fix it by using &lt;code&gt;ChangeDetectorRef.markForCheck()&lt;/code&gt;. It tells the ChangeDetector to check for state changes anyway (in the current or next Change Detection Cycle) and update the View if necessary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;changeDetection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OnPush&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodoShellComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Todo&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;todosState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TodosStateService&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;cdr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectorRef&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;todosState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;todos&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;cdr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Fix View not updating&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;But we can also use the &lt;code&gt;async&lt;/code&gt; pipe in the template instead. It is calling &lt;code&gt;ChangeDetectorRef.markForCheck&lt;/code&gt; for us. See here in the Angular Source: &lt;a href="https://github.com/angular/angular/blob/10.1.x/packages/common/src/pipes/async_pipe.ts#L146" rel="noopener noreferrer"&gt;async_pipe&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Much shorter and prettier:&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;todo-list&lt;/span&gt; &lt;span class="na"&gt;[todos]=&lt;/span&gt;&lt;span class="s"&gt;"todos$ | async"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/todo-list&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The async pipe does a lot. Subscribe, unsubscribe, markForCheck. Let's use it where possible. &lt;/p&gt;

&lt;p&gt;See the async pipe in action in the Demo: &lt;a href="https://stackblitz.com/edit/rxjs-angular-state-manager?file=src%2Fapp%2Fmodules%2Ftodo%2Fcomponents%2Ftodo-shell%2Ftodo-shell.component.html" rel="noopener noreferrer"&gt;todo-shell.component.html&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;select&lt;/code&gt; callbacks are called often
&lt;/h3&gt;

&lt;p&gt;We should be aware of the fact that a callback passed to the &lt;code&gt;select&lt;/code&gt; method needs to be executed on every call to &lt;code&gt;setState&lt;/code&gt;.&lt;br&gt;
Therefore the select callback should not contain heavy calculations.&lt;/p&gt;
&lt;h3&gt;
  
  
  Multicasting is gone
&lt;/h3&gt;

&lt;p&gt;If there are many subscribers to an Observable which is returned by the &lt;code&gt;select&lt;/code&gt; method then we see something interesting: The Multicasting of BehaviorSubject is gone... The callback function passed to the &lt;code&gt;select&lt;/code&gt; method is called multiple times when state changes. The Observable is executed per subscriber. &lt;br&gt;
This is because we converted the BehaviorSubject to an Observable using &lt;code&gt;this.state$.asObservable()&lt;/code&gt;. Observables do not multicast.&lt;/p&gt;

&lt;p&gt;Luckily RxJS provides an (multicasting) operator to make an Observable multicast: &lt;code&gt;shareReplay&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I would suggest to use the shareReplay operator only where it's needed. Let's assume there are multiple subscribers to the &lt;code&gt;todos$&lt;/code&gt; Observable. In that case we could make it multicast like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;todos$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todos&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;shareReplay&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;refCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;bufferSize&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is important to use &lt;code&gt;refCount: true&lt;/code&gt; to avoid memory leaks. &lt;code&gt;bufferSize: 1&lt;/code&gt; will make sure that late subscribers still get the last emitted value.&lt;/p&gt;

&lt;p&gt;Read more about multicasting operators here: &lt;a href="https://itnext.io/the-magic-of-rxjs-sharing-operators-and-their-differences-3a03d699d255" rel="noopener noreferrer"&gt;The magic of RXJS sharing operators and their differences&lt;/a&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  Facade Pattern
&lt;/h3&gt;

&lt;p&gt;There is one more nice thing. The state management service promotes the &lt;a href="https://medium.com/@thomasburlesonIA/ngrx-facades-better-state-management-82a04b9a1e39" rel="noopener noreferrer"&gt;facade pattern&lt;/a&gt;: &lt;code&gt;select&lt;/code&gt; and &lt;code&gt;setState&lt;/code&gt; are protected functions. Therefore they can only be called inside the &lt;code&gt;TodosStateService&lt;/code&gt;. This helps to keep components lean and clean, since they will not be able to use the &lt;code&gt;setState&lt;/code&gt;/&lt;code&gt;select&lt;/code&gt; methods directly (e.g. on a injected TodosStateService). State implementation details stay inside the TodosStateService.&lt;br&gt;
The facade pattern makes it easy to refactor the TodosStateService to another state management solution (e.g. NgRx) - if you ever want to :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;Special thanks for reviewing this blog post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/paulfreelance" rel="noopener noreferrer"&gt;Paul Moers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/diePartments" rel="noopener noreferrer"&gt;Michael Rutzer - diePartments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/niklas_wortmann" rel="noopener noreferrer"&gt;Jan-Niklas Wortmann - RxJS Core Team Member&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Articles which inspired me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/avatsaev/simple-state-management-in-angular-with-only-services-and-rxjs-41p8"&gt;Simple state management in Angular with only Services and RxJS&lt;/a&gt; by &lt;a href="https://twitter.com/avatsaev" rel="noopener noreferrer"&gt;Aslan Vatsaev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Very similar approach: &lt;a href="https://www.bennadel.com/blog/3522-creating-a-simple-setstate-store-using-an-rxjs-behaviorsubject-in-angular-6-1-10.htm" rel="noopener noreferrer"&gt;Creating A Simple setState() Store Using An RxJS BehaviorSubject In Angular 6.1.10&lt;/a&gt; by &lt;a href="https://twitter.com/BenNadel" rel="noopener noreferrer"&gt;Ben Nadel&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MiniRx
&lt;/h2&gt;

&lt;p&gt;My experience with reactive state management made it into this very cool library: &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;MiniRx Store&lt;/a&gt;.&lt;br&gt;
You can easily refactor the StateService from this article to MiniRx Feature Store. &lt;a href="https://github.com/spierala/mini-rx-store#feature-store-api" rel="noopener noreferrer"&gt;MiniRx Feature Store&lt;/a&gt; also supports &lt;code&gt;setState&lt;/code&gt; and &lt;code&gt;select&lt;/code&gt;, but you get extra goodies like Redux DevTools support, undo, enforced immutability, effects, memoized selectors and much more.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤓 Learn more about MiniRx on the &lt;a href="https://mini-rx.io" rel="noopener noreferrer"&gt;Docs site&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/spierala/mini-rx-store" rel="noopener noreferrer"&gt;MiniRx on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🚀 &lt;a href="https://angular-demo.mini-rx.io/" rel="noopener noreferrer"&gt;Angular Demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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