<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://penguincoders.net/feed.xml" rel="self" type="application/atom+xml" /><link href="https://penguincoders.net/" rel="alternate" type="text/html" /><updated>2025-02-11T03:12:19+00:00</updated><id>https://penguincoders.net/feed.xml</id><title type="html">The Penguin Coders</title><subtitle>Exploring web development, AWS technologies, or taking a deep dive into any tech that captivates my interest.
</subtitle><author><name>Mohit Singh</name><email>mohit@penguincoders.net</email></author><entry><title type="html">Singleton Design Pattern in Java</title><link href="https://penguincoders.net/blog/singleton-design-pattern-in-java/" rel="alternate" type="text/html" title="Singleton Design Pattern in Java" /><published>2024-09-10T00:00:00+00:00</published><updated>2024-09-10T00:00:00+00:00</updated><id>https://penguincoders.net/blog/singleton-design-pattern-in-java</id><content type="html" xml:base="https://penguincoders.net/blog/singleton-design-pattern-in-java/"><![CDATA[<p>Software design patterns are there to help solve common problems which occur in software design. There are different types of design patterns which we have, each solving a different use case.</p>

<p>In this post, we will look at Singleton pattern, which is a creational pattern (deal with object creation mechanisms), that allows a single instance of the class to be present, and all references to that class point to a single instance which we create.</p>

<p>A Singleton design pattern makes sure that the class has a single instance, and provides access to that class globally.</p>

<h3 id="why-would-a-singleton-pattern-be-needed-at-all">Why would a Singleton pattern be needed at all?</h3>

<p>When we need to ensure that the class has only one instance and a global access to that class is required, we use the Singleton pattern. Some examples would be -</p>

<ol>
  <li>
    <p><strong>Creating a Database connection pool</strong> - A Singleton class can be used to manage a single access point to DB pool, and limit number of connections to database.</p>
  </li>
  <li>
    <p><strong>Logging Service</strong> - We can implement logging service as a Singleton to ensure that various parts of application, will log the messages through same class, and prevents inconsistencies in log file access.</p>
  </li>
  <li>
    <p><strong>Configuration Management</strong> - We can manage environment settings, API keys, global settings by storing them in a singleton class, and accessing them throughout the application, without the need to creating new instances whenever used.</p>
  </li>
</ol>

<h3 id="how-do-we-implement-a-singleton">How do we implement a Singleton?</h3>

<p>To implement a Singleton class, there are 2 steps to implement it -</p>

<ol>
  <li>Declare all constructors of the class as <strong>private</strong> so it cannot be instantiated by any other objects.</li>
  <li>Provide a <strong>static method</strong> which can give the reference of the class instance.</li>
</ol>

<h3 id="singleton-implementation-in-java">Singleton Implementation in JAVA</h3>

<p>We will implement a very basic Lazy initialization Singleton class which will have a private constructor, and a static method to get its instance.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Singleton</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">static</span> <span class="nc">Singleton</span> <span class="n">instance</span><span class="o">;</span>

    <span class="c1">//Private constructor</span>
    <span class="kd">private</span> <span class="nf">Singleton</span><span class="o">(){</span>
    <span class="o">}</span>

    <span class="c1">//Lazy initialization</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Singleton</span> <span class="nf">getInstance</span><span class="o">(){</span>
        <span class="c1">//If not already initialized, create a new instance, else return the existing instance</span>
        <span class="k">if</span><span class="o">(</span><span class="n">instance</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span>
            <span class="n">instance</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Singleton</span><span class="o">();</span>
        <span class="k">return</span> <span class="n">instance</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h4 id="usage">Usage</h4>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">SingletonDemo</span><span class="o">{</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">){</span>
        <span class="c1">//We can refer to the instance by calling its getInstance method.</span>
        <span class="c1">//We don't need Singleton singleton = new Singleton(), so a single copy is used globally.</span>
        <span class="nc">Singleton</span> <span class="n">singleton</span> <span class="o">=</span> <span class="nc">Singleton</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>This implementation looks fine, but it can have issues on a multi threaded environment, where this class could be called from 2 threads, and the following scenario would occur -</p>

<ol>
  <li>
    <p>Thread 1 calls the <strong>getInstance</strong> method, the Singleton is not yet created, so a new instance is created and returned. Thread 2 calls the <strong>getInstance</strong> method, the Singleton class object has been created, so already created object is returned back.</p>
  </li>
  <li>
    <p>Thread 1 and Thread 2 both call the <strong>getInstance</strong> method, both see that the class instance is not created, so 2 instances of the Singleton are created and returned, which is problematic.</p>
  </li>
</ol>

<p>To ensure that our Singleton class works correctly in a multi threaded environment, we use a concept known as <strong>Double Checked Locking(DCL)</strong>.
We synchronize the threads during creation of first Singleton object.</p>

<p>To make this happen, following changes should be made to the Singleton class.</p>

<ul>
  <li>Declare the Singleton instance as <strong>volatile</strong></li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">static</span> <span class="kd">volatile</span> <span class="nc">Singleton</span> <span class="n">instance</span>
</code></pre></div></div>

<ul>
  <li>While checking if instance is null, and creating a new instance, make it <strong>synchronized</strong>.</li>
</ul>

<p>The complete example with thread safe DCL Singleton class is given below</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">DCLSingleton</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">static</span> <span class="kd">volatile</span> <span class="nc">DCLSingleton</span> <span class="n">instance</span><span class="o">;</span>

    <span class="c1">//Private constructor</span>
    <span class="kd">private</span> <span class="nf">DCLSingleton</span><span class="o">(){</span>
    <span class="o">}</span>

    <span class="c1">//Lazy initialization</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">DCLSingleton</span> <span class="nf">getInstance</span><span class="o">(){</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">instance</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// First check (no locking)</span>
            <span class="kd">synchronized</span> <span class="o">(</span><span class="nc">Singleton</span><span class="o">.</span><span class="na">class</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// Locking</span>
                <span class="k">if</span> <span class="o">(</span><span class="n">instance</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// Second check (with locking)</span>
                    <span class="n">instance</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">DCLSingleton</span><span class="o">();</span>
                <span class="o">}</span>
            <span class="o">}</span>
        <span class="o">}</span>
        <span class="k">return</span> <span class="n">instance</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="potential-downsides-of-singleton-pattern">Potential downsides of Singleton pattern</h3>

<ol>
  <li>There could be global state issues.</li>
  <li>Unit testing can be difficult as singleton have global state, so we need to mock it correctly.</li>
  <li>Improper implementation of singleton can cause issues in a multi threaded environment.</li>
