<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohit Singh</title>
    <description>The latest articles on DEV Community by Mohit Singh (@msindev).</description>
    <link>https://dev.to/msindev</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%2F498625%2F961a2fd7-7196-4ef0-9654-e6baf2f30c10.jpg</url>
      <title>DEV Community: Mohit Singh</title>
      <link>https://dev.to/msindev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/msindev"/>
    <language>en</language>
    <item>
      <title>Singleton Design Pattern in Java</title>
      <dc:creator>Mohit Singh</dc:creator>
      <pubDate>Tue, 10 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/msindev/singleton-design-pattern-in-java-13j7</link>
      <guid>https://dev.to/msindev/singleton-design-pattern-in-java-13j7</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;A Singleton design pattern makes sure that the class has a single instance, and provides access to that class globally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why would a Singleton pattern be needed at all?
&lt;/h3&gt;

&lt;p&gt;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 -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creating a Database connection pool&lt;/strong&gt; - A Singleton class can be used to manage a single access point to DB pool, and limit number of connections to database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logging Service&lt;/strong&gt; - 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration Management&lt;/strong&gt; - 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.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How do we implement a Singleton?
&lt;/h3&gt;

&lt;p&gt;To implement a Singleton class, there are 2 steps to implement it -&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Singleton Implementation in JAVA
&lt;/h3&gt;