</ol>]]></content><author><name>Mohit Singh</name><email>mohit@penguincoders.net</email></author><category term="blog" /><summary type="html"><![CDATA[Software design patterns are there to help solve common problems which occur in software design. There are different types of design patterns which we have, each solving a different use case.]]></summary></entry><entry><title type="html">Creating a ToDo App with Angular, NestJS, and NgRx in a Nx Monorepo</title><link href="https://penguincoders.net/blog/todo-app-in-angular-nestjs-ngrx/" rel="alternate" type="text/html" title="Creating a ToDo App with Angular, NestJS, and NgRx in a Nx Monorepo" /><published>2024-04-02T00:00:00+00:00</published><updated>2024-04-02T00:00:00+00:00</updated><id>https://penguincoders.net/blog/todo-app-in-angular-nestjs-ngrx</id><content type="html" xml:base="https://penguincoders.net/blog/todo-app-in-angular-nestjs-ngrx/"><![CDATA[<p>In this post, we will be creating a fully functional ToDo application in a Nx monorepo, using Angular for Frontend and NestJs for Backend. The ToDo app will also provide Angular’s state management using NgRx. Our frontend app will be using Tailwind to style our components.</p>

<p><img src="/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/todo.png" alt="ToDo App" /></p>

<p>Let’s proceed to setting up our project.</p>

<h3 id="step-1-set-up-nx-monorepo-with-angular-and-nestjs">Step 1: Set Up Nx MonoRepo with Angular and NestJS</h3>

<ul>
  <li>
    <p>Create a new Nx workspace using latest Nx version <code class="language-plaintext highlighter-rouge">npx create-nx-workspace@latest</code> and follow the on-screen instructions by choosing Angular project. Your end result should look something like this <img src="/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/nx-monorepo-generation-screen.png" alt="Nx MonoRepo Generation Terminal Window" /></p>
  </li>
  <li>
    <p>Now, add NestJs to your monorepo in your monorepo’s directory using <code class="language-plaintext highlighter-rouge">nx add @nx/nest</code></p>
  </li>
  <li>
    <p>Create a new NestJs app which will keep our backend APIs in the monorepo using <code class="language-plaintext highlighter-rouge">nx g @nx/nest:app apps/api --frontendProject todo</code> which will generate 2 folders <strong>api</strong> and <strong>api-e2e</strong>. Our APIs will be present in the <em>apps/api</em> folder. It will also add a <code class="language-plaintext highlighter-rouge">proxy.conf.json</code> in the <em>apps/todo</em> folder.</p>
  </li>
  <li>
    <p>After the frontend and api apps have been installed, the folder structure should look something like below <img src="/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/nx-api-frontend-folder-structure.png" alt="Application Folder Structure" /></p>
  </li>
</ul>

<hr />

<h3 id="step-2---create-apis-in-nestjs-app">Step 2 - Create APIs in NestJS App</h3>

<p>We will be creating a in-memory database to store our ToDos. So we are not using any external databases, but the code can be modified to support your databases as well. We will also use OpenAPI to display the API documentation.</p>