&lt;p&gt;We will implement a very basic Lazy initialization Singleton class which will have a private constructor, and a static method to get its instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Singleton {
    private static Singleton instance;

    //Private constructor
    private Singleton(){
    }

    //Lazy initialization
    public static Singleton getInstance(){
        //If not already initialized, create a new instance, else return the existing instance
        if(instance == null)
            instance = new Singleton();
        return instance;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SingletonDemo{
    public static void main(String[] args){
        //We can refer to the instance by calling its getInstance method.
        //We don't need Singleton singleton = new Singleton(), so a single copy is used globally.
        Singleton singleton = Singleton.getInstance();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 -&lt;/p&gt;

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

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

&lt;p&gt;To make this happen, following changes should be made to the Singleton class.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declare the Singleton instance as &lt;strong&gt;volatile&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static volatile Singleton instance

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;While checking if instance is null, and creating a new instance, make it &lt;strong&gt;synchronized&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The complete example with thread safe DCL Singleton class is given below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class DCLSingleton {
    private static volatile DCLSingleton instance;

    //Private constructor
    private DCLSingleton(){
    }

    //Lazy initialization
    public static DCLSingleton getInstance(){
        if (instance == null) { // First check (no locking)
            synchronized (Singleton.class) { // Locking
                if (instance == null) { // Second check (with locking)
                    instance = new DCLSingleton();
                }
            }
        }
        return instance;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Potential downsides of Singleton pattern
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;There could be global state issues.&lt;/li&gt;
&lt;li&gt;Unit testing can be difficult as singleton have global state, so we need to mock it correctly.&lt;/li&gt;
&lt;li&gt;Improper implementation of singleton can cause issues in a multi threaded environment.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>blog</category>
    </item>
    <item>
      <title>Creating a ToDo App with Angular, NestJS, and NgRx in a Nx Monorepo</title>
      <dc:creator>Mohit Singh</dc:creator>
      <pubDate>Tue, 02 Apr 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/msindev/creating-a-todo-app-with-angular-nestjs-and-ngrx-in-a-nx-monorepo-3dcl</link>
      <guid>https://dev.to/msindev/creating-a-todo-app-with-angular-nestjs-and-ngrx-in-a-nx-monorepo-3dcl</guid>
      <description>&lt;p&gt;In this post, we will be creating a fully functional ToDo application in an Nx monorepo, using Angular for Frontend and NestJs for Backend. The ToDo app will also provide Angular’s state management using NgRx. Our front-end app will be using Tailwind to style our components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--scjq0IDN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/todo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--scjq0IDN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/todo.png" alt="ToDo App" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s proceed to setting up our project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Set Up Nx MonoRepo with Angular and NestJS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a new Nx workspace using the latest Nx version &lt;code&gt;npx create-nx-workspace@latest&lt;/code&gt; and follow the on-screen instructions by choosing Angular project. Your end result should look something like this&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VvauvTSW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/nx-monorepo-generation-screen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VvauvTSW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/nx-monorepo-generation-screen.png" alt="Nx MonoRepo Generation Terminal Window" width="800" height="672"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, add NestJs to your monorepo in your monorepo’s directory using &lt;code&gt;nx add @nx/nest&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new NestJs app that will keep our backend APIs in the monorepo using &lt;code&gt;nx g @nx/nest:app apps/api --frontendProject todo&lt;/code&gt; which will generate 2 folders &lt;strong&gt;api&lt;/strong&gt; and &lt;strong&gt;api-e2e&lt;/strong&gt;. Our APIs will be present in the &lt;em&gt;apps/api&lt;/em&gt; folder. It will also add a &lt;code&gt;proxy.conf.json&lt;/code&gt; in the &lt;em&gt;apps/todo&lt;/em&gt; folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After the frontend and api apps have been installed, the folder structure should look something like below&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TU2cUSce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/nx-api-frontend-folder-structure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TU2cUSce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/nx-api-frontend-folder-structure.png" alt="Application Folder Structure" width="800" height="1008"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 2 - Create APIs in NestJS App
&lt;/h3&gt;

&lt;p&gt;We will be creating an 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.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install the Swagger dependency through &lt;code&gt;npm install --save @nestjs/swagger&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After your dependencies have been installed, add the Swagger configuration to your &lt;em&gt;apps/api/src/main.ts&lt;/em&gt; file. Below is the &lt;em&gt;main.ts&lt;/em&gt; file after adding configuration.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Logger } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { AppModule } from "./app/app.module";

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

bootstrap();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You should now have OpenAPI empty documentation ready. To view the Swagger docs in your browser, start the API server using &lt;code&gt;nx serve api&lt;/code&gt; and browse to &lt;a href="http://localhost:3000/api"&gt;http://localhost:3000/api&lt;/a&gt; and you should see the below image&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EqJd77TF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/empty-swagger-nestjs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EqJd77TF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/empty-swagger-nestjs.png" alt="Empty Swagger API Documentation" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let’s write the API services and controllers. Before that, we will add a new library that will hold our models and interfaces for our ToDo object. Generate a new library in Nx workspace using the command &lt;code&gt;nx g @nx/js:library --name=types --bundler=none --directory=libs/types --projectNameAndRootFormat=as-provided&lt;/code&gt; or use the Nx Console to generate a &lt;code&gt;@nx/js&lt;/code&gt; library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the newly generated lib, go to &lt;code&gt;libs/types/src/lib/types.ts&lt;/code&gt; file and add the DTOs and model for our ToDo object.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ApiProperty } from "@nestjs/swagger";

export class ToDoDto {
  @ApiProperty({ description: "Task" })
  task!: string;
}

export interface ToDo extends ToDoDto {
  id: string;
  done: boolean;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;ToDoDto&lt;/strong&gt; is used to transfer via REST, and &lt;strong&gt;ToDo&lt;/strong&gt; interface stores additional properties indicating id and status.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Once your &lt;em&gt;types&lt;/em&gt; 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;File&lt;/strong&gt; : &lt;code&gt;apps/api/src/app/app.service.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable, NotFoundException } from "@nestjs/common";
import { ToDo, ToDoDto } from "@nx-todo-app/types";

@Injectable()
export class AppService {
  todos: ToDo[] = [];

  getAllToDos() {
    return this.todos;
  }

  addToDo(todoDto: ToDoDto) {
    const todo: ToDo = { id: String(Date.now()), done: false, ...todoDto };
    this.todos.push(todo);
    return { message: "ToDo successfully added" };
  }

  getActiveToDos() {
    return this.todos.filter((todo) =&amp;gt; !todo.done);
  }

  getCompletedToDos() {
    return this.todos.filter((todo) =&amp;gt; todo.done);
  }

  updateToDo(id: string, done: boolean) {
    const todo = this.todos.find((todo) =&amp;gt; todo.id === id);
    if (todo) {
      todo.done = done ?? todo.done;
      return { message: `ToDo with ID ${id} updated successfully` };
    } else {
      throw new NotFoundException(`ToDo with ID ${id} not found`);
    }
  }

  deleteToDo(id: string) {
    const todoIndex = this.todos.findIndex((todo) =&amp;gt; todo.id === id);
    if (todoIndex === -1) {
      throw new NotFoundException(`ToDo with ID ${id} not found`);
    }
    this.todos.splice(todoIndex, 1);
    return { message: `ToDo with ID ${id} deleted successfully` };
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;p&gt;&lt;strong&gt;File&lt;/strong&gt; : &lt;code&gt;apps/api/src/app/app.controller.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ApiTags("tasks")
@Controller("/v1/tasks")
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  @ApiOperation({ summary: "Get all ToDos" })
  @ApiResponse({
    status: 200,
    description: "Returns an array of ToDos",
    isArray: true,
  })
  getAllToDos() {
    return this.appService.getAllToDos();
  }

  @Post()
  @ApiOperation({ summary: "Add a new ToDo" })
  @ApiBody({ type: ToDoDto })
  @ApiResponse({ status: 201, description: "ToDo successfully added" })
  addToDo(@Body() todo: ToDoDto) {
    return this.appService.addToDo(todo);
  }

  @Put(":id/done")
  @ApiOperation({ summary: "Update the status of a ToDo" })
  @ApiParam({ name: "id", description: "ToDo ID" })
  @ApiBody({ schema: { properties: { done: { type: "boolean" } } } })
  @ApiResponse({ status: 200, description: "ToDo updated successfully" })
  updateStatus(@Param("id") id: string, @Body("done") done: boolean) {
    return this.appService.updateToDo(id, done);
  }

  @Delete(":id")
  @ApiOperation({ summary: "Delete a ToDo" })
  @ApiParam({ name: "id", description: "ToDo ID" })
  @ApiResponse({ status: 200, description: "ToDo deleted successfully" })
  deleteToDo(@Param("id") id: string) {
    return this.appService.deleteToDo(id);
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;nx serve api&lt;/code&gt; and browse to &lt;a href="http://localhost:3000/api"&gt;http://localhost:3000/api&lt;/a&gt;, and you should have all the APIs ready. Go and Try it yourself using cURL or Postman. The OpenAPI Schema should look like &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v7dM3AwD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/swagger-with-apis-nestjs.png" alt="Swagger API Documentation" width="800" height="686"&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 3 - Generate OpenAPI Services for Angular
&lt;/h3&gt;

&lt;p&gt;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 _ &lt;strong&gt;OpenAPI Generator CLI&lt;/strong&gt; _ tool available.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install the OpenAPI Generator by - &lt;code&gt;npm install @openapitools/openapi-generator-cli -g&lt;/code&gt;. This will globally install the openapi-generator-cli in your machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will create a new library to hold our OpenAPI generated services. Create a new lib using &lt;code&gt;nx g @nx/js:library --name=openapi-generated --bundler=none --directory=libs/openapi-generated --projectNameAndRootFormat=as-provided&lt;/code&gt; and delete the 2 files &lt;strong&gt;openapi_generated.ts&lt;/strong&gt; and &lt;strong&gt;openapi_generated.spec.ts&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, we will run the command to populate our Typescript client service - &lt;code&gt;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&lt;/code&gt;. This wil generate a bunch of files including &lt;strong&gt;model&lt;/strong&gt; and &lt;strong&gt;api&lt;/strong&gt;. You can browse to see the ToDoDto model among others and the todo service file generated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You should have the following openapi-generated library as shown in below picture. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sYpGKiZn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/openapi-generated-typescript.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sYpGKiZn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/openapi-generated-typescript.png" alt="OpenAPI Generated Client Library" width="500" height="752"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One final step, update the &lt;code&gt;libs/openapi-generated/src/index.ts&lt;/code&gt; file to include our APIs.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export * from "./lib/api/api"; //This will allow the APIs to be exposed.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have completed coding our backend, and will move now to code our UI in Angular. &lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExam1lc3RtZ3hkb2x6Y3NhcW8wYnQ4eGlvZzhsNnZ3c2Jvcm16Ym45aCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/a0h7sAqON67nO/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExam1lc3RtZ3hkb2x6Y3NhcW8wYnQ4eGlvZzhsNnZ3c2Jvcm16Ym45aCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/a0h7sAqON67nO/giphy.gif" alt="Success GIPHY Meme" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 4 - Add Angular Material and Tailwind CSS Libraries
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We will be using Angular Material and Tailwind for our frontend app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Angular Material in your project using the command &lt;code&gt;npx nx g @angular/material:ng-add --project=todo&lt;/code&gt; and use the below image as reference to choose your options. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hg-q4wXk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/angular-material-setup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hg-q4wXk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/angular-material-setup.png" alt="Angular Material Options" width="800" height="206"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://tailwindcss.com/"&gt;Tailwind CSS&lt;/a&gt; using &lt;code&gt;npx nx g @nx/angular:setup-tailwind todo&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 5 - Add Store for ToDo App (Actions, Reducers, and Effects)
&lt;/h3&gt;

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

&lt;p&gt;In our app, we will be using the Global Store state management.&lt;/p&gt;

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

&lt;h4&gt;
  
  
  Actions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Let’s begin by writing our first action to load all the tasks.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Load Tasks
export const loadTasks = createAction("[Todo] Load Tasks");
export const loadTasksSuccess = createAction(
  "[Todo] Load Tasks Success",
  props&amp;lt;{ tasks: ToDo[] }&amp;gt;()
);
export const loadTasksFailure = createAction(
  "[Todo] Load Tasks Failure",
  props&amp;lt;{ error: unknown }&amp;gt;()
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Similarly, we will write the actions for all other CRUD operations
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Add Task
export const addTask = createAction("[Todo] Add Task", props&amp;lt;{ task: ToDo }&amp;gt;());
export const addTaskSuccess = createAction(
  "[Todo] Add Task Success",
  props&amp;lt;{ task: ToDo }&amp;gt;()
);
export const addTaskFailure = createAction(
  "[Todo] Add Task Failure",
  props&amp;lt;{ error: unknown }&amp;gt;()
);

// Update Task Status
export const updateTaskStatus = createAction(
  "[Todo] Update Task Status",
  props&amp;lt;{ id: string; done: boolean }&amp;gt;()
);
export const updateTaskStatusSuccess = createAction(
  "[Todo] Update Task Status Success",
  props&amp;lt;{ id: string; done: boolean }&amp;gt;()
);
export const updateTaskStatusFailure = createAction(
  "[Todo] Update Task Status Failure",
  props&amp;lt;{ error: unknown }&amp;gt;()
);

// Delete Task
export const deleteTask = createAction(
  "[Todo] Delete Task",
  props&amp;lt;{ id: string }&amp;gt;()
);
export const deleteTaskSuccess = createAction(
  "[Todo] Delete Task Success",
  props&amp;lt;{ id: string }&amp;gt;()
);
export const deleteTaskFailure = createAction(
  "[Todo] Delete Task Failure",
  props&amp;lt;{ error: unknown }&amp;gt;()
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h4&gt;
  
  
  Reducers
&lt;/h4&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;em&gt;todo.reducer.ts&lt;/em&gt; file, create the AppState and TodoState.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface AppState {
  tasks: TodoState;
}
export interface TodoState {
  tasks: ToDo[]; //List of tasks retrieved from API
  loading: boolean; //To show loader on screen
  error: unknown; //Sets to error object for any API failures
}

const initialState: TodoState = {
  tasks: [],
  loading: false,
  error: null,
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const todoReducer = createReducer(
  initialState,

  on(TodoActions.loadTasks, (state) =&amp;gt; ({
    ...state,
    loading: true,
    error: null,
  })),

  on(TodoActions.loadTasksSuccess, (state, { tasks }) =&amp;gt; ({
    ...state,
    tasks: [...tasks],
    loading: false,
  })),

  on(TodoActions.loadTasksFailure, (state, { error }) =&amp;gt; ({
    ...state,
    loading: false,
    error,
  })),

  on(TodoActions.addTaskSuccess, (state, { task }) =&amp;gt; ({
    ...state,
    tasks: [...state.tasks, task],
  })),

  on(TodoActions.updateTaskStatusSuccess, (state, { id, done }) =&amp;gt; ({
    ...state,
    tasks: state.tasks.map((task) =&amp;gt;
      task.id === id ? { ...task, done } : task
    ),
  })),

  on(TodoActions.deleteTaskSuccess, (state, { id }) =&amp;gt; ({
    ...state,
    tasks: state.tasks.filter((task) =&amp;gt; task.id !== id),
  }))
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h4&gt;
  
  
  Effects
&lt;/h4&gt;

&lt;p&gt;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.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;loadTasks$ = createEffect(() =&amp;gt;
  this.actions$.pipe(
    ofType(TodoActions.loadTasks),
    mergeMap(() =&amp;gt;
      this.todoService.appControllerGetAllToDos().pipe(
        map((tasks) =&amp;gt; TodoActions.loadTasksSuccess({ tasks })),
        catchError((error) =&amp;gt; of(TodoActions.loadTasksFailure({ error })))
      )
    )
  )
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;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 &lt;strong&gt;TodoActions.loadTasksSuccess&lt;/strong&gt; 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 &lt;strong&gt;TodoActions.loadTasksFailure&lt;/strong&gt; is called with the error sent as prop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Here is the complete file with other effects for Add Task, Update Task, and Delete Task.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from "@angular/core";
import { Actions, createEffect, ofType } from "@ngrx/effects";
import { mergeMap, map, catchError, of } from "rxjs";
import * as TodoActions from "./todo.actions";
import { TasksService } from "@nx-todo-app/openapi-generated";

@Injectable()
export class TodoEffects {
  constructor(private actions$: Actions, private todoService: TasksService) {}

  loadTasks$ = createEffect(() =&amp;gt;
    this.actions$.pipe(
      ofType(TodoActions.loadTasks),
      mergeMap(() =&amp;gt;
        this.todoService.appControllerGetAllToDos().pipe(
          map((tasks) =&amp;gt; TodoActions.loadTasksSuccess({ tasks })),
          catchError((error) =&amp;gt; of(TodoActions.loadTasksFailure({ error })))
        )
      )
    )
  );

  addTask$ = createEffect(() =&amp;gt;
    this.actions$.pipe(
      ofType(TodoActions.addTask),
      mergeMap(({ task }) =&amp;gt;
        this.todoService.appControllerAddToDo(task).pipe(
          map((addedTask) =&amp;gt; TodoActions.addTaskSuccess({ task: addedTask })),
          catchError((error) =&amp;gt; of(TodoActions.addTaskFailure({ error })))
        )
      )
    )
  );

  updateTaskStatus$ = createEffect(() =&amp;gt;
    this.actions$.pipe(
      ofType(TodoActions.updateTaskStatus),
      mergeMap(({ id, done }) =&amp;gt;
        this.todoService.appControllerUpdateStatus({ done }, id).pipe(
          map(() =&amp;gt; TodoActions.updateTaskStatusSuccess({ id, done })),
          catchError((error) =&amp;gt;
            of(TodoActions.updateTaskStatusFailure({ error }))
          )
        )
      )
    )
  );

  deleteTask$ = createEffect(() =&amp;gt;
    this.actions$.pipe(
      ofType(TodoActions.deleteTask),
      mergeMap(({ id }) =&amp;gt;
        this.todoService.appControllerDeleteToDo(id).pipe(
          map(() =&amp;gt; TodoActions.deleteTaskSuccess({ id })),
          catchError((error) =&amp;gt; of(TodoActions.deleteTaskFailure({ error })))
        )
      )
    )
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the final step to setup your store, we need to register the effects and store in our &lt;strong&gt;app.config.ts&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the app.config.ts file, update the providers array to change the provideEffects() and provideStore() to
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provideEffects([TodoEffects]),
provideStore({ tasks: todoReducer }),

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6 - Write the ToDo Component
&lt;/h3&gt;

&lt;p&gt;We will have a look at the UI and see that we have 2 components to build.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ukI-bvg7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/todo-component-structure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ukI-bvg7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://penguincoders.net/assets/images/2024-04-02-todo-app-in-angular-nestjs-ngrx/todo-component-structure.png" alt="ToDo App Components" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  todo component
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Generate a new component using &lt;code&gt;nx g @nx/angular:component --name=todo-list --directory=apps/todo/src/app/components/todo-list --changeDetection=OnPush --nameAndDirectoryFormat=as-provided --skipTests=true&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will be using Angular Material’s components to build our component. Add the below template file to &lt;strong&gt;todo-list.component.html&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form class="flex mt-16" (submit)="addTask(taskInput.value)"&amp;gt;
  &amp;lt;mat-form-field class="w-9/12"&amp;gt;
    &amp;lt;mat-label&amp;gt;add details&amp;lt;/mat-label&amp;gt;
    &amp;lt;input matInput #taskInput /&amp;gt;
  &amp;lt;/mat-form-field&amp;gt;
  &amp;lt;button type="submit" mat-raised-button color="primary" class="mt-2 ml-16"&amp;gt;
    Add
  &amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;

&amp;lt;ul&amp;gt;
  &amp;lt;li *ngFor="let item of tasks" class="flex items-center justify-between"&amp;gt;
    &amp;lt;mat-checkbox
      [checked]="item.done"
      (change)="updateTaskStatus(item, $event.checked)"
    &amp;gt;

    &amp;lt;/mat-checkbox&amp;gt;
    &amp;lt;button mat-icon-button color="warn" (click)="deleteTask(item.id)"&amp;gt;
      &amp;lt;mat-icon&amp;gt;delete&amp;lt;/mat-icon&amp;gt;
    &amp;lt;/button&amp;gt;
  &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;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 &lt;strong&gt;todo-list.component.ts&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component({
  selector: "nx-todo-app-todo-list",
  standalone: true,
  imports: [
    CommonModule,
    MatCheckboxModule,
    MatInputModule,
    MatButtonModule,
    MatIconModule,
  ],
  templateUrl: "./todo-list.component.html",
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TodoListComponent {
  @ViewChild("taskInput")
  taskInput!: ElementRef&amp;lt;HTMLInputElement&amp;gt;;
  @Input()
  tasks!: ToDo[] | null;

  constructor(private store: Store&amp;lt;AppState&amp;gt;) {}

  addTask(taskInput: string): void {
    if (taskInput.trim() === "") {
      return;
    }
    //Create new object for a task
    const task: ToDo = {
      id: Date.now().toString(),
      task: taskInput,
      done: false,
    };
    this.store.dispatch(addTask({ task }));
    this.taskInput.nativeElement.value = ""; //Reset input form
  }

  updateTaskStatus(task: ToDo, event: boolean): void {
    this.store.dispatch(updateTaskStatus({ id: task.id, done: event }));
  }

  deleteTask(id: string): void {
    this.store.dispatch(deleteTask({ id }));
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  app component
&lt;/h4&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head class="flex justify-center my-12"&amp;gt;
  &amp;lt;title&amp;gt;ToDo App&amp;lt;/title&amp;gt;
  &amp;lt;h1&amp;gt;#todo&amp;lt;/h1&amp;gt;
&amp;lt;/head&amp;gt;

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

&amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;The component code is listed below, with explanation after that
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component({
  standalone: true,
  imports: [
    CommonModule,
    HttpClientModule,
    RouterModule,
    MatTabsModule,
    TodoListComponent,
  ],
  selector: "nx-todo-app-root",
  templateUrl: "./app.component.html",
})
export class AppComponent {
  title = "todo";
  allTasks$: Observable&amp;lt;ToDo[]&amp;gt;;
  activeTasks$: Observable&amp;lt;ToDo[]&amp;gt;;
  completedTasks$: Observable&amp;lt;ToDo[]&amp;gt;;

  constructor(private store: Store&amp;lt;AppState&amp;gt;) {
    this.store.dispatch(loadTasks());
    this.allTasks$ = this.store.select((state) =&amp;gt; state.tasks.tasks);
    this.activeTasks$ = this.allTasks$.pipe(
      // Filter active tasks
      map((tasks) =&amp;gt; tasks.filter((task) =&amp;gt; !task.done))
    );
    this.completedTasks$ = this.allTasks$.pipe(
      // Filter completed tasks
      map((tasks) =&amp;gt; tasks.filter((task) =&amp;gt; task.done))
    );
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;title&lt;/strong&gt; shows the app’s name&lt;/li&gt;
&lt;li&gt;We inject the store in our app’s constructor and dispatch(call) the &lt;strong&gt;loadTasks&lt;/strong&gt; action so the relevant effect is triggered, and API call is triggered. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure the backend is running before running your Angular app. (Hint: Execute &lt;code&gt;nx serve api&lt;/code&gt; to get APIs up &amp;amp; running).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We create 3 observables to store the tasks -&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;These observables are subscribed in the template using async and relevant data is displayed in all three 3 tabs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This marks the end of our application. You should have the complete application running now. Use &lt;code&gt;nx serve todo&lt;/code&gt; to run the UI application. Try playing by adding/updating or deleting tasks, and see the network call happening in your browser with data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Get complete code at &lt;a href="https://github.com/msindev/nx-todo-app"&gt;msindev/nx-todo-app&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Feel free to add suggestions/questions in the comment box below if you are stuck anywhere in the tutorial.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ngrx</category>
      <category>nestjs</category>
    </item>
  </channel>
</rss>