<ul>
  <li>
    <p>Install the Swagger dependency through <code class="language-plaintext highlighter-rouge">npm install --save @nestjs/swagger</code></p>
  </li>
  <li>
    <p>After your dependencies have been installed, add the Swagger configuration to your <em>apps/api/src/main.ts</em> file. Below is the <em>main.ts</em> file after adding configuration.</p>
  </li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Logger</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@nestjs/common</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">NestFactory</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@nestjs/core</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">DocumentBuilder</span><span class="p">,</span> <span class="nx">SwaggerModule</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@nestjs/swagger</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">AppModule</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./app/app.module</span><span class="dl">"</span><span class="p">;</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nx">bootstrap</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">NestFactory</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">AppModule</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">globalPrefix</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">api</span><span class="dl">"</span><span class="p">;</span>
  <span class="nx">app</span><span class="p">.</span><span class="nx">setGlobalPrefix</span><span class="p">(</span><span class="nx">globalPrefix</span><span class="p">);</span>
  <span class="c1">// Swagger configuration</span>
  <span class="kd">const</span> <span class="nx">config</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">DocumentBuilder</span><span class="p">()</span>
    <span class="p">.</span><span class="nx">setTitle</span><span class="p">(</span><span class="dl">"</span><span class="s2">Todo API</span><span class="dl">"</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">setDescription</span><span class="p">(</span><span class="dl">"</span><span class="s2">API documentation for Todo application</span><span class="dl">"</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">setVersion</span><span class="p">(</span><span class="dl">"</span><span class="s2">1.0</span><span class="dl">"</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">build</span><span class="p">();</span>
  <span class="kd">const</span> <span class="nb">document</span> <span class="o">=</span> <span class="nx">SwaggerModule</span><span class="p">.</span><span class="nx">createDocument</span><span class="p">(</span><span class="nx">app</span><span class="p">,</span> <span class="nx">config</span><span class="p">);</span>
  <span class="nx">SwaggerModule</span><span class="p">.</span><span class="nx">setup</span><span class="p">(</span><span class="dl">"</span><span class="s2">api</span><span class="dl">"</span><span class="p">,</span> <span class="nx">app</span><span class="p">,</span> <span class="nb">document</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">port</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PORT</span> <span class="o">||</span> <span class="mi">3000</span><span class="p">;</span>
  <span class="k">await</span> <span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">port</span><span class="p">);</span>
  <span class="nx">Logger</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span>
    <span class="s2">`🚀 Application is running on: http://localhost:</span><span class="p">${</span><span class="nx">port</span><span class="p">}</span><span class="s2">/</span><span class="p">${</span><span class="nx">globalPrefix</span><span class="p">}</span><span class="s2">`</span>
  <span class="p">);</span>
<span class="p">}</span>

<span class="nx">bootstrap</span><span class="p">();</span>
</code></pre></div></div>

<p><br /></p>
<ul>
  <li>
    <p>You should now have OpenAPI empty documentation ready. To view the Swagger docs in your browser, start the API server using <code class="language-plaintext highlighter-rouge">nx serve api</code> and browse to <a href="http://localhost:3000/api">http://localhost:3000/api</a> and you should see the below image <img src="/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/empty-swagger-nestjs.png" alt="Empty Swagger API Documentation" /></p>
  </li>
  <li>
    <p>Let’s write the API services and controllers. Before that, we will add a new library which will hold our models and interfaces for our ToDo object. Generate a new library in Nx workspace using the command <code class="language-plaintext highlighter-rouge">nx g @nx/js:library --name=types --bundler=none --directory=libs/types --projectNameAndRootFormat=as-provided</code> or use the Nx Console to generate a <code class="language-plaintext highlighter-rouge">@nx/js</code> library.</p>
  </li>
  <li>
    <p>In the newly generated lib, go to <code class="language-plaintext highlighter-rouge">libs/types/src/lib/types.ts</code> file and add the DTOs and model for our ToDo object.</p>
  </li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">ApiProperty</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@nestjs/swagger</span><span class="dl">"</span><span class="p">;</span>

<span class="k">export</span> <span class="kd">class</span> <span class="nx">ToDoDto</span> <span class="p">{</span>
  <span class="p">@</span><span class="nd">ApiProperty</span><span class="p">({</span> <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Task</span><span class="dl">"</span> <span class="p">})</span>
  <span class="nx">task</span><span class="o">!</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">export</span> <span class="kr">interface</span> <span class="nx">ToDo</span> <span class="kd">extends</span> <span class="nx">ToDoDto</span> <span class="p">{</span>
  <span class="nl">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">done</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<blockquote>
  <p>The <strong>ToDoDto</strong> is used to transfer via REST, and <strong>ToDo</strong> interface stores additional properties indicating id and status.</p>
</blockquote>

<p><br /></p>
<ul>
  <li>Once your <em>types</em> lib is ready, we can move to writing our service. For sake of simplicity in this tutorial, I will not be using any Database and will be creating the Tasks in-memory.</li>
</ul>

<p><strong>File</strong>: <code class="language-plaintext highlighter-rouge">apps/api/src/app/app.service.ts</code></p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Injectable</span><span class="p">,</span> <span class="nx">NotFoundException</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@nestjs/common</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">ToDo</span><span class="p">,</span> <span class="nx">ToDoDto</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@nx-todo-app/types</span><span class="dl">"</span><span class="p">;</span>

<span class="p">@</span><span class="nd">Injectable</span><span class="p">()</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">AppService</span> <span class="p">{</span>
  <span class="nl">todos</span><span class="p">:</span> <span class="nx">ToDo</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>

  <span class="nx">getAllToDos</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">todos</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="nx">addToDo</span><span class="p">(</span><span class="nx">todoDto</span><span class="p">:</span> <span class="nx">ToDoDto</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">todo</span><span class="p">:</span> <span class="nx">ToDo</span> <span class="o">=</span> <span class="p">{</span> <span class="na">id</span><span class="p">:</span> <span class="nb">String</span><span class="p">(</span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">()),</span> <span class="na">done</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="p">...</span><span class="nx">todoDto</span> <span class="p">};</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">todos</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">todo</span><span class="p">);</span>
    <span class="k">return</span> <span class="p">{</span> <span class="na">message</span><span class="p">:</span> <span class="dl">"</span><span class="s2">ToDo successfully added</span><span class="dl">"</span> <span class="p">};</span>
  <span class="p">}</span>

  <span class="nx">getActiveToDos</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">todos</span><span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">todo</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="o">!</span><span class="nx">todo</span><span class="p">.</span><span class="nx">done</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="nx">getCompletedToDos</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">todos</span><span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">todo</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">todo</span><span class="p">.</span><span class="nx">done</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="nx">updateToDo</span><span class="p">(</span><span class="nx">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">done</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">todo</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">todos</span><span class="p">.</span><span class="nx">find</span><span class="p">((</span><span class="nx">todo</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">todo</span><span class="p">.</span><span class="nx">id</span> <span class="o">===</span> <span class="nx">id</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">todo</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">todo</span><span class="p">.</span><span class="nx">done</span> <span class="o">=</span> <span class="nx">done</span> <span class="o">??</span> <span class="nx">todo</span><span class="p">.</span><span class="nx">done</span><span class="p">;</span>
      <span class="k">return</span> <span class="p">{</span> <span class="na">message</span><span class="p">:</span> <span class="s2">`ToDo with ID </span><span class="p">${</span><span class="nx">id</span><span class="p">}</span><span class="s2"> updated successfully`</span> <span class="p">};</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nx">NotFoundException</span><span class="p">(</span><span class="s2">`ToDo with ID </span><span class="p">${</span><span class="nx">id</span><span class="p">}</span><span class="s2"> not found`</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="nx">deleteToDo</span><span class="p">(</span><span class="nx">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">todoIndex</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">todos</span><span class="p">.</span><span class="nx">findIndex</span><span class="p">((</span><span class="nx">todo</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">todo</span><span class="p">.</span><span class="nx">id</span> <span class="o">===</span> <span class="nx">id</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">todoIndex</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">throw</span> <span class="k">new</span> <span class="nx">NotFoundException</span><span class="p">(</span><span class="s2">`ToDo with ID </span><span class="p">${</span><span class="nx">id</span><span class="p">}</span><span class="s2"> not found`</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">todos</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">todoIndex</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
    <span class="k">return</span> <span class="p">{</span> <span class="na">message</span><span class="p">:</span> <span class="s2">`ToDo with ID </span><span class="p">${</span><span class="nx">id</span><span class="p">}</span><span class="s2"> deleted successfully`</span> <span class="p">};</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<blockquote>
  <p>The <strong>todos</strong> array holds our tasks in memory. Standard CRUD(Create, Read, Update and Delete) functions have been written which are self explanatory.
<br /> (Please put in comments if something is unclear).</p>
</blockquote>

<ul>
  <li>The next step is to write the API Controllers to access this service. We will write the following REST Functions (GET, PUT, POST, DELETE).</li>
</ul>

<p><strong>File</strong>: <code class="language-plaintext highlighter-rouge">apps/api/src/app/app.controller.ts</code></p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">@</span><span class="nd">ApiTags</span><span class="p">(</span><span class="dl">"</span><span class="s2">tasks</span><span class="dl">"</span><span class="p">)</span>
<span class="p">@</span><span class="nd">Controller</span><span class="p">(</span><span class="dl">"</span><span class="s2">/v1/tasks</span><span class="dl">"</span><span class="p">)</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">AppController</span> <span class="p">{</span>
  <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="k">readonly</span> <span class="nx">appService</span><span class="p">:</span> <span class="nx">AppService</span><span class="p">)</span> <span class="p">{}</span>

  <span class="p">@</span><span class="nd">Get</span><span class="p">()</span>
  <span class="p">@</span><span class="nd">ApiOperation</span><span class="p">({</span> <span class="na">summary</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Get all ToDos</span><span class="dl">"</span> <span class="p">})</span>
  <span class="p">@</span><span class="nd">ApiResponse</span><span class="p">({</span>
    <span class="na">status</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
    <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Returns an array of ToDos</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">isArray</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
  <span class="p">})</span>
  <span class="nx">getAllToDos</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">appService</span><span class="p">.</span><span class="nx">getAllToDos</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="p">@</span><span class="nd">Post</span><span class="p">()</span>
  <span class="p">@</span><span class="nd">ApiOperation</span><span class="p">({</span> <span class="na">summary</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Add a new ToDo</span><span class="dl">"</span> <span class="p">})</span>
  <span class="p">@</span><span class="nd">ApiBody</span><span class="p">({</span> <span class="na">type</span><span class="p">:</span> <span class="nx">ToDoDto</span> <span class="p">})</span>
  <span class="p">@</span><span class="nd">ApiResponse</span><span class="p">({</span> <span class="na">status</span><span class="p">:</span> <span class="mi">201</span><span class="p">,</span> <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">ToDo successfully added</span><span class="dl">"</span> <span class="p">})</span>
  <span class="nx">addToDo</span><span class="p">(@</span><span class="nd">Body</span><span class="p">()</span> <span class="nx">todo</span><span class="p">:</span> <span class="nx">ToDoDto</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">appService</span><span class="p">.</span><span class="nx">addToDo</span><span class="p">(</span><span class="nx">todo</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="p">@</span><span class="nd">Put</span><span class="p">(</span><span class="dl">"</span><span class="s2">:id/done</span><span class="dl">"</span><span class="p">)</span>
  <span class="p">@</span><span class="nd">ApiOperation</span><span class="p">({</span> <span class="na">summary</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Update the status of a ToDo</span><span class="dl">"</span> <span class="p">})</span>
  <span class="p">@</span><span class="nd">ApiParam</span><span class="p">({</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">id</span><span class="dl">"</span><span class="p">,</span> <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">ToDo ID</span><span class="dl">"</span> <span class="p">})</span>
  <span class="p">@</span><span class="nd">ApiBody</span><span class="p">({</span> <span class="na">schema</span><span class="p">:</span> <span class="p">{</span> <span class="na">properties</span><span class="p">:</span> <span class="p">{</span> <span class="na">done</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">boolean</span><span class="dl">"</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">})</span>
  <span class="p">@</span><span class="nd">ApiResponse</span><span class="p">({</span> <span class="na">status</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span> <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">ToDo updated successfully</span><span class="dl">"</span> <span class="p">})</span>
  <span class="nx">updateStatus</span><span class="p">(@</span><span class="nd">Param</span><span class="p">(</span><span class="dl">"</span><span class="s2">id</span><span class="dl">"</span><span class="p">)</span> <span class="nx">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="p">@</span><span class="nd">Body</span><span class="p">(</span><span class="dl">"</span><span class="s2">done</span><span class="dl">"</span><span class="p">)</span> <span class="nx">done</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">appService</span><span class="p">.</span><span class="nx">updateToDo</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">done</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="p">@</span><span class="nd">Delete</span><span class="p">(</span><span class="dl">"</span><span class="s2">:id</span><span class="dl">"</span><span class="p">)</span>
  <span class="p">@</span><span class="nd">ApiOperation</span><span class="p">({</span> <span class="na">summary</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Delete a ToDo</span><span class="dl">"</span> <span class="p">})</span>
  <span class="p">@</span><span class="nd">ApiParam</span><span class="p">({</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">id</span><span class="dl">"</span><span class="p">,</span> <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">ToDo ID</span><span class="dl">"</span> <span class="p">})</span>
  <span class="p">@</span><span class="nd">ApiResponse</span><span class="p">({</span> <span class="na">status</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span> <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">ToDo deleted successfully</span><span class="dl">"</span> <span class="p">})</span>
  <span class="nx">deleteToDo</span><span class="p">(@</span><span class="nd">Param</span><span class="p">(</span><span class="dl">"</span><span class="s2">id</span><span class="dl">"</span><span class="p">)</span> <span class="nx">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">appService</span><span class="p">.</span><span class="nx">deleteToDo</span><span class="p">(</span><span class="nx">id</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<ul>
  <li>Run <code class="language-plaintext highlighter-rouge">nx serve api</code> and browse to <a href="http://localhost:3000/api">http://localhost:3000/api</a>, and you should have all the APIs ready. Go and Try it yourself using cURL or Postman. The OpenAPI Schema should look like <img src="/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/swagger-with-apis-nestjs.png" alt="Swagger API Documentation" /></li>
</ul>

<hr />

<h3 id="step-3---generate-openapi-services-for-angular">Step 3 - Generate OpenAPI Services for Angular</h3>

<p>You might ask, why we cannot write our own HttpService in Angular. Sure, we can! But why to do it manually when we have an awesome <em><strong>OpenAPI Generator CLI</strong></em> tool available.</p>

<ul>
  <li>
    <p>Install the OpenAPI Generator by - <code class="language-plaintext highlighter-rouge">npm install @openapitools/openapi-generator-cli -g</code>. This will globally install the openapi-generator-cli in your machine.</p>
  </li>
  <li>
    <p>We will create a new library to hold our OpenAPI generated services. Create a new lib using <code class="language-plaintext highlighter-rouge">nx g @nx/js:library --name=openapi-generated --bundler=none --directory=libs/openapi-generated --projectNameAndRootFormat=as-provided</code> and delete the 2 files <strong>openapi_generated.ts</strong> and <strong>openapi_generated.spec.ts</strong></p>
  </li>
  <li>
    <p>Next, we will run the command to populate our Typescript client service - <code class="language-plaintext highlighter-rouge">npx @openapitools/openapi-generator-cli generate -i http://localhost:3000/api-json --generator-name typescript-angular -o libs/openapi-generated/src/lib --additional-properties=useSingleRequestParameter=true</code>. This wil generate a bunch of files including <strong>model</strong> and <strong>api</strong>. You can browse to see the ToDoDto model among others and the todo service file generated.</p>

    <blockquote>
      <p>Make sure your NestJS server is up and running, and then execute this command. It picks up the OpenApi Spec from <strong>http://localhost:3000/api-json</strong>.</p>
    </blockquote>
  </li>
  <li>
    <p>You should have the following openapi-generated library as shown in below picture. <img src="/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/openapi-generated-typescript.png" alt="OpenAPI Generated Client Library" /></p>
  </li>
  <li>
    <p>One final step, update the <code class="language-plaintext highlighter-rouge">libs/openapi-generated/src/index.ts</code> file to include our APIs.</p>
  </li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="o">*</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./lib/api/api</span><span class="dl">"</span><span class="p">;</span> <span class="c1">//This will allow the APIs to be exposed.</span>
</code></pre></div></div>

<p><br /></p>

<p>We have completed coding our backend, and will move now to code our UI in Angular. <img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExam1lc3RtZ3hkb2x6Y3NhcW8wYnQ4eGlvZzhsNnZ3c2Jvcm16Ym45aCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/a0h7sAqON67nO/giphy.gif" alt="Success GIPHY Meme" /></p>

<p><br /></p>

<hr />

<h3 id="step-4---add-angular-material-and-tailwind-css-libraries">Step 4 - Add Angular Material and Tailwind CSS Libraries</h3>

<ul>
  <li>
    <p>We will be using Angular Material and Tailwind for our frontend app.</p>
  </li>
  <li>
    <p>Install Angular Material in your project using the command <code class="language-plaintext highlighter-rouge">npx nx g @angular/material:ng-add --project=todo</code> and use the below image as reference to choose your options. <img src="/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/angular-material-setup.png" alt="Angular Material Options" /></p>
  </li>
</ul>

<p><br /></p>

<ul>
  <li>Install <a href="https://tailwindcss.com/">Tailwind CSS</a> using <code class="language-plaintext highlighter-rouge">npx nx g @nx/angular:setup-tailwind todo</code>.</li>
</ul>

<hr />

<h3 id="step-5---add-store-for-todo-app-actions-reducers-and-effects">Step 5 - Add Store for ToDo App (Actions, Reducers, and Effects)</h3>

<blockquote>
  <p>For those unaware of NgRx Store, refer here - <a href="https://ngrx.io/guide/store">NgRx Store Guide</a></p>
</blockquote>

<p>In our app, we will be using the Global Store state management.</p>

<ul>
  <li>
    <p>Install the necessary store dependencies using <code class="language-plaintext highlighter-rouge">nx g ngrx-root-store todo --addDevTools=true</code>. This will add the Store and Effects module in the <em>app.config.ts</em> file of your <em>apps/todo/src/app</em> folder.</p>
  </li>
  <li>
    <p>Create a new folder under <em>apps/todo/src/app/</em> named <em>store/todo</em> where we will write our actions, reducers and effects.</p>

    <ul>
      <li>Create 3 files named as <strong>todo.actions.ts</strong>, <strong>todo.effects.ts</strong>, and <strong>todo.reducers.ts</strong> in the same folder.</li>
    </ul>
  </li>
</ul>

<h4 id="actions">Actions</h4>

<ul>
  <li>Let’s begin by writing our first action to load all the tasks.</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Load Tasks</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">loadTasks</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span><span class="dl">"</span><span class="s2">[Todo] Load Tasks</span><span class="dl">"</span><span class="p">);</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">loadTasksSuccess</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Load Tasks Success</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">tasks</span><span class="p">:</span> <span class="nx">ToDo</span><span class="p">[]</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">loadTasksFailure</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Load Tasks Failure</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">error</span><span class="p">:</span> <span class="nx">unknown</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
</code></pre></div></div>

<ul>
  <li>Similarly, we will write the actions for all other CRUD operations</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Add Task</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">addTask</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span><span class="dl">"</span><span class="s2">[Todo] Add Task</span><span class="dl">"</span><span class="p">,</span> <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">task</span><span class="p">:</span> <span class="nx">ToDo</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">());</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">addTaskSuccess</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Add Task Success</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">task</span><span class="p">:</span> <span class="nx">ToDo</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">addTaskFailure</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Add Task Failure</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">error</span><span class="p">:</span> <span class="nx">unknown</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>

<span class="c1">// Update Task Status</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">updateTaskStatus</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Update Task Status</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span> <span class="nl">done</span><span class="p">:</span> <span class="nx">boolean</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">updateTaskStatusSuccess</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Update Task Status Success</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span> <span class="nl">done</span><span class="p">:</span> <span class="nx">boolean</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">updateTaskStatusFailure</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Update Task Status Failure</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">error</span><span class="p">:</span> <span class="nx">unknown</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>

<span class="c1">// Delete Task</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">deleteTask</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Delete Task</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">id</span><span class="p">:</span> <span class="kr">string</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">deleteTaskSuccess</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Delete Task Success</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">id</span><span class="p">:</span> <span class="kr">string</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">deleteTaskFailure</span> <span class="o">=</span> <span class="nx">createAction</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">[Todo] Delete Task Failure</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">props</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">error</span><span class="p">:</span> <span class="nx">unknown</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Github Code - <a href="https://github.com/msindev/nx-todo-app/blob/main/apps/todo/src/app/store/todo/todo.actions.ts">todo.actions.ts</a></p>
</blockquote>

<h4 id="reducers">Reducers</h4>

<p>Reducers are used to change the state based on the action type. We will write the reducers for all the actions listed above. We first start with the state required in our app, which will be used to store the tasks data.</p>

<ul>
  <li>In the <em>todo.reducer.ts</em> file, create the AppState and TodoState.</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kr">interface</span> <span class="nx">AppState</span> <span class="p">{</span>
  <span class="nl">tasks</span><span class="p">:</span> <span class="nx">TodoState</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">export</span> <span class="kr">interface</span> <span class="nx">TodoState</span> <span class="p">{</span>
  <span class="nl">tasks</span><span class="p">:</span> <span class="nx">ToDo</span><span class="p">[];</span> <span class="c1">//List of tasks retrieved from API</span>
  <span class="nl">loading</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">;</span> <span class="c1">//To show loader on screen</span>
  <span class="nl">error</span><span class="p">:</span> <span class="nx">unknown</span><span class="p">;</span> <span class="c1">//Sets to error object for any API failures</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">initialState</span><span class="p">:</span> <span class="nx">TodoState</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">tasks</span><span class="p">:</span> <span class="p">[],</span>
  <span class="na">loading</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
  <span class="na">error</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="p">};</span>
</code></pre></div></div>

<ul>
  <li>Next, we write the todoReducer using NgRx’s <strong>createReducer</strong> function which takes the initialState and multiple actions as parameters.</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">const</span> <span class="nx">todoReducer</span> <span class="o">=</span> <span class="nx">createReducer</span><span class="p">(</span>
  <span class="nx">initialState</span><span class="p">,</span>

  <span class="nx">on</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasks</span><span class="p">,</span> <span class="p">(</span><span class="nx">state</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">({</span>
    <span class="p">...</span><span class="nx">state</span><span class="p">,</span>
    <span class="na">loading</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="na">error</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
  <span class="p">})),</span>

  <span class="nx">on</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasksSuccess</span><span class="p">,</span> <span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="p">{</span> <span class="nx">tasks</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">({</span>
    <span class="p">...</span><span class="nx">state</span><span class="p">,</span>
    <span class="na">tasks</span><span class="p">:</span> <span class="p">[...</span><span class="nx">tasks</span><span class="p">],</span>
    <span class="na">loading</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
  <span class="p">})),</span>

  <span class="nx">on</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasksFailure</span><span class="p">,</span> <span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="p">{</span> <span class="nx">error</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">({</span>
    <span class="p">...</span><span class="nx">state</span><span class="p">,</span>
    <span class="na">loading</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="nx">error</span><span class="p">,</span>
  <span class="p">})),</span>

  <span class="nx">on</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">addTaskSuccess</span><span class="p">,</span> <span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="p">{</span> <span class="nx">task</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">({</span>
    <span class="p">...</span><span class="nx">state</span><span class="p">,</span>
    <span class="na">tasks</span><span class="p">:</span> <span class="p">[...</span><span class="nx">state</span><span class="p">.</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">task</span><span class="p">],</span>
  <span class="p">})),</span>

  <span class="nx">on</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">updateTaskStatusSuccess</span><span class="p">,</span> <span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="p">{</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">done</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">({</span>
    <span class="p">...</span><span class="nx">state</span><span class="p">,</span>
    <span class="na">tasks</span><span class="p">:</span> <span class="nx">state</span><span class="p">.</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">)</span> <span class="o">=&gt;</span>
      <span class="nx">task</span><span class="p">.</span><span class="nx">id</span> <span class="o">===</span> <span class="nx">id</span> <span class="p">?</span> <span class="p">{</span> <span class="p">...</span><span class="nx">task</span><span class="p">,</span> <span class="nx">done</span> <span class="p">}</span> <span class="p">:</span> <span class="nx">task</span>
    <span class="p">),</span>
  <span class="p">})),</span>

  <span class="nx">on</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">deleteTaskSuccess</span><span class="p">,</span> <span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="p">{</span> <span class="nx">id</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">({</span>
    <span class="p">...</span><span class="nx">state</span><span class="p">,</span>
    <span class="na">tasks</span><span class="p">:</span> <span class="nx">state</span><span class="p">.</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">task</span><span class="p">.</span><span class="nx">id</span> <span class="o">!==</span> <span class="nx">id</span><span class="p">),</span>
  <span class="p">}))</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Github Code - <a href="https://github.com/msindev/nx-todo-app/blob/main/apps/todo/src/app/store/todo/todo.reducer.ts">todo.reducer.ts</a></p>
</blockquote>

<h4 id="effects">Effects</h4>

<p>Effects interact with external services(in our case, the backend API) based on the Actions and update the state. We will need 4 effects to support all CRUD operations.</p>

<ul>
  <li>Here is the <strong>loadTasks</strong> effect using NgRx’s <strong>createEffect</strong> function. We use the 3 loadTasks actions - loadTasks, loadTasksSuccess and loadTasksFailure to call the effect.</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">loadTasks$</span> <span class="o">=</span> <span class="nx">createEffect</span><span class="p">(()</span> <span class="o">=&gt;</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">actions$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
    <span class="nx">ofType</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasks</span><span class="p">),</span>
    <span class="nx">mergeMap</span><span class="p">(()</span> <span class="o">=&gt;</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">todoService</span><span class="p">.</span><span class="nx">appControllerGetAllToDos</span><span class="p">().</span><span class="nx">pipe</span><span class="p">(</span>
        <span class="nx">map</span><span class="p">((</span><span class="nx">tasks</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasksSuccess</span><span class="p">({</span> <span class="nx">tasks</span> <span class="p">})),</span>
        <span class="nx">catchError</span><span class="p">((</span><span class="nx">error</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">of</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasksFailure</span><span class="p">({</span> <span class="nx">error</span> <span class="p">})))</span>
      <span class="p">)</span>
    <span class="p">)</span>
  <span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>In this code block, we pipe through the actions from NgRx (full code below), and call the todoService method to load tasks. For a successful response, it is mapped and <strong>TodoActions.loadTasksSuccess</strong> is called which in turn will call the reducer to update the state. Later in the Angular component, we will subscribe to the state changes and update our component. For any errors <strong>TodoActions.loadTasksFailure</strong> is called with the error sent as prop.</p>
</blockquote>

<ul>
  <li>Here is the complete file with other effects for Add Task, Update Task, and Delete Task.</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">Injectable</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@angular/core</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Actions</span><span class="p">,</span> <span class="nx">createEffect</span><span class="p">,</span> <span class="nx">ofType</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@ngrx/effects</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">mergeMap</span><span class="p">,</span> <span class="nx">map</span><span class="p">,</span> <span class="nx">catchError</span><span class="p">,</span> <span class="k">of</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">rxjs</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">TodoActions</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./todo.actions</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">TasksService</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@nx-todo-app/openapi-generated</span><span class="dl">"</span><span class="p">;</span>

<span class="p">@</span><span class="nd">Injectable</span><span class="p">()</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">TodoEffects</span> <span class="p">{</span>
  <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">actions$</span><span class="p">:</span> <span class="nx">Actions</span><span class="p">,</span> <span class="k">private</span> <span class="nx">todoService</span><span class="p">:</span> <span class="nx">TasksService</span><span class="p">)</span> <span class="p">{}</span>

  <span class="nx">loadTasks$</span> <span class="o">=</span> <span class="nx">createEffect</span><span class="p">(()</span> <span class="o">=&gt;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">actions$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
      <span class="nx">ofType</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasks</span><span class="p">),</span>
      <span class="nx">mergeMap</span><span class="p">(()</span> <span class="o">=&gt;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">todoService</span><span class="p">.</span><span class="nx">appControllerGetAllToDos</span><span class="p">().</span><span class="nx">pipe</span><span class="p">(</span>
          <span class="nx">map</span><span class="p">((</span><span class="nx">tasks</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasksSuccess</span><span class="p">({</span> <span class="nx">tasks</span> <span class="p">})),</span>
          <span class="nx">catchError</span><span class="p">((</span><span class="nx">error</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">of</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">loadTasksFailure</span><span class="p">({</span> <span class="nx">error</span> <span class="p">})))</span>
        <span class="p">)</span>
      <span class="p">)</span>
    <span class="p">)</span>
  <span class="p">);</span>

  <span class="nx">addTask$</span> <span class="o">=</span> <span class="nx">createEffect</span><span class="p">(()</span> <span class="o">=&gt;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">actions$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
      <span class="nx">ofType</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">addTask</span><span class="p">),</span>
      <span class="nx">mergeMap</span><span class="p">(({</span> <span class="nx">task</span> <span class="p">})</span> <span class="o">=&gt;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">todoService</span><span class="p">.</span><span class="nx">appControllerAddToDo</span><span class="p">(</span><span class="nx">task</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span>
          <span class="nx">map</span><span class="p">((</span><span class="nx">addedTask</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">TodoActions</span><span class="p">.</span><span class="nx">addTaskSuccess</span><span class="p">({</span> <span class="na">task</span><span class="p">:</span> <span class="nx">addedTask</span> <span class="p">})),</span>
          <span class="nx">catchError</span><span class="p">((</span><span class="nx">error</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">of</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">addTaskFailure</span><span class="p">({</span> <span class="nx">error</span> <span class="p">})))</span>
        <span class="p">)</span>
      <span class="p">)</span>
    <span class="p">)</span>
  <span class="p">);</span>

  <span class="nx">updateTaskStatus$</span> <span class="o">=</span> <span class="nx">createEffect</span><span class="p">(()</span> <span class="o">=&gt;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">actions$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
      <span class="nx">ofType</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">updateTaskStatus</span><span class="p">),</span>
      <span class="nx">mergeMap</span><span class="p">(({</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">done</span> <span class="p">})</span> <span class="o">=&gt;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">todoService</span><span class="p">.</span><span class="nx">appControllerUpdateStatus</span><span class="p">({</span> <span class="nx">done</span> <span class="p">},</span> <span class="nx">id</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span>
          <span class="nx">map</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">TodoActions</span><span class="p">.</span><span class="nx">updateTaskStatusSuccess</span><span class="p">({</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">done</span> <span class="p">})),</span>
          <span class="nx">catchError</span><span class="p">((</span><span class="nx">error</span><span class="p">)</span> <span class="o">=&gt;</span>
            <span class="k">of</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">updateTaskStatusFailure</span><span class="p">({</span> <span class="nx">error</span> <span class="p">}))</span>
          <span class="p">)</span>
        <span class="p">)</span>
      <span class="p">)</span>
    <span class="p">)</span>
  <span class="p">);</span>

  <span class="nx">deleteTask$</span> <span class="o">=</span> <span class="nx">createEffect</span><span class="p">(()</span> <span class="o">=&gt;</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">actions$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
      <span class="nx">ofType</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">deleteTask</span><span class="p">),</span>
      <span class="nx">mergeMap</span><span class="p">(({</span> <span class="nx">id</span> <span class="p">})</span> <span class="o">=&gt;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">todoService</span><span class="p">.</span><span class="nx">appControllerDeleteToDo</span><span class="p">(</span><span class="nx">id</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span>
          <span class="nx">map</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">TodoActions</span><span class="p">.</span><span class="nx">deleteTaskSuccess</span><span class="p">({</span> <span class="nx">id</span> <span class="p">})),</span>
          <span class="nx">catchError</span><span class="p">((</span><span class="nx">error</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">of</span><span class="p">(</span><span class="nx">TodoActions</span><span class="p">.</span><span class="nx">deleteTaskFailure</span><span class="p">({</span> <span class="nx">error</span> <span class="p">})))</span>
        <span class="p">)</span>
      <span class="p">)</span>
    <span class="p">)</span>
  <span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>As the final step to setup your store, we need to register the effects and store in our <strong>app.config.ts</strong>.</p>

<ul>
  <li>In the app.config.ts file, update the providers array to change the provideEffects() and provideStore() to</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">provideEffects</span><span class="p">([</span><span class="nx">TodoEffects</span><span class="p">]),</span>
<span class="nx">provideStore</span><span class="p">({</span> <span class="na">tasks</span><span class="p">:</span> <span class="nx">todoReducer</span> <span class="p">}),</span>
</code></pre></div></div>

<h3 id="step-6---write-the-todo-component">Step 6 - Write the ToDo Component</h3>

<p>We will have a look at the UI and see that we have 2 components to build.</p>

<ul>
  <li>One is a list component which has the input bar and the todos, which will be reused in the 3 tabs(All, Active, Completed).</li>
  <li>The top one is the app.component which has the title and 3 tabs.</li>
</ul>

<p><img src="/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/todo-component-structure.png" alt="ToDo App Components" /></p>

<h4 id="todo-component">todo component</h4>

<ul>
  <li>
    <p>Generate a new component using <code class="language-plaintext highlighter-rouge">nx g @nx/angular:component --name=todo-list --directory=apps/todo/src/app/components/todo-list --changeDetection=OnPush --nameAndDirectoryFormat=as-provided --skipTests=true</code></p>
  </li>
  <li>
    <p>We will be using Angular Material’s components to build our component. Add the below template file to <strong>todo-list.component.html</strong></p>
  </li>
</ul>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;form</span> <span class="na">class=</span><span class="s">"flex mt-16"</span> <span class="na">(submit)=</span><span class="s">"addTask(taskInput.value)"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;mat-form-field</span> <span class="na">class=</span><span class="s">"w-9/12"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;mat-label&gt;</span>add details<span class="nt">&lt;/mat-label&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">matInput</span> <span class="na">#taskInput</span> <span class="nt">/&gt;</span>
  <span class="nt">&lt;/mat-form-field&gt;</span>
  <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">mat-raised-button</span> <span class="na">color=</span><span class="s">"primary"</span> <span class="na">class=</span><span class="s">"mt-2 ml-16"</span><span class="nt">&gt;</span>
    Add
  <span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;/form&gt;</span>

<span class="nt">&lt;ul&gt;</span>
  <span class="nt">&lt;li</span> <span class="na">*ngFor=</span><span class="s">"let item of tasks"</span> <span class="na">class=</span><span class="s">"flex items-center justify-between"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;mat-checkbox</span>
      <span class="na">[checked]=</span><span class="s">"item.done"</span>
      <span class="na">(change)=</span><span class="s">"updateTaskStatus(item, $event.checked)"</span>
    <span class="nt">&gt;</span>
      
    <span class="nt">&lt;/mat-checkbox&gt;</span>
    <span class="nt">&lt;button</span> <span class="na">mat-icon-button</span> <span class="na">color=</span><span class="s">"warn"</span> <span class="na">(click)=</span><span class="s">"deleteTask(item.id)"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;mat-icon&gt;</span>delete<span class="nt">&lt;/mat-icon&gt;</span>
    <span class="nt">&lt;/button&gt;</span>
  <span class="nt">&lt;/li&gt;</span>
<span class="nt">&lt;/ul&gt;</span>
</code></pre></div></div>

<ul>
  <li>Import the necessary modules in the component file, and inject store into component. We will dispatch the necessary store actions on event handlers present in the template file. Below is the complete code for <strong>todo-list.component.ts</strong></li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">@</span><span class="nd">Component</span><span class="p">({</span>
  <span class="na">selector</span><span class="p">:</span> <span class="dl">"</span><span class="s2">nx-todo-app-todo-list</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">standalone</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
  <span class="na">imports</span><span class="p">:</span> <span class="p">[</span>
    <span class="nx">CommonModule</span><span class="p">,</span>
    <span class="nx">MatCheckboxModule</span><span class="p">,</span>
    <span class="nx">MatInputModule</span><span class="p">,</span>
    <span class="nx">MatButtonModule</span><span class="p">,</span>
    <span class="nx">MatIconModule</span><span class="p">,</span>
  <span class="p">],</span>
  <span class="na">templateUrl</span><span class="p">:</span> <span class="dl">"</span><span class="s2">./todo-list.component.html</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">changeDetection</span><span class="p">:</span> <span class="nx">ChangeDetectionStrategy</span><span class="p">.</span><span class="nx">OnPush</span><span class="p">,</span>
<span class="p">})</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">TodoListComponent</span> <span class="p">{</span>
  <span class="p">@</span><span class="nd">ViewChild</span><span class="p">(</span><span class="dl">"</span><span class="s2">taskInput</span><span class="dl">"</span><span class="p">)</span>
  <span class="nx">taskInput</span><span class="o">!</span><span class="p">:</span> <span class="nx">ElementRef</span><span class="o">&lt;</span><span class="nx">HTMLInputElement</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="p">@</span><span class="nd">Input</span><span class="p">()</span>
  <span class="nx">tasks</span><span class="o">!</span><span class="p">:</span> <span class="nx">ToDo</span><span class="p">[]</span> <span class="o">|</span> <span class="kc">null</span><span class="p">;</span>

  <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">store</span><span class="p">:</span> <span class="nx">Store</span><span class="o">&lt;</span><span class="nx">AppState</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{}</span>

  <span class="nx">addTask</span><span class="p">(</span><span class="nx">taskInput</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">taskInput</span><span class="p">.</span><span class="nx">trim</span><span class="p">()</span> <span class="o">===</span> <span class="dl">""</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="c1">//Create new object for a task</span>
    <span class="kd">const</span> <span class="na">task</span><span class="p">:</span> <span class="nx">ToDo</span> <span class="o">=</span> <span class="p">{</span>
      <span class="na">id</span><span class="p">:</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">().</span><span class="nx">toString</span><span class="p">(),</span>
      <span class="na">task</span><span class="p">:</span> <span class="nx">taskInput</span><span class="p">,</span>
      <span class="na">done</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="p">};</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="nx">addTask</span><span class="p">({</span> <span class="nx">task</span> <span class="p">}));</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">taskInput</span><span class="p">.</span><span class="nx">nativeElement</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="dl">""</span><span class="p">;</span> <span class="c1">//Reset input form</span>
  <span class="p">}</span>

  <span class="nx">updateTaskStatus</span><span class="p">(</span><span class="nx">task</span><span class="p">:</span> <span class="nx">ToDo</span><span class="p">,</span> <span class="nx">event</span><span class="p">:</span> <span class="nx">boolean</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="nx">updateTaskStatus</span><span class="p">({</span> <span class="na">id</span><span class="p">:</span> <span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="na">done</span><span class="p">:</span> <span class="nx">event</span> <span class="p">}));</span>
  <span class="p">}</span>

  <span class="nx">deleteTask</span><span class="p">(</span><span class="nx">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="nx">deleteTask</span><span class="p">({</span> <span class="nx">id</span> <span class="p">}));</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><br /></p>

<h4 id="app-component">app component</h4>

<ul>
  <li>The <strong>app.component.ts</strong> contains a simple template with the title and tabs. We use Angular Material Tabs for 3 tabs - <strong>All</strong> (All Tasks), <strong>Active</strong> (Active Tasks), and <strong>Completed</strong> (Completed Tasks).</li>
</ul>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;head</span> <span class="na">class=</span><span class="s">"flex justify-center my-12"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;title&gt;</span>ToDo App<span class="nt">&lt;/title&gt;</span>
  <span class="nt">&lt;h1&gt;</span>#todo<span class="nt">&lt;/h1&gt;</span>
<span class="nt">&lt;/head&gt;</span>

<span class="nt">&lt;body</span> <span class="na">class=</span><span class="s">"container mx-auto w-1/2"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;mat-tab-group</span>
    <span class="na">fitInkBarToContent</span>
    <span class="na">mat-stretch-tabs</span>
    <span class="na">class=</span><span class="s">"border-b-1 border-black"</span>
  <span class="nt">&gt;</span>
    <span class="nt">&lt;mat-tab</span> <span class="na">label=</span><span class="s">"All"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;nx-todo-app-todo-list</span>
        <span class="na">[tasks]=</span><span class="s">"allTasks$ | async"</span>
      <span class="nt">&gt;&lt;/nx-todo-app-todo-list&gt;</span>
    <span class="nt">&lt;/mat-tab&gt;</span>
    <span class="nt">&lt;mat-tab</span> <span class="na">label=</span><span class="s">"Active"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;nx-todo-app-todo-list</span>
        <span class="na">[tasks]=</span><span class="s">"activeTasks$ | async"</span>
      <span class="nt">&gt;&lt;/nx-todo-app-todo-list&gt;</span>
    <span class="nt">&lt;/mat-tab&gt;</span>
    <span class="nt">&lt;mat-tab</span> <span class="na">label=</span><span class="s">"Completed"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;nx-todo-app-todo-list</span>
        <span class="na">[tasks]=</span><span class="s">"completedTasks$ | async"</span>
      <span class="nt">&gt;&lt;/nx-todo-app-todo-list&gt;</span>
    <span class="nt">&lt;/mat-tab&gt;</span>
  <span class="nt">&lt;/mat-tab-group&gt;</span>
<span class="nt">&lt;/body&gt;</span>

<span class="nt">&lt;router-outlet&gt;&lt;/router-outlet&gt;</span>
</code></pre></div></div>

<p>We pass the tasks as input to the <strong>nx-todo-app-todo-list</strong> or simply <em>todo-list.component.ts</em> depending on tab (all, active and completed). The <strong>async</strong> keyword subscribes to the observable (allTasks$, activeTasks$, completedTasks$) and sends the list to child component. More details in the component implementation.</p>

<ul>
  <li>The component code is listed below, with explanation after that</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">@</span><span class="nd">Component</span><span class="p">({</span>
  <span class="na">standalone</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
  <span class="na">imports</span><span class="p">:</span> <span class="p">[</span>
    <span class="nx">CommonModule</span><span class="p">,</span>
    <span class="nx">HttpClientModule</span><span class="p">,</span>
    <span class="nx">RouterModule</span><span class="p">,</span>
    <span class="nx">MatTabsModule</span><span class="p">,</span>
    <span class="nx">TodoListComponent</span><span class="p">,</span>
  <span class="p">],</span>
  <span class="na">selector</span><span class="p">:</span> <span class="dl">"</span><span class="s2">nx-todo-app-root</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">templateUrl</span><span class="p">:</span> <span class="dl">"</span><span class="s2">./app.component.html</span><span class="dl">"</span><span class="p">,</span>
<span class="p">})</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">AppComponent</span> <span class="p">{</span>
  <span class="nx">title</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">todo</span><span class="dl">"</span><span class="p">;</span>
  <span class="nx">allTasks$</span><span class="p">:</span> <span class="nx">Observable</span><span class="o">&lt;</span><span class="nx">ToDo</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="nx">activeTasks$</span><span class="p">:</span> <span class="nx">Observable</span><span class="o">&lt;</span><span class="nx">ToDo</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="nx">completedTasks$</span><span class="p">:</span> <span class="nx">Observable</span><span class="o">&lt;</span><span class="nx">ToDo</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">;</span>

  <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">store</span><span class="p">:</span> <span class="nx">Store</span><span class="o">&lt;</span><span class="nx">AppState</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="nx">loadTasks</span><span class="p">());</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">allTasks$</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">select</span><span class="p">((</span><span class="nx">state</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">state</span><span class="p">.</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">tasks</span><span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">activeTasks$</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">allTasks$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
      <span class="c1">// Filter active tasks</span>
      <span class="nx">map</span><span class="p">((</span><span class="nx">tasks</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">tasks</span><span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="o">!</span><span class="nx">task</span><span class="p">.</span><span class="nx">done</span><span class="p">))</span>
    <span class="p">);</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">completedTasks$</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">allTasks$</span><span class="p">.</span><span class="nx">pipe</span><span class="p">(</span>
      <span class="c1">// Filter completed tasks</span>
      <span class="nx">map</span><span class="p">((</span><span class="nx">tasks</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">tasks</span><span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">task</span><span class="p">.</span><span class="nx">done</span><span class="p">))</span>
    <span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li><strong>title</strong> shows the app’s name</li>
  <li>We inject the store in our app’s constructor and dispatch(call) the <strong>loadTasks</strong> action so the relevant effect is triggered, and API call is triggered.
    <blockquote>
      <p>Make sure the backend is running before running your Angular app. (Hint: Execute <code class="language-plaintext highlighter-rouge">nx serve api</code> to get APIs up &amp; running).</p>
    </blockquote>
  </li>
  <li>
    <p>We create 3 observables to store the tasks -</p>

    <ul>
      <li><strong>allTasks$</strong> - Gets all tasks</li>
      <li><strong>activeTasks$</strong> - Filters tasks having done as false</li>
      <li><strong>completedTasks$</strong> - Filters tasks with done as true</li>
    </ul>
  </li>
  <li>These observables are subscribed in the template using async and relevant data is displayed in all the 3 tabs.</li>
</ul>

<p>This marks the end of our application. You should have the complete application running now. Use <code class="language-plaintext highlighter-rouge">nx serve todo</code> to run the UI application. Try playing by adding/updating or deleting tasks, and see the network call happening in your browser with data.</p>

<hr />

<h2 id="code">Code</h2>

<p>Get complete code at <a href="https://github.com/msindev/nx-todo-app">msindev/nx-todo-app</a></p>

<hr />

<p>Feel free to add suggestions/questions in the comment box below if you are stuck anywhere in the tutorial.</p>]]></content><author><name>Mohit Singh</name><email>mohit@penguincoders.net</email></author><category term="blog" /><summary type="html"><![CDATA[In this post, we will be creating a fully functional ToDo application in a Nx monorepo, using Angular for Frontend and NestJs for Backend. The ToDo app will also provide Angular’s state management using NgRx. Our frontend app will be using Tailwind to style our components.]]></summary></entry></feed>