<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Angular - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Angular - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 10 May 2026 22:20:17 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/angular/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Realtime Chat Application with Angular 20 and Supabase ]]>
                </title>
                <description>
                    <![CDATA[ Chat applications let you talk in real-time with your friends, family, or coworkers, and help you quickly, effectively, and efficiently transfer of information. When you’re building modern web applications, chat applications are now pretty much a req... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-realtime-chat-app-with-angular-20-and-supabase/</link>
                <guid isPermaLink="false">6850913c10d2d4fd5525e0d6</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ supabase ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Frontend Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ deji adesoga ]]>
                </dc:creator>
                <pubDate>Mon, 16 Jun 2025 21:48:44 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750094888966/7ac31fee-bd4d-4353-b8cb-911ac60b4516.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Chat applications let you talk in real-time with your friends, family, or coworkers, and help you quickly, effectively, and efficiently transfer of information. When you’re building modern web applications, chat applications are now pretty much a requirement to enable collaboration and enhanced the user experience.</p>
<p>In this tutorial, we will break down how to build a chat application using modern technologies like Angular and Supabase. Building this chat application will help you learn features such as Google OAuth 2.0 for authentication, Angular router for navigation, the <code>CanActivate</code> route guard for route protection, and how to call Supabase functions to create, fetch and delete chats.</p>
<p>On the backend, you will learn how to create database tables in Supabase. You’ll also learn about Supabase functions and Supabase triggers.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-table-of-contents">Table of Contents</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-installations-and-account-configuration">Installations and Account Configuration:</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-the-user-interface-of-the-angular-application">How to Create the User Interface of the Angular Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-a-new-supabase-project">How to Set Up a New Supabase Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-google-oauth-20-for-authentication-and-authorization">How to Set Up Google OAuth 2.0 for Authentication and Authorization</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-the-router-of-the-angular-application">How to Configure the Router of the Angular Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-the-authentication-service">How to Set Up the Authentication Service</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-create-the-service-functions-for-login-and-sign-out-functionality">How to Create the Service Functions for Login and Sign Out Functionality</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-integrate-the-authentication-service-function-in-the-template">How to Integrate the Authentication Service Function in the Template</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-route-protection-in-angular">How to Create Route Protection in Angular</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-and-setup-the-users-table-in-supabase-using-the-sql-editor">How to Create and Setup the Users Table in Supabase using the SQL Editor</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-row-level-security-policies-in-supabase-with-the-sql-editor">How to Configure Row Level Security Policies in Supabase with the SQL Editor</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-supabase-functions-in-supabase-with-the-sql-editor">How to Configure Supabase Functions in Supabase with the SQL Editor</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-supabase-trigger-in-supabase-with-the-sql-editor">How to Configure Supabase Trigger in Supabase with the SQL Editor</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-and-setup-the-chat-table-in-supabase-using-the-user-interface">How to Create and Setup the Chat Table in Supabase using the User Interface</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-and-setup-the-chat-table-policies-in-supabase">How to Create and Setup the Chat Table Policies in Supabase</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-integrate-functionality-to-create-a-new-chat-message-in-the-angular-application">How to Integrate Functionality to Create a New Chat Message in the Angular Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-fetch-data-in-the-angular-application-from-supabase">How to Fetch Data in the Angular Application from Supabase</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-delete-data-in-the-angular-application">How to Delete Data in the Angular Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-logout-functionality-in-the-angular-application">How to Implement Logout Functionality in the Angular Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<ul>
<li><p>HTML</p>
</li>
<li><p>JavaScript</p>
</li>
<li><p>TypeScript</p>
</li>
</ul>
<h2 id="heading-installations-and-account-configuration"><strong>Installations and Account Configuration:</strong></h2>
<p>Before we begin, make sure you have the following installed and ready:</p>
<ul>
<li><p><strong>Node.js and npm:</strong> Angular requires Node. You can check to see if you have it (and what version you have) by running <code>node -v</code> in your terminal.</p>
</li>
<li><p><strong>Angular CLI:</strong> This is the command-line tool to scaffold and manage Angular projects. If you don’t have it, install it with <code>npm install -g @angular/cli</code>. Verify with <code>ng version</code>.</p>
</li>
<li><p><strong>A Supabase account:</strong> Supabase offers a free tier. Sign up on the <a target="_blank" href="http://supabase.com/">Supabase</a> website if you haven’t already.</p>
</li>
</ul>
<p>You can also watch the video version of this article below, or on my <a target="_blank" href="https://youtu.be/8SRhekaJ5iI?si=Vddj2ayZ0rF1R3W2">YouTube channel</a>:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/8SRhekaJ5iI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-to-create-the-user-interface-of-the-angular-application">How to Create the User Interface of the Angular Application</h2>
<p>To create the user interface of the application, we’ll use <a target="_blank" href="https://getbootstrap.com/docs/5.0/getting-started/introduction/">Bootstrap 5</a>. In the <code>index.html</code> file of the Angular application, you are going to paste the Bootstrap 5 CDN link as seen below:</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!doctype <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>NgChat<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">base</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"icon"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"image/x-icon"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"favicon.ico"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>
    <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">app-root</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-root</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"</span>
    <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"</span>
    <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Above, you have two CDN links from Bootstrap 5. The first is the <code>&lt;link&gt;</code> tag within the head section, while the second is the <code>&lt;script&gt;</code> tag which is right below the <code>&lt;app-root&gt;&lt;/app-root&gt;</code> tag.</p>
<p>Now that you have the Bootstrap 5 CDN link setup within the project, the next step is to create two new components called <strong>chat</strong> and <strong>login</strong>, respectively, within a pages folder. You can do that using the command below:</p>
<pre><code class="lang-powershell">ng g c pages/chat<span class="hljs-literal">-component</span> &amp;&amp; ng g c pages/login<span class="hljs-literal">-component</span>
</code></pre>
<p>The <code>login-component.html</code> is going to contain the code below:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"login-block"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-12"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-lg btn-google btn-block text-uppercase btn-outline"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">img</span>
            <span class="hljs-attr">src</span>=<span class="hljs-string">"https://res.cloudinary.com/dz4tt9omp/image/upload/v1712537582/google-logo.png"</span>&gt;</span> Signup Using Google<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
</code></pre>
<p>While the <code>login-component.css</code> will contain the code below:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.login-block</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">300px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
  <span class="hljs-attribute">display</span>:flex;
  <span class="hljs-attribute">justify-content</span>:center;
  <span class="hljs-attribute">align-items</span>:center;
  <span class="hljs-attribute">height</span>:<span class="hljs-number">100vh</span>;
}

<span class="hljs-selector-class">.btn</span> {
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;
  <span class="hljs-attribute">text-transform</span>: capitalize;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">15px</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span> <span class="hljs-number">19px</span>;
  <span class="hljs-attribute">cursor</span>: pointer
}


<span class="hljs-selector-class">.btn-google</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#545454</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ffffff</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">1px</span> <span class="hljs-number">2px</span> <span class="hljs-number">1px</span> <span class="hljs-number">#ddd</span>;
}
</code></pre>
<p>To see how the user interface looks, you can call the <code>&lt;app-login /&gt;</code> tag with the <code>app.component.html</code> file, since the route navigations have not yet been configured. The user interface should look like the screenshot below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746232060227/98f18b59-d433-486b-adbe-f28302e8d901.png" alt="Screenshot of a web page running on localhost at port 4200. The page displays a centered white background with a single button labeled &quot;SIGNUP USING GOOGLE&quot; that includes a Google logo icon. The button is slightly elevated with a shadow effect." class="image--center mx-auto" width="1920" height="951" loading="lazy"></p>
<h2 id="heading-how-to-set-up-a-new-supabase-project">How to Set Up a New Supabase Project</h2>
<p>To set up Supabase, you will need to create a new account on <a target="_blank" href="https://supabase.com/">Supabase.com</a> by using either a GitHub account, or the traditional email and password. Once you’ve done this, you will be presented with a form to create a new organization as you can see in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747178536860/972076bf-ae5e-4b33-b18c-011e1e63b3a0.png" alt="Supabase form to create a new organization with name, type, and plan fields." class="image--center mx-auto" width="1920" height="892" loading="lazy"></p>
<p>The organization will be created as fast as your internet speed. Once that is done, the next form you’ll see will allow you to create a new Supabase project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747180463389/a41cd54d-4514-4a8b-8230-a348723b0a2f.png" alt="Supabase interface for creating a new project, showing fields for organization, project name, database password, and region selection." class="image--center mx-auto" width="1910" height="890" loading="lazy"></p>
<p>As you can see from the image above, all you need to do to create a new project is to set a database password and select a region close to where you think most of your users will be. This will help reduce latency. With that you can now click on the create button to create a new project.</p>
<p>Once the project creation is complete, you will be navigated to the dashboard below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747180885966/b9b89775-36cb-49e8-a596-c5ae4bad75a7.png" alt="Supabase dashboard showing a new project with no tables and a task list in progress." class="image--center mx-auto" width="1920" height="891" loading="lazy"></p>
<p>With that, you have now set up your new Supabase project.</p>
<h2 id="heading-how-to-set-up-google-oauth-20-for-authentication-and-authorization">How to Set Up Google OAuth 2.0 for Authentication and Authorization</h2>
<p>To set up Google OAuth 2.0, you need to create an account on <a target="_blank" href="https://console.cloud.google.com">Google Cloud Console</a>. Once you create an account, you will be navigated to the dashboard, where you can create a new project by clicking on the select project button on the top left-hand side of the dashboard.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747353793461/b42cd8f9-5a6c-4579-be15-074f9bf90e13.png" alt="Google Cloud console welcome page showing a $300 free credit offer. A 'Select a project' button is highlighted near the top." class="image--center mx-auto" width="1912" height="932" loading="lazy"></p>
<p>Once you’ve selected the newly created project, you can now begin implementing Google OAuth 2.0 by following these steps:</p>
<ul>
<li><p>Click on the hamburger menu on the left-hand side of the dashboard and hover over <strong>APIs and services.</strong></p>
</li>
<li><p>Click on <strong>Credentials</strong>, on the Credentials page, select <strong>Create Credentials</strong> at the top menu of the dashboard. A dropdown menu will appear. Select <strong>Create OAuth client ID</strong>.</p>
</li>
<li><p>On the Client ID page, you’ll get a warning message that says “To create an OAuth client ID, you must first configure your consent screen.” Click on the <strong>Configure consent screen</strong> button.</p>
</li>
</ul>
<p>Next, you’ll be directed to the Branding page. Click on the getting Started button, and you’ll be presented with a form on the overview page as you can see below. Then just fill out the form:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747358499033/47c07eda-9b1e-45ce-ae0b-bb478178a0a2.png" alt="Google Cloud console showing the 'Create branding' page under the Google Auth Platform. The user is filling out app information, including app name and support email, as part of the project configuration steps." class="image--center mx-auto" width="1916" height="885" loading="lazy"></p>
<p>You can now create the OAuth Consent Screen by heading to the Clients tab on the left-side of the dashboard and filling out the details for your application type, the name of your OAuth 2.0 client, as well as the Authorized JavaScript origins.</p>
<p>For the Authorized JavaScript origins, you can enter the URL (<a target="_blank" href="http://localhost:4200">http://localhost:4200</a>), since that is the development URL for our Angular application. Then click on the create button. You may get a warning saying “Note: It may take five minutes to a few hours for settings to take effect.”</p>
<p>Once the configuration is complete, you will get a modal that contains a Client ID and a Client Secret, as you can see below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747361106624/6ba6ed98-469a-4154-9d47-6719d982176e.png" alt="A Google Cloud OAuth client creation dialog displays the Client ID, Client secret, creation date, status as enabled, and a warning about downloading credentials before June 2025." class="image--center mx-auto" width="1918" height="884" loading="lazy"></p>
<p>Make sure you copy the Client ID and Client secret, as you will use this in the Supabase dashboard.</p>
<p>To complete the authentication and authorization setup, head to the Supabase dashboard. Then navigate to the Authentication menu, which is located in the items on the left-side of the dashboard. On this part of the dashboard, you will select <strong>Sign In / Providers</strong>.</p>
<p>On the Sign In / Providers page, scroll down to the <strong>Auth Providers</strong>, then select and enable <strong>Google</strong>. This is where you will paste in the credentials of the Client ID and Client Secret created on the <strong>Google Cloud Console</strong>. Then click on the save button – and make sure you copy the Callback URL (for OAuth).</p>
<p>The final step in this process is to head back to the GCP dashboard, and under the Clients tab, click on the edit icon of the OAuth 2.0 Client IDs you created previously.</p>
<p>Under the Authorized redirect URIs, click on the Add URI button. An input box will appear. Paste in the link of the Callback URL (for OAuth) you grabbed in the Supabase dashboard and click save.</p>
<h2 id="heading-how-to-configure-the-router-of-the-angular-application">How to Configure the Router of the Angular Application</h2>
<p>Earlier in this tutorial, you created two components: Chat and Login. At this point, you need to setup the route configuration in the <code>app.routes.ts</code>. In this file, add the code below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Routes } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> routes: Routes = [
  {
    path: <span class="hljs-string">'chat'</span>,
    loadComponent: <span class="hljs-function">() =&gt;</span>
      <span class="hljs-keyword">import</span>(<span class="hljs-string">'./pages/chat/chat-component'</span>).then(<span class="hljs-function">(<span class="hljs-params">com</span>) =&gt;</span> com.ChatComponent),
  },
  {
    path: <span class="hljs-string">'login'</span>,
    loadComponent: <span class="hljs-function">() =&gt;</span>
      <span class="hljs-keyword">import</span>(<span class="hljs-string">'./pages/login/login-component'</span>).then(<span class="hljs-function">(<span class="hljs-params">com</span>) =&gt;</span> com.LoginComponent),
  },
  {
    path: <span class="hljs-string">''</span>,
    loadComponent: <span class="hljs-function">() =&gt;</span>
      <span class="hljs-keyword">import</span>(<span class="hljs-string">'./pages/login/login-component'</span>).then(<span class="hljs-function">(<span class="hljs-params">com</span>) =&gt;</span> com.LoginComponent),
  },
];
</code></pre>
<p>Above, you can see the two components now have their separate routes called <strong>chat</strong> and <strong>login</strong>, respectively. They can be accessed anywhere in the application.</p>
<h2 id="heading-how-to-set-up-the-authentication-service">How to Set Up the Authentication Service</h2>
<p>To setup the authentication service in the Angular application, use the following command:</p>
<pre><code class="lang-bash">ng g s services/auth-service
</code></pre>
<p>Next, you’ll generate the environments folders to setup the environment variables using the below command:</p>
<pre><code class="lang-bash">ng g environments
</code></pre>
<p>The final configuration you need to do from the terminal before you begin creating the function for the Angular authentication service is to install Supabase with the command below:</p>
<pre><code class="lang-bash">npm i @supabase/supabase-js
</code></pre>
<p>And with that, you now have Supabase installed in the project and you can begin integrating the functions in the service. Start from the <code>environment.development.ts</code> file<strong>.</strong> The current structure of this file should look this way by default:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> environment = {};
</code></pre>
<p>To configure this file, you need to head to the Supabase dashboard. Locate and select the settings menu on the left hand panel of the dashboard. Under the <strong>Configuration</strong> tab, click on Data API.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747569518560/94ae00c7-4f62-4cc7-a0f9-250088754acb.png" alt="Screenshot of Supabase API settings, showing the project URL and API keys section with arrows pointing to the URL and keys, plus buttons to copy each credential." class="image--center mx-auto" width="1918" height="886" loading="lazy"></p>
<p>You can now grab both the Project URL and anon public key (the arrow is pointing to it in the image above). You can now head over to the <code>environment.development.ts</code> file and paste in the values of the copied link following the format below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> environment = {
  production: <span class="hljs-literal">false</span>,
  supabaseUrl: <span class="hljs-string">'https://zktqzszvllbxvjfzkhvk.supabase.co'</span>,
  supabaseKey:
    <span class="hljs-string">'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InprdHF6c3p2bGxieHZqZnpraHZrIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDcyNTg3MDgsImV4cCI6MjA2MjgzNDcwOH0.qf3MA-La6se8QijzLFALKc_XdiISmzDk7AZw4-na0uA'</span>,
};
</code></pre>
<p>With the environment variables all in place, you can now create the functions for the authentication service.</p>
<p>In the <code>auth-service.ts</code> which you created previously, start by importing the Supabase package as well as the environments file as you can see below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { SupabaseClient, createClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@supabase/supabase-js'</span>;
<span class="hljs-keyword">import</span> { environment } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../environments/environment.development'</span>;
</code></pre>
<p>Next, complete the injection of the Supabase <code>npm</code> package by injecting it into your constructor:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { SupabaseClient, createClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@supabase/supabase-js'</span>;
<span class="hljs-keyword">import</span> { environment } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../environments/environment.development'</span>;

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthService {
  supabase!: SupabaseClient;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
      <span class="hljs-built_in">this</span>.supabase = createClient(
      environment.supabaseUrl,
      environment.supabaseKey
    );
  }
}
</code></pre>
<h3 id="heading-how-to-create-the-service-functions-for-login-and-sign-out-functionality">How to Create the Service Functions for Login and Sign Out Functionality</h3>
<p>The final step in setting up the <code>Auth</code>service is to create the functions which will later be called in the template. You are going to create four functions which you can see in the code below:</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">private</span> router = inject(Router);
  <span class="hljs-keyword">private</span> _ngZone = inject(NgZone);

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.supabase = createClient(
      environment.supabaseUrl,
      environment.supabaseKey
    );

    <span class="hljs-built_in">this</span>.supabase.auth.onAuthStateChange(<span class="hljs-function">(<span class="hljs-params">event, session</span>) =&gt;</span> {

      <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'session'</span>, <span class="hljs-built_in">JSON</span>.stringify(session?.user));

      <span class="hljs-keyword">if</span> (session?.user) {
        <span class="hljs-built_in">this</span>._ngZone.run(<span class="hljs-function">() =&gt;</span> {
          <span class="hljs-built_in">this</span>.router.navigate([<span class="hljs-string">'/chat'</span>]);
        });
      }
    });
  }

  get isLoggedIn(): <span class="hljs-built_in">boolean</span> {
    <span class="hljs-keyword">const</span> user = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'session'</span>) <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>;

    <span class="hljs-keyword">return</span> user === <span class="hljs-string">'undefined'</span> ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>;
  }

  <span class="hljs-keyword">async</span> signInWithGoogle() {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase.auth.signInWithOAuth({
      provider: <span class="hljs-string">'google'</span>,
    });
  }

  <span class="hljs-keyword">async</span> signOut() {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase.auth.signOut();
  }
}
</code></pre>
<p>The first function created is within the constructor. This is the <code>onAuthStateChange</code> callback function which is derived from Supabase and allows us to listen to Auth changes. It accepts two parameters called <code>event</code> and <code>session</code>.</p>
<p>Here, two conditions were instantiated within the <code>onAuthStateChange</code> callback function. They say that when the <code>session?.user</code> exists, you proceed to set the value to the local storage, and then navigate the user to the dashboard using the Angular router (which has been imported and injected using the <code>inject()</code> function).</p>
<p>The second function, <code>isLoggedIn()</code>, is a getter function that returns a Boolean. It returns either true or false, depending on if it is able to retrieve the user session from <code>localStorage</code>. This function will be used in the authentication guard which you’ll create later.</p>
<p>The third function, <code>signInWithGoogle()</code>, allows the user log into the dashboard using the <code>signInWithOAuth()</code> method provided by Supabase. This allows the user to log into the dashboard using a Google Gmail account.</p>
<p>The final function, <code>signOut()</code>, allows users to logout of the dashboard by resetting the state of the user session to null.</p>
<p>With all these functions created, the final code base in the <code>auth-service.ts</code> should look like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable, NgZone, inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { SupabaseClient, createClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@supabase/supabase-js'</span>;
<span class="hljs-keyword">import</span> { environment } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../environments/environment.development'</span>;
<span class="hljs-keyword">import</span> { Router } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthService {
  <span class="hljs-keyword">private</span> supabase!: SupabaseClient;

  <span class="hljs-keyword">private</span> router = inject(Router);
  <span class="hljs-keyword">private</span> _ngZone = inject(NgZone);
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.supabase = createClient(
      environment.supabaseUrl,
      environment.supabaseKey
    );

    <span class="hljs-built_in">this</span>.supabase.auth.onAuthStateChange(<span class="hljs-function">(<span class="hljs-params">event, session</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'event'</span>, event);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'session'</span>, session);

      <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'session'</span>, <span class="hljs-built_in">JSON</span>.stringify(session?.user));

      <span class="hljs-keyword">if</span> (session?.user) {
        <span class="hljs-built_in">this</span>._ngZone.run(<span class="hljs-function">() =&gt;</span> {
          <span class="hljs-built_in">this</span>.router.navigate([<span class="hljs-string">'/chat'</span>]);
        });
      }
    });
  }

  get isLoggedIn(): <span class="hljs-built_in">boolean</span> {
    <span class="hljs-keyword">const</span> user = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'session'</span>) <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>;

    <span class="hljs-keyword">return</span> user === <span class="hljs-string">'undefined'</span> ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>;
  }

  <span class="hljs-keyword">async</span> signInWithGoogle() {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase.auth.signInWithOAuth({
      provider: <span class="hljs-string">'google'</span>,
    });
  }

  <span class="hljs-keyword">async</span> signOut() {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase.auth.signOut();
  }
}
</code></pre>
<p>You can now utilize these functions anywhere in the Angular project as a form of state management.</p>
<h3 id="heading-how-to-integrate-the-authentication-service-function-in-the-template">How to Integrate the Authentication Service Function in the Template</h3>
<p>The first function we’ll use is the <code>signInWithGoogle()</code> function. We’ll use it in the <code>login-component.ts</code> file to allow users log into the application as you can see below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { AuthService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/auth-service'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-login'</span>,
  standalone: <span class="hljs-literal">true</span>,
  imports: [],
  templateUrl: <span class="hljs-string">'./login-component.html'</span>,
  styleUrl: <span class="hljs-string">'./login-component.css'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> LoginComponent {
  <span class="hljs-keyword">private</span> auth = inject(AuthService);

  <span class="hljs-keyword">async</span> handleAuth() {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.auth.signInWithGoogle();
  }
}
</code></pre>
<p>Above, you implemented three features:</p>
<ul>
<li><p>Importing <code>AuthService</code> into the <code>LoginComponent</code></p>
</li>
<li><p>Injecting <code>AuthService</code> using the Inject function into the <code>LoginComponent</code></p>
</li>
<li><p>Creating the <code>handleAuth()</code> function that allows you call the <code>signInWithGoogle()</code> from the <code>AuthService</code> file.</p>
</li>
</ul>
<p>Now you can head to the <code>login-component.html</code> file and call the <code>handleAuth(</code>) function as below within the <code>&lt;a&gt;</code> tag:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"login-block"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-12"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"handleAuth()"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-lg btn-google btn-block text-uppercase btn-outline"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">img</span>
            <span class="hljs-attr">src</span>=<span class="hljs-string">"https://res.cloudinary.com/dz4tt9omp/image/upload/v1712537582/google-logo.png"</span>&gt;</span> Signup Using Google<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
</code></pre>
<p>Before you test the implementation, you will need to set the URL configuration in the Supabase dashboard. The URL configuration allows the URLs that authentication providers permit to redirect and post authentication, including wildcards.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748363896805/0b8f2ed1-ba45-44b9-93b8-0f470cb5ff32.png" alt="Interface displaying authentication settings, including site URL configuration and allowed redirect URLs for a web application." class="image--center mx-auto" width="1920" height="886" loading="lazy"></p>
<p>As you can see in the above image, the two Redirect URLs provided are localhost, since we are still currently creating the app in our local machine.</p>
<p>With this, you can test the Google OAuth 2.0 configuration by typing the localhost URL (<a target="_blank" href="http://localhost:4200/">http://localhost:4200</a>) in the browser, clicking on the <strong>Signup Using Google</strong> button<strong>,</strong> and selecting a Gmail account you want to sign up/login with. Then you should get navigated to the Chat component.</p>
<h2 id="heading-how-to-create-route-protection-in-angular">How to Create Route Protection in Angular</h2>
<p>To create route protection in Angular, you can use an in-built mechanism called a <strong>Route Guard</strong>. The Route Guard is used to control access to certain parts of the Angular application using certain conditions before a route is activated or accessible to the user.</p>
<p>In our case, you will be generating the Route Guard as a function (which is the default in our current version of Angular (20), instead of as a class) using the command below:</p>
<pre><code class="lang-bash">ng generate guard auth-guard
</code></pre>
<p>You will then see this prompt that asks “Which type of guard would you like to create?”:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748365560338/650c5bf7-8e1c-45cf-915b-c988c167416a.png" alt="650c5bf7-8e1c-45cf-915b-c988c167416a" class="image--center mx-auto" width="1872" height="379" loading="lazy"></p>
<p>Use the spacebar to select <code>CanActivate</code>, and then press the Enter key to generate the Guard. Two files will be generated: the <code>auth-guard.spec.ts</code> file (for testing), and the <code>auth-guard.ts</code> file. Within the <code>auth-guard.ts</code> file, you will see the boilerplate code below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { CanActivateFn } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> authGuard: CanActivateFn = <span class="hljs-function">(<span class="hljs-params">route, state</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
};
</code></pre>
<p>You can start modifying the above template by importing the Angular Router, the <code>AuthService</code> file that you created earlier, as well as the Inject function:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { CanActivateFn, Router } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { AuthService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./services/auth-service'</span>;
<span class="hljs-keyword">import</span> { inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
</code></pre>
<p>Next, use the <code>isLoggedIn</code> getter that you created earlier in the <code>AuthService</code> file (which returns a Boolean) to conditionally activate the Chat dashboard for the user based on their login status using the code below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { CanActivateFn, Router } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { AuthService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./services/auth-service'</span>;
<span class="hljs-keyword">import</span> { inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> authGuard: CanActivateFn = <span class="hljs-function">(<span class="hljs-params">route, state</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (inject(AuthService).isLoggedIn === <span class="hljs-literal">false</span>) {
    inject(Router).navigate([<span class="hljs-string">'/login'</span>]);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
};
</code></pre>
<p>To complete the Guard integration, head over to the <code>app.routes.ts</code> file and import and inject the Authentication Guard as you can see below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Routes } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { authGuard } <span class="hljs-keyword">from</span> <span class="hljs-string">'./auth-guard'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> routes: Routes = [
  {
    path: <span class="hljs-string">'chat'</span>,
    canActivate: [authGuard],
    loadComponent: <span class="hljs-function">() =&gt;</span>
      <span class="hljs-keyword">import</span>(<span class="hljs-string">'./pages/chat/chat-component'</span>).then(<span class="hljs-function">(<span class="hljs-params">com</span>) =&gt;</span> com.ChatComponent),
  },
  {
    path: <span class="hljs-string">'login'</span>,
    loadComponent: <span class="hljs-function">() =&gt;</span>
      <span class="hljs-keyword">import</span>(<span class="hljs-string">'./pages/login/login-component'</span>).then(<span class="hljs-function">(<span class="hljs-params">com</span>) =&gt;</span> com.LoginComponent),
  },
  {
    path: <span class="hljs-string">''</span>,
    loadComponent: <span class="hljs-function">() =&gt;</span>
      <span class="hljs-keyword">import</span>(<span class="hljs-string">'./pages/login/login-component'</span>).then(<span class="hljs-function">(<span class="hljs-params">com</span>) =&gt;</span> com.LoginComponent),
  },
];
</code></pre>
<p>With this, the route protection implementation is now complete and only authenticated users can view the dashboard.</p>
<h2 id="heading-how-to-create-and-setup-the-users-table-in-supabase-using-the-sql-editor">How to Create and Setup the Users Table in Supabase using the SQL Editor</h2>
<p>To create and setup the users table, use the schema below:</p>
<ul>
<li><p>id (uuid)</p>
</li>
<li><p>full_name (text)</p>
</li>
<li><p>avatar_url (text)</p>
</li>
</ul>
<p>You can use the <strong>SQL</strong> Editor in Supabase. The SQL Editor is the third item on the menu panel in the Supabase dashboard. Here you are going to type in the query below in the SQL Editor input field:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-built_in">public</span>.users (
   id <span class="hljs-type">uuid</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">null</span> <span class="hljs-keyword">references</span> auth.users <span class="hljs-keyword">on</span> <span class="hljs-keyword">delete</span> <span class="hljs-keyword">cascade</span>,
   full_name <span class="hljs-type">text</span> <span class="hljs-keyword">NULL</span>,
   avatar_url <span class="hljs-type">text</span> <span class="hljs-keyword">NULL</span>,
   <span class="hljs-keyword">primary key</span> (id)
);
</code></pre>
<p>You can now click on the Run button on the bottom right. You should get a message that says: <strong>Success. No rows returned</strong>, as you can see in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748394167618/5db26c97-a947-4233-8232-3aba72187a12.png" alt="SQL code for creating a user profile table with fields for id, full name, and avatar URL. Returns No rows returned after execution." class="image--center mx-auto" width="1918" height="885" loading="lazy"></p>
<p>Now let’s go ahead and enable row level security, as well as the Supabase function and trigger.</p>
<h3 id="heading-how-to-configure-row-level-security-policies-in-supabase-with-the-sql-editor">How to Configure Row Level Security Policies in Supabase with the SQL Editor</h3>
<p>Row Level Security (RLS) in Supabase allows you to control access to individual rows in your database tables based on custom logic. It’s one of the core features for building secure, multi-user applications with Supabase.</p>
<p>RLS lets you define SQL policies that determine which users can <code>SELECT</code>, <code>INSERT</code>, <code>UPDATE</code>, or <code>DELETE</code> specific rows in a table.</p>
<p>To enable RLS in the <strong>users</strong> table, type the command below in your SQL Editor:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-built_in">public</span>.users <span class="hljs-keyword">ENABLE</span> <span class="hljs-keyword">ROW</span> <span class="hljs-keyword">LEVEL</span> <span class="hljs-keyword">SECURITY</span>;
</code></pre>
<p>For the purpose of this tutorial, you are going to create just two policies, which are:</p>
<ol>
<li><p>The ability for users to access their own profile</p>
</li>
<li><p>The ability for users to update their own profile</p>
</li>
</ol>
<h4 id="heading-the-ability-for-users-to-access-their-own-profile">The ability for users to access their own profile</h4>
<p>To enable users access their own profile, head back to the SQL editor and create a new snippet with the following query:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">POLICY</span> "Permit Users to Access Their Profile"
  <span class="hljs-keyword">ON</span> <span class="hljs-built_in">public</span>.users
  <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">SELECT</span>
  <span class="hljs-keyword">USING</span> ( auth.uid() = id );
</code></pre>
<p>With this query, users will be able to access their own profile as long as the authenticated user’s ID matches the <code>id</code> of the column of the row.</p>
<h4 id="heading-the-ability-for-users-to-update-their-own-profile">The ability for users to update their own profile</h4>
<p>To enable users update their own profile, head back to the SQL editor and create a new snippet with the following query:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">POLICY</span> "Permit Users to Update Their Profile"
  <span class="hljs-keyword">ON</span> <span class="hljs-built_in">public</span>.users
  <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">UPDATE</span>
  <span class="hljs-keyword">USING</span> ( auth.uid() = id );
</code></pre>
<p>With the above query, users will be able to update their own profile as long as the authenticated user’s ID matches the <code>id</code> of the column of the row.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748397263186/11e886f4-0d08-4907-9859-9269ee0da2ef.png" alt="Screenshot of SQL Editor displaying a policy script for user profile updates, with navigation pane and no results returned." class="image--center mx-auto" width="1910" height="886" loading="lazy"></p>
<h3 id="heading-how-to-configure-supabase-functions-in-supabase-with-the-sql-editor">How to Configure Supabase Functions in Supabase with the SQL Editor</h3>
<p><strong>Supabase Functions</strong> are serverless functions that can be deployed and run within your Supabase project using <strong>Supabase Edge Functions</strong>.</p>
<p>In this project, you will create a trigger function that automatically creates a new row in the users table whenever a new user is created in the <code>auth.users</code> table.</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">CREATE</span>
<span class="hljs-keyword">OR REPLACE</span> <span class="hljs-keyword">FUNCTION</span> <span class="hljs-built_in">public</span>.user_profile() <span class="hljs-keyword">RETURNS</span> <span class="hljs-type">TRIGGER</span> <span class="hljs-keyword">AS</span> $$<span class="pgsql"> <span class="hljs-keyword">BEGIN</span> <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> <span class="hljs-built_in">public</span>.users (id, full_name,avatar_url)
<span class="hljs-keyword">VALUES</span>
  (
    <span class="hljs-built_in">NEW</span>.id,
    <span class="hljs-built_in">NEW</span>.raw_user_meta_data -&gt;&gt; <span class="hljs-string">'full_name'</span>::<span class="hljs-type">TEXT</span>,
    <span class="hljs-built_in">NEW</span>.raw_user_meta_data -&gt;&gt; <span class="hljs-string">'avatar_url'</span>::<span class="hljs-type">TEXT</span>
  );
<span class="hljs-keyword">RETURN</span> <span class="hljs-built_in">NEW</span>;
<span class="hljs-keyword">END</span>;
$$</span> <span class="hljs-keyword">LANGUAGE</span> plpgsql <span class="hljs-keyword">SECURITY</span> <span class="hljs-keyword">DEFINER</span>;
</code></pre>
<p>To summarize the above query:</p>
<ul>
<li><p>You start by defining or replacing a function named <code>user_profile()</code> that will be used as a trigger.</p>
</li>
<li><p>Next, the trigger inserts a new row into the <code>public.users</code> table, and then extracts the <code>full_name</code> and <code>avatar_url</code> from the user's metadata as text.</p>
</li>
<li><p>The inserted record is now returned when the trigger function is complete</p>
</li>
<li><p>Finally, you use the <code>SECURITY DEFINER</code> keyword so that the function can run with the privileges of the user who created it.</p>
</li>
</ul>
<h3 id="heading-how-to-configure-supabase-trigger-in-supabase-with-the-sql-editor">How to Configure Supabase Trigger in Supabase with the SQL Editor</h3>
<p>A trigger in Supabase is a PostgreSQL feature used to automatically run a function in response to events on a table (SELECT, INSERT, UPDATE, or DELETE). It’s mostly used with Row Level Security or syncing data across tables.</p>
<p>In this project, you will create a Supabase trigger that automatically runs a function after a new user is created in the <code>auth.users</code> table.</p>
<pre><code class="lang-pgsql"> <span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TRIGGER</span>
  create_user_trigger
  <span class="hljs-keyword">AFTER</span> <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">ON</span> auth.users
  <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">EACH</span> <span class="hljs-keyword">ROW</span>
  <span class="hljs-keyword">EXECUTE</span> <span class="hljs-keyword">PROCEDURE</span>
    <span class="hljs-built_in">public</span>.user_profile();
</code></pre>
<p>To summarize the above query:</p>
<ul>
<li><p>The first line creates a <strong>trigger</strong> named <code>create_user_trigger</code>.</p>
</li>
<li><p>Next, the INSERT ON statement is activated when a user signs up and a new row is inserted into the <code>auth.users</code> table</p>
</li>
<li><p>Then the trigger runs once for every new user added in a new row.</p>
</li>
<li><p>Finally, the custom function <code>public.user_profile()</code> is called to perform some logic, typically inserting data into the <code>users</code> table.</p>
</li>
</ul>
<p>With the above integration, you can now log into the dashboard with a new google account and view the users table. There you will see the data that contains the <strong>id</strong>, <strong>full_name</strong>, and <strong>avatar_url</strong> as you can see below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748560146471/4c7663a8-6708-461a-8ed5-7ed8a3931318.png" alt="Screenshot of a database table editor displaying user data, including name and avatar URL, with options for filtering and sorting." class="image--center mx-auto" width="1920" height="878" loading="lazy"></p>
<h2 id="heading-how-to-create-and-setup-the-chat-table-in-supabase-using-the-user-interface">How to Create and Setup the Chat Table in Supabase using the User Interface</h2>
<p>To create the chat table, you will use the user interface in Supabase instead of the SQL Editor. To do this, you need to head to the Table Editor menu on the dashboard and click on the <strong>New Table</strong> button.</p>
<p>Once selected, a modal will popup which contains some input fields such as the table name, description, and columns. You can call the table name chat and omit the description for now since it’s optional. In the columns section, fill out the fields using the schema below:</p>
<ul>
<li><p>id (uuid)</p>
</li>
<li><p>Created At (date)</p>
</li>
<li><p>text (text)</p>
</li>
<li><p>editable (boolean)</p>
</li>
<li><p>sender (uuid)</p>
</li>
</ul>
<p>You can see the configuration for this in the table below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748564800333/0e879684-75d3-4c47-9f38-56d6041d6b38.png" alt="Screenshot of a table editor interface displaying fields for creating a new database table with various data types and options." class="image--center mx-auto" width="1882" height="879" loading="lazy"></p>
<p>Next up, you need to add a foreign key relation for the users table. To do this, you scroll to the bottom of the modal and click on the <strong>Add foreign key relation</strong> button. This will prompt another modal on top of the current modal. Here you can take the following steps:</p>
<ul>
<li><p>Under the <strong>Select a table to reference to</strong> label, select the <strong>users</strong> table<strong>.</strong></p>
</li>
<li><p>Under the <strong>public.chat</strong> label, select the <strong>sender</strong> option.</p>
</li>
<li><p>Under public.users label, select <strong>uuid.</strong></p>
</li>
<li><p>Under the <strong>Action if referenced row is updated</strong> label, select <strong>Cascade</strong>.</p>
</li>
<li><p>Under the <strong>Action if referenced row is removed</strong> label, select <strong>Cascade</strong> as well.</p>
</li>
</ul>
<p>If you’ve followed the above steps, you can now click on the save button, which successfully creates the chat table.</p>
<h2 id="heading-how-to-create-and-setup-the-chat-table-policies-in-supabase">How to Create and Setup the Chat Table Policies in Supabase</h2>
<p>The final step you need to perform for the chat table is to add a Row Level Security policy. You can do this by clicking the <strong>Add RLS policy</strong> button at the top of the chat table page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748567233239/6f69e305-5e09-4485-89b7-0115d41c8e0f.png" alt="A web interface displaying a Table Editor with options for managing chat and user data in a database schema." class="image--center mx-auto" width="1915" height="385" loading="lazy"></p>
<p>A new page will appear. Then you can click on the <strong>Create policy</strong> button, which displays a modal.</p>
<p>The first policy you will create is the <strong>DELETE</strong> policy, which will have the configuration you can see in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748779442105/f977dafb-ab73-4bb7-8643-9aa4e889c359.png" alt="Screenshot of a database policy settings interface for deleting user records based on user ID in a chat application." class="image--center mx-auto" width="1920" height="777" loading="lazy"></p>
<p>From the above image, we made these four implementations:</p>
<ul>
<li><p>First, we entered the policy name as “<strong>Delete by User ID</strong>“.</p>
</li>
<li><p>Next we selected the <strong>DELETE</strong> policy command clause.</p>
</li>
<li><p>Then under the targeted roles, we selected authenticated in the drop down select, to allow only authenticated users to perform delete operations.</p>
</li>
<li><p>Finally, under the <strong>USE OPTIONS ABOVE TO EDIT</strong> section, in line 7, we condition the query as <code>(auth.uid() = sender)</code> This allows only logged in users to delete their data.</p>
</li>
</ul>
<p>You can now click on the <strong>Save policy</strong> button to complete the DELETE setup.</p>
<p>The second policy you will create is the <strong>INSERT</strong> policy, which will have the configuration you can see in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748823531256/14aea41d-f221-42df-a739-b40a680395e3.png" alt="A policy configuration interface for inserting records in a chat table, targeting authenticated users with specific criteria." class="image--center mx-auto" width="1900" height="879" loading="lazy"></p>
<p>From the above image, four implementations were made:</p>
<ul>
<li><p>First, we entered the policy name as “<strong>Insert for Authenticated Users</strong>“.</p>
</li>
<li><p>Next we selected the <strong>INSERT</strong> policy command clause.</p>
</li>
<li><p>Then under the targeted roles, we selected authenticated in the drop down to allow only authenticated users perform insert operations.</p>
</li>
<li><p>Finally, under the <strong>USE OPTIONS ABOVE TO EDIT</strong> section, in line 7, the query was conditioned as <code>((sender = auth.uid()) AND (created_at = now()))</code>. The first condition ensures that the <code>sender</code> field in the inserted row matches the currently logged-in user's ID (from the Supabase JWT), while the second condition ensures that the <code>created_at</code> field is exactly equal to the current timestamp at the time of insertion.</p>
</li>
</ul>
<p>The third policy you will create is the <strong>SELECT</strong> policy, which will have the configuration you can see in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748824129598/8c15b701-dadb-4763-b5eb-e9484bd84470.png" alt="Row-level security policy configuration for a database table, specifying access permissions for authenticated users based on SELECT criteria." class="image--center mx-auto" width="1904" height="882" loading="lazy"></p>
<p>From the above image, we implemented four things:</p>
<ul>
<li><p>First, we entered the policy name as “<strong>Read Data for Authenticated Users</strong>“.</p>
</li>
<li><p>Next we selected the <strong>SELECT</strong> policy command clause, <em>pun intended</em> <strong>😊*</strong>.*</p>
</li>
<li><p>Then under the targeted roles, we selected authenticated in the drop down to allow only authenticated users perform select operations.</p>
</li>
<li><p>Finally, under the <strong>USE OPTIONS ABOVE TO EDIT</strong> section, in line 7, the query was conditioned as <code>true</code>. This allows all authenticated users to read all rows, or chats in our case.</p>
</li>
</ul>
<p>With the above implementation, you’ve created all the policies needed for the chat application.</p>
<h2 id="heading-how-to-integrate-functionality-to-create-a-new-chat-message-in-the-angular-application">How to Integrate Functionality to Create a New Chat Message in the Angular Application</h2>
<p>Now let’s add the code that lets users create a new chat message. First, start by creating a new Angular service using the command below:</p>
<pre><code class="lang-powershell">ng g s services/chat<span class="hljs-literal">-service</span>
</code></pre>
<p>Within the <code>chat-service.ts</code> file, you can now configure the Supabase client, just as we did in the <code>auth-service.ts</code> file as seen below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable, signal } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { SupabaseClient, createClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@supabase/supabase-js'</span>;
<span class="hljs-keyword">import</span> { environment } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../environments/environment.development'</span>;

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChatService {
  supabase!: SupabaseClient;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.supabase = createClient(
      environment.supabaseUrl,
      environment.supabaseKey
    );
  }
}
</code></pre>
<p>Next, create the function that enables you to create a new chat message. The function called <code>chatMessage()</code> is below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable, signal } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { SupabaseClient, createClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@supabase/supabase-js'</span>;
<span class="hljs-keyword">import</span> { environment } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../environments/environment.development'</span>;

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChatService {
  supabase!: SupabaseClient;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.supabase = createClient(
      environment.supabaseUrl,
      environment.supabaseKey
    );
  }

  <span class="hljs-keyword">async</span> chatMessage(text: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> { data, error } = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase.from(<span class="hljs-string">'chat'</span>).insert({ text });

      <span class="hljs-keyword">if</span> (error) {
        alert(error.message);
      }
    } <span class="hljs-keyword">catch</span> (error) {
      alert(error);
    }
  }
}
</code></pre>
<p>The above <code>chatMessage</code> function sends a chat message by inserting it into the <code>chat</code> table in Supabase.</p>
<p>You can now call this service in the <code>chat-component.ts</code> file. Within the <code>chat-component.ts</code>, import and inject the <code>chat-service.ts</code> file.</p>
<p>To send the data to the Supabase database, you need to setup Reactive form. Reactive form in Angular enables you to get data from an input field, which can be passed as a payload and then inserted into the database.</p>
<p>To setup a Reactive form in Angular, follow these steps:</p>
<ul>
<li><p>Import <code>FormBuilder</code>, <code>FormGroup</code>, <code>ReactiveFormsModule</code>, and <code>Validators</code> from <code>@angular/forms</code></p>
</li>
<li><p>Insert the <code>ReactiveFormsModule</code> inside of the imports array.</p>
</li>
<li><p>Inject the <code>FormBuilder</code> as a variable.</p>
</li>
<li><p>Declare a property that will hold the <strong>Reactive Form group.</strong></p>
</li>
<li><p>Inject the <code>FormBuilder</code> into the <code>ngOnInit</code> lifecycle hook.</p>
</li>
</ul>
<p>The code for the Reactive form setup is below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { AuthService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/auth-service'</span>;
<span class="hljs-keyword">import</span> {
  FormBuilder,
  FormGroup,
  ReactiveFormsModule,
  Validators,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/forms'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-chat'</span>,
  standalone: <span class="hljs-literal">true</span>,
  imports: [ReactiveFormsModule],
  templateUrl: <span class="hljs-string">'./chat-component.html'</span>,
  styleUrl: <span class="hljs-string">'./chat-component.css'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChatComponent {
  chatForm!: FormGroup;
  <span class="hljs-keyword">private</span> fb = inject(FormBuilder);

  ngOnInit() {
    <span class="hljs-built_in">this</span>.chatForm = <span class="hljs-built_in">this</span>.fb.group({
      chat_message: [<span class="hljs-string">''</span>, Validators.required],
    });
  }
}
</code></pre>
<p>To complete the Reactive form setup, bind the <code>FormGroup</code> into the HTML file. Also bind the disabled attribute, which disables the button when the form is invalid, as you can see below:</p>
<pre><code class="lang-xml">  <span class="hljs-tag">&lt;<span class="hljs-name">form</span> [<span class="hljs-attr">formGroup</span>]=<span class="hljs-string">"chatForm"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex-grow-0 py-3 px-4 border-top"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"input-group"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">formControlName</span>=<span class="hljs-string">"chat_message"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Type your message"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> [<span class="hljs-attr">disabled</span>]=<span class="hljs-string">"!chatForm.valid"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;</span>Send<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
           <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>With the Reactive form setup complete, you can now create the function that calls the service which allows you create a new chat message.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { AuthService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/auth-service'</span>;
<span class="hljs-keyword">import</span> {
  FormBuilder,
  FormGroup,
  ReactiveFormsModule,
  Validators,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/forms'</span>;
<span class="hljs-keyword">import</span> { ChatService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/chat-service'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-chat'</span>,
  standalone: <span class="hljs-literal">true</span>,
  imports: [ReactiveFormsModule],
  templateUrl: <span class="hljs-string">'./chat-component.html'</span>,
  styleUrl: <span class="hljs-string">'./chat-component.css'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChatComponent {
  <span class="hljs-keyword">private</span> chat_service = inject(ChatService);
  chatForm!: FormGroup;
  <span class="hljs-keyword">private</span> fb = inject(FormBuilder);

  ngOnInit() {
    <span class="hljs-built_in">this</span>.chatForm = <span class="hljs-built_in">this</span>.fb.group({
      chat_message: [<span class="hljs-string">''</span>, Validators.required],
    });
  }

  onSubmit() {
    <span class="hljs-keyword">const</span> formValue = <span class="hljs-built_in">this</span>.chatForm.value.chat_message;
    <span class="hljs-built_in">this</span>.chat_service
      .chatMessage(formValue)
      .then(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> {
        <span class="hljs-built_in">this</span>.chatForm.reset();
      })
      .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
        alert(err.message);
      });
  }
}
</code></pre>
<p>The <code>onSubmit()</code> function in the above code basically does the following tasks:</p>
<ul>
<li><p>Gets the data from the Reactive form input field using the variable called <code>formValue</code></p>
</li>
<li><p>Calls the <code>chatMessage()</code> method from the <code>ChatService</code>, passing the data from the input field.</p>
</li>
<li><p>If successful, it resets the form.</p>
</li>
<li><p>If there's an error, it shows an alert with the error message.</p>
</li>
</ul>
<p>In the <code>chat-component.html</code> file, use of the <code>(ngSubmit)</code> directive to bind the <code>onSubmit()</code> function to the form:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> [<span class="hljs-attr">formGroup</span>]=<span class="hljs-string">"chatForm"</span> (<span class="hljs-attr">ngSubmit</span>)=<span class="hljs-string">"onSubmit()"</span>&gt;</span>
</code></pre>
<p>You can now test to see if the data we send from the input field saves directly into the <strong>chat</strong> database table.</p>
<p><strong>NOTE:</strong> make sure you <strong>delete all current users saved in the users table and authentication page on Supabase</strong> before trying this out for best results.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749042436895/a50416e7-3f8b-48a9-b8f3-96df520b2238.png" alt="Screenshot of a chat interface showing a message from &quot;Sharon Doe,&quot; with a timestamp and a text input field at the bottom." class="image--center mx-auto" width="1917" height="880" loading="lazy"></p>
<p>From the above image, you will click on the send button and send the <strong>Test</strong> data in the input field.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749043485066/94b53998-e924-44c2-bbfd-e26d591fdf54.png" alt="Table editor interface displaying the &quot;chat&quot; table with columns including ID, created_at, text, editable, and sender, showing entries and configuration options." class="image--center mx-auto" width="1911" height="739" loading="lazy"></p>
<p>The data should now be successfully saved into the database and the <strong>INSERT</strong> operation should now be integrated into the Angular application.</p>
<h2 id="heading-how-to-fetch-data-in-the-angular-application-from-supabase">How to Fetch Data in the Angular Application from Supabase</h2>
<p>To fetch data from the chat table from Supabase, start by creating a service function in the <code>chat-service.ts</code> file, as seen below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable, signal } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { SupabaseClient, createClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@supabase/supabase-js'</span>;
<span class="hljs-keyword">import</span> { environment } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../environments/environment.development'</span>;

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChatService {
  supabase!: SupabaseClient;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.supabase = createClient(
      environment.supabaseUrl,
      environment.supabaseKey
    );
  }

  <span class="hljs-keyword">async</span> chatMessage(text: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> { data, error } = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase.from(<span class="hljs-string">'chat'</span>).insert({ text });
      <span class="hljs-keyword">if</span> (error) {
        alert(error.message);
      }
    } <span class="hljs-keyword">catch</span> (error) {
      alert(error);
    }
  }

    <span class="hljs-keyword">async</span> listChat() {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> { data, error } = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase
        .from(<span class="hljs-string">'chat'</span>)
        .select(<span class="hljs-string">'*,users(*)'</span>);

      <span class="hljs-keyword">if</span> (error) {
        alert(error.message);
      }

      <span class="hljs-keyword">return</span> data;
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-keyword">throw</span> error;
    }
  }
}
</code></pre>
<p>To summarize the function above called <code>listChat()</code>:</p>
<ul>
<li><p>We fetch the chat messages from the <code>chat</code> table using the <code>from</code> clause.</p>
</li>
<li><p>Then we include the related user info by joining the users table with <code>(select(', users()'))</code>.</p>
</li>
<li><p>An alert message is shown if there's a Supabase error.</p>
</li>
<li><p>Finally, the fetched data is returned, an error is thrown if something goes wrong.</p>
</li>
</ul>
<p>Before you head to the <code>chat-component.ts</code> file to consume the <code>listChat()</code> service function, you need to create an interface which helps shape the structure of the array of objects returned from Supabase. This gives us type safety and consistency.</p>
<p>To set up the interface, create an <strong>interface</strong> folder within the <strong>app</strong> directory. Here you will create a file called <code>chat-response.ts</code>. Then create the structure below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Ichat {
  created_at: <span class="hljs-built_in">string</span>;
  editable: <span class="hljs-built_in">boolean</span>;
  id: <span class="hljs-built_in">string</span>;
  sender: <span class="hljs-built_in">string</span>;
  text: <span class="hljs-built_in">string</span>;
  users: {
    avatar_url: <span class="hljs-built_in">string</span>;
    id: <span class="hljs-built_in">string</span>;
    full_name: <span class="hljs-built_in">string</span>;
  };
}
</code></pre>
<p>Heading back to the <code>chat-component.ts</code>, import both the interface which was named <code>Ichat</code> as well as <code>signal</code> and <code>effect</code> from <code>@angular/core</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, effect, inject, signal } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { AuthService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/auth-service'</span>;
<span class="hljs-keyword">import</span> {
  FormBuilder,
  FormGroup,
  ReactiveFormsModule,
  Validators,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/forms'</span>;
<span class="hljs-keyword">import</span> { ChatService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/chat-service'</span>;
<span class="hljs-keyword">import</span> { Ichat } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../interface/chat-response'</span>;
</code></pre>
<p>Next, create a variable called <code>chats</code>, which will hold the response from the Supabase client as a signal:</p>
<pre><code class="lang-typescript">  chats = signal&lt;Ichat[]&gt;([]);
</code></pre>
<p>With this, you can now create the function that fetches the chat array of objects from the Supabase dashboard:</p>
<pre><code class="lang-typescript">  onListChat() {
    <span class="hljs-built_in">this</span>.chat_service
      .listChat()
      .then(<span class="hljs-function">(<span class="hljs-params">res: Ichat[] | <span class="hljs-literal">null</span></span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(res);
        <span class="hljs-keyword">if</span> (res !== <span class="hljs-literal">null</span>) {
          <span class="hljs-built_in">this</span>.chats.set(res);
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'No messages Found'</span>);
        }
      })
      .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
        alert(err.message);
      });
  }
</code></pre>
<p>To summarize the function above, we started by:</p>
<ul>
<li><p>Calling the <code>listChat()</code> function from the <code>ChatService</code> to fetch the chat messages.</p>
</li>
<li><p>If messages are returned, it updates the chats signal with the result, by using the <code>set()</code> method derived from signals.</p>
</li>
<li><p>In the event where no messages are returned, it logs <code>"No messages Found"</code> to the console.</p>
</li>
<li><p>If an error occurs, it shows an alert with the error message.</p>
</li>
</ul>
<p>We then call the <code>onListChat()</code> function within the constructor using the <code>effect()</code> function, which helps handle asynchronous operations.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    effect(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.onListChat();
    });
  }
</code></pre>
<p>When the application is saved, you can see the data in the console from the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749066359110/dedaa60a-c711-42d9-bac1-c9a130fcc4d1.png" alt="Screenshot of a chat application showing a message from Sharon Doe, along with developer tools displaying the message data in an array of object." class="image--center mx-auto" width="1912" height="868" loading="lazy"></p>
<p>You can now display the chat data in the HTML file of the page by getting rid of the placeholder text.</p>
<p>To do this, you can use the <code>@for</code> control flow in Angular as seen below:</p>
<pre><code class="lang-typescript">&lt;main&gt;
  &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"container"</span>&gt;
    &lt;h3 <span class="hljs-keyword">class</span>=<span class="hljs-string">"mb-3"</span>&gt;Supa Chat &lt;button <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn btn-secondary"</span> style=<span class="hljs-string">"float: right;"</span>&gt;Log
        out&lt;/button&gt;
    &lt;/h3&gt;
    &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"card"</span>&gt;
      &lt;div&gt;

        &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"col-12 col-lg-12 col-xl-12"</span>&gt;
          <span class="hljs-meta">@for</span> (msg <span class="hljs-keyword">of</span> <span class="hljs-built_in">this</span>.chats(); track msg) {
          &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"position-relative"</span>&gt;
            &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"chat-messages p-4"</span>&gt;
              &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"chat-message-left pb-4"</span>&gt;
                &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"me-5"</span>&gt;
                  &lt;img src={{msg?.users?.avatar_url}} <span class="hljs-keyword">class</span>=<span class="hljs-string">"rounded-circle mr-1"</span> alt=<span class="hljs-string">"image"</span> width=<span class="hljs-string">"40"</span> height=<span class="hljs-string">"40"</span>&gt;
                  &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"text-muted small text-nowrap mt-2"</span>&gt;{{msg?.created_at | date: <span class="hljs-string">'M/d/yy, h:mm a'</span>}}&lt;/div&gt;
                &lt;/div&gt;
                &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"flex-shrink-1 bg-light rounded py-2 px-3 ml-3"</span>&gt;
                  &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"font-weight-bold mb-1"</span>&gt;{{msg?.users?.full_name}}&lt;/div&gt;
                  {{msg?.text}}
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          } <span class="hljs-meta">@empty</span> {
          &lt;div&gt;No chats available&lt;/div&gt;
          }

          &lt;form [formGroup]=<span class="hljs-string">"chatForm"</span> (ngSubmit)=<span class="hljs-string">"onSubmit()"</span>&gt;
            &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"flex-grow-0 py-3 px-4 border-top"</span>&gt;
              &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"input-group"</span>&gt;
                &lt;input formControlName=<span class="hljs-string">"chat_message"</span> <span class="hljs-keyword">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"form-control"</span> placeholder=<span class="hljs-string">"Type your message"</span>&gt;
                &lt;button [disabled]=<span class="hljs-string">"!chatForm.valid"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;Send&lt;/button&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/form&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/main&gt;
</code></pre>
<p>From the code above, right above the <code>div</code> with the <code>position-relative</code> class, we declared the <code>@for (msg of this.chats(); track msg)</code> control flow, which does the following:</p>
<ul>
<li><p>Loops through the array returned by <code>this.chats()</code> which is the signal variable that was declared in the template.</p>
</li>
<li><p>Assigns each item in the array to the <code>msg</code> variable.</p>
</li>
<li><p>Tracks each item by identity <code>track msg</code> for DOM updates.</p>
</li>
</ul>
<p>Next, within the loop, you called the data in the appropriate HTML tag to display the image, the date the chat was created, the full name, and the chat message as well.</p>
<p>Finally, you created an <code>@empty</code> block which displays the message <code>No chats available</code> if there are no items in the array.</p>
<p>You should have the outcome below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749082870784/85184bf1-3cfe-4808-a149-64a6b925e097.png" alt="A chat interface displaying two messages from the user &quot;adedeji adesoga,&quot; dated June 4, 2025, with a text input box at the bottom." class="image--center mx-auto" width="1904" height="715" loading="lazy"></p>
<h2 id="heading-how-to-delete-data-in-the-angular-application">How to Delete Data in the Angular Application</h2>
<p>When creating the delete functionality, first you need to create a service function in the <code>chat-service.ts</code> file as seen below:</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">async</span> deleteChat(id: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase.from(<span class="hljs-string">'chat'</span>).delete().eq(<span class="hljs-string">'id'</span>, id);
    <span class="hljs-keyword">return</span> data;
  }
</code></pre>
<p>All the above function does is find the specific id provided from the parameter, and return the result of the delete operation.</p>
<p>Next, track the selected chat that was clicked from the array of listed chats and then pass the data down to your service.</p>
<p>To do this, first create a function within the service called <code>selectedChats()</code> which helps receive the data from the template:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">public</span> savedChat = signal({});

 selectedChats(msg: Ichat) {
    <span class="hljs-built_in">this</span>.savedChat.set(msg);
  }
</code></pre>
<p>Above, we created the variable called <code>savedChat</code>. It’s declared as a signal that helps receive the object of the chat that we want to delete using the <code>set()</code> method.</p>
<p>You can now head to the <code>chat-component.ts</code> file to create the function that passed the data down to the <code>selectedChats()</code> function.</p>
<p>You can see this function below:</p>
<pre><code class="lang-typescript"> openDropDown(msg: Ichat) {
    <span class="hljs-built_in">console</span>.log(msg);
    <span class="hljs-built_in">this</span>.chat_service.selectedChats(msg);
  }
</code></pre>
<p>As you can see from the function above, once you bind it to the HTML element, it will make sure that you get the object of the specific chat that was clicked.</p>
<p>In our <code>chat-component.html</code> file, create a menu drop down that will help achieve this result as seen below:</p>
<pre><code class="lang-typescript">&lt;main&gt;
  &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"container"</span>&gt;
    &lt;h3 <span class="hljs-keyword">class</span>=<span class="hljs-string">"mb-3"</span>&gt;Supa Chat &lt;button <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn btn-secondary"</span> style=<span class="hljs-string">"float: right;"</span>&gt;Log
        out&lt;/button&gt;
    &lt;/h3&gt;
    &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"card"</span>&gt;
      &lt;div&gt;

        &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"col-12 col-lg-12 col-xl-12"</span>&gt;
          <span class="hljs-meta">@for</span> (msg <span class="hljs-keyword">of</span> <span class="hljs-built_in">this</span>.chats(); track msg) {
          &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"position-relative"</span>&gt;
            &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"chat-messages p-4"</span>&gt;
              &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"chat-message-left pb-4"</span>&gt;
                &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"me-5"</span>&gt;
                  &lt;img src={{msg?.users?.avatar_url}} <span class="hljs-keyword">class</span>=<span class="hljs-string">"rounded-circle mr-1"</span> alt=<span class="hljs-string">"image"</span> width=<span class="hljs-string">"40"</span> height=<span class="hljs-string">"40"</span>&gt;
                  &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"text-muted small text-nowrap mt-2"</span>&gt;{{msg?.created_at | date: <span class="hljs-string">'M/d/yy, h:mm a'</span>}}&lt;/div&gt;
                &lt;/div&gt;
                &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"flex-shrink-1 bg-light rounded py-2 px-3 ml-3"</span>&gt;
                  &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"font-weight-bold mb-1"</span>&gt;{{msg?.users?.full_name}}&lt;/div&gt;
                  {{msg?.text}}
                &lt;/div&gt;

                &lt;!-- Delete Modal Button Menu--&gt;
                &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"dropdown"</span>&gt;
                  &lt;span (click)=<span class="hljs-string">"openDropDown(msg)"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"mt-3 ms-5"</span> <span class="hljs-keyword">type</span>=<span class="hljs-string">"button"</span> id=<span class="hljs-string">"dropdownMenuButton1"</span>
                    data-bs-toggle=<span class="hljs-string">"dropdown"</span> aria-expanded=<span class="hljs-string">"false"</span>&gt;
                    ...
                  &lt;/span&gt;
                  &lt;ul <span class="hljs-keyword">class</span>=<span class="hljs-string">"dropdown-menu"</span> aria-labelledby=<span class="hljs-string">"dropdownMenuButton1"</span>&gt;
                    &lt;li&gt;
                      &lt;a <span class="hljs-keyword">class</span>=<span class="hljs-string">"dropdown-item"</span> href=<span class="hljs-string">"#"</span> data-bs-toggle=<span class="hljs-string">"modal"</span> data-bs-target=<span class="hljs-string">"#exampleModal"</span>&gt;Delete&lt;/a&gt;
                    &lt;/li&gt;
                  &lt;/ul&gt;
                &lt;/div&gt;


              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          } <span class="hljs-meta">@empty</span> {
          &lt;div&gt;No chats available&lt;/div&gt;
          }

          &lt;form [formGroup]=<span class="hljs-string">"chatForm"</span> (ngSubmit)=<span class="hljs-string">"onSubmit()"</span>&gt;
            &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"flex-grow-0 py-3 px-4 border-top"</span>&gt;
              &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"input-group"</span>&gt;
                &lt;input formControlName=<span class="hljs-string">"chat_message"</span> <span class="hljs-keyword">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"form-control"</span> placeholder=<span class="hljs-string">"Type your message"</span>&gt;
                &lt;button [disabled]=<span class="hljs-string">"!chatForm.valid"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;Send&lt;/button&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/form&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/main&gt;
</code></pre>
<p>From the above code, take note of the following: the comment with the text <code>&lt;!-- Delete Modal Button Menu--&gt;</code> is created within the <code>@for</code> control flow. This is essential because it allows the <code>openDropDown(msg)</code> to receive the right object as a parameter when the drop down menu is clicked. A quick look at the console will reveal this.</p>
<p>You can now create the delete modal component, which allows you to consume the delete service required for a chat to be deleted.</p>
<p>To create the delete component, use the command below:</p>
<pre><code class="lang-powershell">ng g component layout/modal<span class="hljs-literal">-component</span>
</code></pre>
<p>The design for the delete component is a Bootstrap 5 modal that looks like this:</p>
<pre><code class="lang-typescript">&lt;!-- Modal --&gt;
&lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"modal fade"</span> id=<span class="hljs-string">"exampleModal"</span> tabindex=<span class="hljs-string">"-1"</span> aria-labelledby=<span class="hljs-string">"exampleModalLabel"</span> aria-hidden=<span class="hljs-string">"true"</span>&gt;
  &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"modal-dialog"</span>&gt;
    &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"modal-content"</span>&gt;
      &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"modal-header"</span>&gt;
        &lt;h5 <span class="hljs-keyword">class</span>=<span class="hljs-string">"modal-title"</span> id=<span class="hljs-string">"exampleModalLabel"</span>&gt;Modal title&lt;/h5&gt;
        &lt;button <span class="hljs-keyword">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn-close"</span> data-bs-dismiss=<span class="hljs-string">"modal"</span> aria-label=<span class="hljs-string">"Close"</span>&gt;&lt;/button&gt;
      &lt;/div&gt;
      &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"modal-body"</span>&gt;
        Are really sure you want to <span class="hljs-keyword">delete</span> <span class="hljs-built_in">this</span> message?
      &lt;/div&gt;
      &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"modal-footer"</span>&gt;
        &lt;button <span class="hljs-keyword">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn btn-secondary"</span> data-bs-dismiss=<span class="hljs-string">"modal"</span>&gt;No&lt;/button&gt;
        &lt;button [attr.data-bs-dismiss]=<span class="hljs-string">"!this.dismiss() === true ? 'modal' : null"</span> (click)=<span class="hljs-string">"deleteChat()"</span> <span class="hljs-keyword">type</span>=<span class="hljs-string">"button"</span>
          <span class="hljs-keyword">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;Yes&lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p>If you paste the above code directly in your code editor, you’re going to get a host of errors because we have not created the <code>deleteChat()</code> function as well as the <code>dismiss()</code> signal variable in the template file. Let’s go ahead and do that.</p>
<p>The first step in setting up the <code>modal-componet.ts</code> file component is to import the appropriate modules as seen below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, effect, inject, signal } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { ChatService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/chat.service'</span>;
<span class="hljs-keyword">import</span> { Router } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;
</code></pre>
<p>Next, inject the <code>chatservice</code>, <code>Angular router</code>, as well as the the <code>dismiss</code> variable which is a signal as seen below:</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">private</span> chat_service = inject(ChatService);
  <span class="hljs-keyword">private</span> router = inject(Router);
  dismiss = signal(<span class="hljs-literal">false</span>);
</code></pre>
<p>With this you can now create the <code>deleteChat()</code> function as seen below:</p>
<pre><code class="lang-typescript">deleteChat() {
    <span class="hljs-keyword">const</span> id = (<span class="hljs-built_in">this</span>.chat_service.savedChat() <span class="hljs-keyword">as</span> { id: <span class="hljs-built_in">string</span> }).id;

    <span class="hljs-built_in">console</span>.log(id);

    <span class="hljs-built_in">this</span>.chat_service
      .deleteChat(id)
      .then(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">let</span> currentUrl = <span class="hljs-built_in">this</span>.router.url;

        <span class="hljs-built_in">this</span>.dismiss.set(<span class="hljs-literal">true</span>);

        <span class="hljs-built_in">this</span>.router
          .navigateByUrl(<span class="hljs-string">'/'</span>, { skipLocationChange: <span class="hljs-literal">true</span> })
          .then(<span class="hljs-function">() =&gt;</span> {
            <span class="hljs-built_in">this</span>.router.navigate([currentUrl]);
          });
      })
      .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(err);
        alert(err.message);
      });
  }
</code></pre>
<ul>
<li><p>The first thing we did under the <code>deleteChat()</code> method was to extract the <code>id</code> from the chat service.</p>
</li>
<li><p>This <code>id</code> is then passed into the <code>deleteChat()</code> method from our service which helps delete the specific chat that was selected.</p>
</li>
<li><p>Once the chat has been deleted, the current route gets reloaded to update the UI.</p>
</li>
</ul>
<p>To activate the modal, you need to import the Modal Component in the <code>chat-component.html</code> file (last line of code below:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-3"</span>&gt;</span>Supa Chat <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-secondary"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"float: right;"</span>&gt;</span>Log
        out<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-12 col-lg-12 col-xl-12"</span>&gt;</span>
          @for (msg of this.chats(); track msg) {
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"position-relative"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat-messages p-4"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chat-message-left pb-4"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"me-5"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{{msg?.users?.avatar_url}}</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"rounded-circle mr-1"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"image"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"40"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"40"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-muted small text-nowrap mt-2"</span>&gt;</span>{{msg?.created_at | date: 'M/d/yy, h:mm a'}}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex-shrink-1 bg-light rounded py-2 px-3 ml-3"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"font-weight-bold mb-1"</span>&gt;</span>{{msg?.users?.full_name}}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                  {{msg?.text}}
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

                <span class="hljs-comment">&lt;!-- Delete Modal Button Menu--&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"openDropDown(msg)"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mt-3 ms-5"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"dropdownMenuButton1"</span>
                    <span class="hljs-attr">data-bs-toggle</span>=<span class="hljs-string">"dropdown"</span> <span class="hljs-attr">aria-expanded</span>=<span class="hljs-string">"false"</span>&gt;</span>
                    ...
                  <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown-menu"</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"dropdownMenuButton1"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
                      <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown-item"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">data-bs-toggle</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">data-bs-target</span>=<span class="hljs-string">"#exampleModal"</span>&gt;</span>Delete<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
                  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>


              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          } @empty {
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>No chats available<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          }

          <span class="hljs-tag">&lt;<span class="hljs-name">form</span> [<span class="hljs-attr">formGroup</span>]=<span class="hljs-string">"chatForm"</span> (<span class="hljs-attr">ngSubmit</span>)=<span class="hljs-string">"onSubmit()"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex-grow-0 py-3 px-4 border-top"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"input-group"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">formControlName</span>=<span class="hljs-string">"chat_message"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Type your message"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> [<span class="hljs-attr">disabled</span>]=<span class="hljs-string">"!chatForm.valid"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;</span>Send<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>

<span class="hljs-comment">&lt;!-- modal --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">app-modal</span> /&gt;</span>
</code></pre>
<p><strong>NOTE</strong>: Don’t forget to import the <strong>ModalComponent</strong> file in the <code>chat-component.ts</code> file to avoid having any errors.</p>
<p>You have now implemented the ability to Insert, read, and delete data. The final implementation is to integrate the logout functionality.</p>
<h2 id="heading-how-to-implement-logout-functionality-in-the-angular-application">How to Implement Logout Functionality in the Angular Application</h2>
<p>Earlier in the tutorial, within the <code>auth-service.ts</code> file, you created a function called <code>signOut()</code> as seen below:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">async</span> signOut() {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.supabase.auth.signOut();
  }
</code></pre>
<p>In the <code>chat-component.ts</code> file, you will import and inject the <code>sigOut()</code> method. To do this, follow these steps:</p>
<ul>
<li><p>Import and inject the Angular router.</p>
</li>
<li><p>Import and inject the Authentication Service file</p>
</li>
<li><p>Create the <code>logOut()</code> function that consumes the <code>signOut()</code> service:</p>
</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> logOut() { 
<span class="hljs-built_in">this</span>.auth .signOut() .then(<span class="hljs-function">() =&gt;</span>
 { <span class="hljs-built_in">this</span>.router.navigate([<span class="hljs-string">'/login'</span>]); }) 
.catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
 alert(err.message);
 });
 }
</code></pre>
<ul>
<li>Finally in the <code>chat-component.html</code> file, within the button tag at the top of the page, call the <code>logout()</code> function using the <code>(click)</code> event handler:</li>
</ul>
<pre><code class="lang-xml">  <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-3"</span>&gt;</span>Supa Chat 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"logOut()"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-secondary"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"float: right;"</span>&gt;</span>Log Out<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
</code></pre>
<p>Once the Log Out button is clicked, the user gets navigated to the Login page and the user state gets reset in the browser.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned how to build a real-time chat application using Angular and Supabase. We covered the following key concepts:</p>
<ul>
<li><p>How to create database tables in Supabase</p>
</li>
<li><p>How to create triggers and functions in Supabase</p>
</li>
<li><p>How to use signals to manage state in an Angular</p>
</li>
<li><p>How to create authentication and authorization using Supabase and Google OAuth 2.0</p>
</li>
<li><p>How to work with Reactive forms in Angular</p>
</li>
</ul>
<p>and lots more.</p>
<p>You can access the full codebase by cloning the repository on <a target="_blank" href="https://github.com/desoga10/ng-chat-20">GitHub</a>.</p>
<p>If you found this article helpful, consider subscribing to my <a target="_blank" href="https://www.youtube.com/@TheCodeAngle">YouTube channel</a> where I share hands-on tutorials on modern web development technologies like JavaScript, HTML, CSS, Angular, Supabase, Firebase, React, Third party API and AI tools, and many more. Cheers!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use @Input() to Read Angular Route Parameters ]]>
                </title>
                <description>
                    <![CDATA[ By Deborah Kurata One of the new features in Angular v16 is automatic route parameter mapping using the @Input() decorator. What does that mean? Well, you may have code that reads route parameters using the Activated Route service, like this:   priva... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/use-input-for-angular-route-parameters/</link>
                <guid isPermaLink="false">66d45e134a7504b7409c3368</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 10 Jul 2023 21:18:44 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/thumbnail.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Deborah Kurata</p>
<p>One of the new features in Angular v16 is automatic route parameter mapping using the <code>@Input()</code> decorator.</p>
<p>What does that mean? Well, you may have code that reads route parameters using the Activated Route service, like this:</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">private</span> route = inject(ActivatedRoute);

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">const</span> id = <span class="hljs-built_in">this</span>.route.snapshot.paramMap.get(<span class="hljs-string">'id'</span>);
    <span class="hljs-keyword">if</span> (id) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.id);
    }
  }
</code></pre>
<p>We first inject the Activated Route service. Then we get the route parameter from that activated route snapshot, dotting down to the <code>get()</code> method and passing in the name of the route parameter.</p>
<p>In Angular v16 and later, our code can instead read route parameters like this:</p>
<pre><code class="lang-typescript">  <span class="hljs-meta">@Input</span>() id = <span class="hljs-string">''</span>;

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.id);
  }
</code></pre>
<p>Here we use an input property defined with the <code>@Input()</code> decorator. Angular automatically reads the route parameter and assigns it to the input property. This syntax is much shorter and easier!</p>
<p>Let's walk through an example: first using the Activated Route service, then trying out the new input property syntax to read route parameters.</p>
<p>You can watch the associated video here for a demonstration:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Nuwn5uY8ETw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-how-to-configure-a-route-with-a-parameter"><strong>How to Configure a Route with a Parameter</strong></h2>
<p>Whether we use Activated Route or an input property, we first need to configure our route with a parameter.</p>
<p>As an example, let's say we have a Product List component that displays a list of products as shown in Figure 1. When the user clicks a product name, we load the Product Detail component to display detail for that product (Figure 2).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-53.png" alt="Image" width="600" height="400" loading="lazy">
<em>Figure 1. List of products (Product List component)</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-54.png" alt="Image" width="600" height="400" loading="lazy">
<em>Figure 2. Detail for product with an id of 5 (Product Detail component)</em></p>
<p>To achieve this feature, the Product List component adds the id of the selected product to the route as a parameter. This is shown in the address bar in Figure 2. The Product Detail component reads that id from the route parameter and uses it to display the selected product's detail.</p>
<p>The configuration for the product detail route looks like this:</p>
<pre><code class="lang-typescript">  { path: <span class="hljs-string">':id'</span>, component: ProductDetailComponent }
</code></pre>
<p>We identify a route parameter by adding a colon before the parameter name, which in this example is <code>id</code>. Anywhere we reference this parameter we'll use this name.</p>
<p>The product detail route is activated when the user clicks on a product link in the Product List component. The code for that link uses the <code>routerLink</code> directive to set the id parameter:</p>
<pre><code class="lang-html"> <span class="hljs-tag">&lt;<span class="hljs-name">a</span> [<span class="hljs-attr">routerLink</span>]=<span class="hljs-string">"[product.id]"</span>&gt;</span> {{ product.productName }} <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>When the user clicks on this link, the <code>routerLink</code> adds the product's id to the URL. The router uses the route configuration to find a matching route path and routes to the Product Detail component.</p>
<p>Code in the Product Detail component then reads the parameter from the URL and displays the product's detail.</p>
<h2 id="heading-how-to-read-route-parameters-activated-route">How to Read Route Parameters (Activated Route)</h2>
<p>One technique to read the parameter from the URL uses Angular's Activated Route service.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, OnInit, inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { ActivatedRoute } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;


  <span class="hljs-keyword">private</span> route = inject(ActivatedRoute);

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">const</span> id = <span class="hljs-built_in">Number</span>(<span class="hljs-built_in">this</span>.route.snapshot.paramMap.get(<span class="hljs-string">'id'</span>));
    <span class="hljs-keyword">if</span> (id) {
      <span class="hljs-built_in">this</span>.productDetailService.setSelectedProductId(id);
    }
  }
</code></pre>
<p>We first inject the Activated Route service using Angular's new <code>inject()</code> keyword. Alternatively, we could use the constructor to inject this service dependency.</p>
<p>To read the parameter when the Product Detail component first loads, we use the OnInit lifecycle hook. We declare a constant for the parameter. Then we set that constant using the Activated Route service. We access the route snapshot's <code>paramMap</code>, and call its <code>get()</code>  method, passing in the name of the parameter to get. This name must match the parameter name we defined in the route configuration.</p>
<p>Route parameters are strings so the <code>get()</code> method returns a string, or null if the parameter isn't found. In this example, the product ids are numbers. So we use the <code>Number()</code> constructor to create a number from the string.</p>
<p>If the code successfully reads the id from the route, we set that id into the Product Detail service. The Product Detail service then finds the product with the defined id. Our component binds to the resulting product and displays that product's detail.</p>
<p>We can simplify this code if we use the <code>@Input()</code> decorator instead.</p>
<h2 id="heading-how-to-start-using-input-for-route-parameters"><strong>How to Start Using <code>@Input()</code> for Route</strong> Parameters</h2>
<p>The first thing we need to do, and the step I so often forget, is to let Angular know that we want to use input properties to read route parameters. We do that in the application configuration.</p>
<p>How we do that depends on the type of bootstrapping our application uses.</p>
<p>With standalone component bootstrapping, we bootstrap an application like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { bootstrapApplication } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser'</span>;
<span class="hljs-keyword">import</span> { appConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app/app.config'</span>;
<span class="hljs-keyword">import</span> { AppComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app/app.component'</span>;

bootstrapApplication(AppComponent, appConfig)
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(err));
</code></pre>
<p>Then, in the <code>appConfig</code>, we provide the routes like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { ApplicationConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { provideRouter, withComponentInputBinding } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">import</span> { provideHttpClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/common/http'</span>;
<span class="hljs-keyword">import</span> { routes } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.routes'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(),
    provideRouter(routes, withComponentInputBinding())
  ]
};
</code></pre>
<p>The <code>provideRouter()</code> function sets up the providers for the router. We pass in the routes <em>and</em>  <code>withComponentInputBinding()</code>. It's the <code>withComponentInputBinding()</code> that let's Angular know that we want to use input properties to read route parameters.</p>
<p>If you are instead using NgModule bootstrapping, the code looks something like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { platformBrowserDynamic } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser-dynamic'</span>;
<span class="hljs-keyword">import</span> { AppModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app/app.module'</span>;

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> <span class="hljs-built_in">console</span>.error(err));
</code></pre>
<p>In this example, the<code>AppModule</code> imports the <code>AppRoutingModule</code> which looks like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { RouterModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">import</span> { WelcomeComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./home/welcome.component'</span>;

<span class="hljs-meta">@NgModule</span>({
  imports: [
    RouterModule.forRoot([
      { path: <span class="hljs-string">'welcome'</span>, component: WelcomeComponent },
      { path: <span class="hljs-string">''</span>, redirectTo: <span class="hljs-string">'welcome'</span>, pathMatch: <span class="hljs-string">'full'</span> },
      {
        path: <span class="hljs-string">'products'</span>,
        loadChildren: <span class="hljs-function">() =&gt;</span>
          <span class="hljs-keyword">import</span>(<span class="hljs-string">'./products/product.module'</span>).then(<span class="hljs-function"><span class="hljs-params">m</span> =&gt;</span> m.ProductModule)
      },
      { path: <span class="hljs-string">'**'</span>, redirectTo: <span class="hljs-string">'welcome'</span>, pathMatch: <span class="hljs-string">'full'</span> }
    ], { bindToComponentInputs: <span class="hljs-literal">true</span> })
  ],
  <span class="hljs-built_in">exports</span>: [RouterModule]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppRoutingModule { }
</code></pre>
<p>In the <code>RouterModule.forRoot()</code>, we set <code>bindToComponentInputs</code> to true to let Angular know that we want to use input properties to read route parameters.</p>
<p>We've now enabled the automatic route parameter mapping using input properties.</p>
<h2 id="heading-how-to-read-route-parameters-input"><strong>How to Read Route Parameters (@Input)</strong></h2>
<p>We add an input property using the <code>@Input()</code> decorator.</p>
<pre><code class="lang-typescript">  <span class="hljs-meta">@Input</span>() id = <span class="hljs-string">''</span>;
</code></pre>
<p>We can name the input property the same as the route parameter, which in this example is <code>id</code>. Route parameters are strings, so we set the initial value to an empty string.</p>
<p>If we want to use a different property name, such as <code>productId</code>, we can. But then we need to pass the route parameter name to the <code>@Input()</code> decorator, like this:</p>
<pre><code class="lang-typescript"><span class="hljs-meta">@Input</span>(<span class="hljs-string">'id'</span>) productId =<span class="hljs-string">''</span>;
</code></pre>
<p>That way, Angular can match up the route parameter to the appropriate input property.</p>
<p>We can then simplify the <code>OnInit</code> lifecycle hook code like this:</p>
<pre><code class="lang-typescript">  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.id) {
      <span class="hljs-built_in">this</span>.productDetailService.setSelectedProductId(<span class="hljs-built_in">Number</span>(<span class="hljs-built_in">this</span>.id));
    }
  }
</code></pre>
<p>Since we're using an input property, we no longer need the Activated Route. We can simply access the input property directly. Since the <code>setSelectedProductId()</code> method is expecting a number, we add the <code>Number()</code> constructor around the id to convert it to a number.</p>
<h2 id="heading-how-to-transform-input-properties"><strong>How to Transform Input Properties</strong></h2>
<p>Starting with Angular v16.1, the <code>@Input()</code> decorator provides a <code>transform</code> function. We use the <code>transform</code> function to perform a transformation or execute other logic when an input property changes.</p>
<p>To further simplify our code, Angular introduced two built-in transformation functions: <code>booleanAttribute</code> and <code>numberAttribute</code>.</p>
<p>For our case, we want to transform the route parameter string, to a number. Using a transformation function, our code then looks like this:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">import</span> { Component, OnInit, Input, numberAttribute } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;


  <span class="hljs-meta">@Input</span>({transform: numberAttribute}) id = <span class="hljs-number">0</span>;

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.id) {
      <span class="hljs-built_in">this</span>.productDetailService.setSelectedProductId(<span class="hljs-built_in">this</span>.id);
    }
  }
</code></pre>
<p>We pass an object to the <code>@Input()</code> decorator and set the <code>transform</code> function to <code>numberAttribute</code>. Since the string route parameter is then transformed to a number, we change the initial value to <code>0</code> in place of an empty string <code>''</code>. And now that the resulting id is a number, we no longer need to convert it ourselves with the <code>Number()</code> creation function.</p>
<h2 id="heading-why-use-route-parameters"><strong>Why Use Route Parameters?</strong></h2>
<p>One question I always like to ask myself is "why". Why do we need route parameters at all? Couldn't the Product List component store the id in a property of a service? Then the Product Detail component could read that id from the service instead of from the route.</p>
<p>One key reason is that by appending the id to the URL, we get <strong>deep linking</strong>. Deep linking allows the user to save or share the URL and have it automatically directly link to a specific product.</p>
<p>Say that your birthday is coming up and you send a friend an Amazon link. That link wouldn't be useful if it didn't navigate directly to a specific product.</p>
<p>Use deep linking any time you want to allow your users to save or send direct links.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Starting with Angular v16, we can use an input property, defined with the <code>@Input()</code> decorator, to access route parameters. This gives us a shorter and easier syntax. We no longer need to work with Angular's Activated Route service.</p>
<p>But don't forget to enable this functionality!</p>
<ul>
<li>If you are using standalone bootstrapping, add <code>withComponentInputBinding()</code> to <code>provideRouter()</code>.</li>
<li>For classic NgModule bootstrapping, set <code>bindToComponentInputs</code> to true in  <code>RouterModule.forRoot()</code>.</li>
</ul>
<p>To see these concepts in action, check out the demo provided in this video:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Nuwn5uY8ETw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>‌‌</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use a Postman Mock Server with Angular ]]>
                </title>
                <description>
                    <![CDATA[ New front end features often require back end data support – especially where new endpoints are concerned.  For example, an application that needs an authenticated user experience may need a new /authenticate endpoint. If for any reason endpoint deve... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-a-postman-mock-server-with-angular/</link>
                <guid isPermaLink="false">66b9fa17d6f1a89d918606af</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brenda Chepkorir ]]>
                </dc:creator>
                <pubDate>Wed, 28 Jun 2023 21:47:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/pexels-christina-morillo-1181247.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>New front end features often require back end data support – especially where new endpoints are concerned. </p>
<p>For example, an application that needs an authenticated user experience may need a new <code>/authenticate</code> endpoint.</p>
<p>If for any reason endpoint development is stalled or lags behind, despite the sprint planning, you will be faced with the question: <em>do you build with or without the data?</em></p>
<p>Fortunately, there is a third option: building with mock data  (which could work depending on your use case). This option is especially beneficial when the feature is a must-have by the end of a sprint. </p>
<p>Some other pros of having mock data handy include:</p>
<ul>
<li>Better testing with different API response data</li>
<li>Secure testing with de-identified data</li>
<li>Re-usable test data</li>
<li>Smoother demos — just in case the real server decides to be offline</li>
</ul>
<p>There are multiple tools that can help with creating and using mock data, such as <a target="_blank" href="https://www.postman.com/">Postman</a> and its <a target="_blank" href="https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/">mock servers</a>. You can also integrate these tools in front end applications for use in development.</p>
<p>A Postman mock server is straightforward to set up and integrate with an Angular application – particularly, when it is paired with an Angular interceptor. It might not be for every use case, but it offers a convenient way of working with mock data.</p>
<h2 id="heading-what-is-a-postman-mock-server">What is a Postman Mock Server?</h2>
<p><a target="_blank" href="https://www.postman.com/product/what-is-postman/">Postman</a> is a collaborative API platform that is designed to support the complete lifecycle of APIs. It provides tools and integrations that help with designing, documenting, testing, monitoring, sharing, and using APIs.</p>
<p>A Postman Mock Server is a dummy API server that accepts requests to endpoints you create in a <a target="_blank" href="https://learning.postman.com/docs/sending-requests/intro-to-collections/">collection</a> and returns the responses you specify in <a target="_blank" href="https://learning.postman.com/docs/sending-requests/examples/">examples</a>. It has its own <a target="_blank" href="https://www.techopedia.com/definition/4858/base-url">base URL</a> and an optional <a target="_blank" href="https://www.techtarget.com/whatis/definition/API-key">API key</a> for added security.</p>
<p>A Postman collection is a logical grouping that helps organize related requests, while a Postman example is an instance of a request in action. It is made up of the request and an expected response. </p>
<p>The <a target="_blank" href="https://learning.postman.com/docs/sending-requests/requests/">Postman documentation</a> provides more comprehensive details about collections and examples if you want to learn more.</p>
<p>Once you’ve decided to work with a Postman Mock Server, you then need to integrate it with the application in such a manner as to not:</p>
<ul>
<li>Disrupt ongoing development</li>
<li>Break the application</li>
</ul>
<p>There are two popular ways that come to mind:</p>
<ol>
<li>Using a <a target="_blank" href="https://angular.io/guide/build#proxying-to-a-backend-server">proxy</a></li>
<li>Using a <a target="_blank" href="https://angular.io/api/common/http/HttpInterceptor">HTTP Interceptor</a></li>
</ol>
<p>The major difference between these two options is that the proxy is applied at build-time, while the interceptor is applied at run-time.</p>
<h3 id="heading-what-is-a-proxy">What is a Proxy?</h3>
<p>A <a target="_blank" href="https://www.techtarget.com/whatis/definition/proxy-server">proxy server</a> is a software tool that often acts as an intermediary between a client and a server. It receives requests from the client, modifies, and diverts some of them to other servers. </p>
<p>Angular uses <a target="_blank" href="https://webpack.js.org/configuration/dev-server/#devserverproxy">Webpack's dev-server</a> as a proxy. It can be configured to divert some requests to a different server, through the <a target="_blank" href="https://angular.io/guide/build#proxying-to-a-backend-server">Angular CLI</a>. This is what makes it a viable solution to use with a Postman mock server in development. </p>
<h3 id="heading-what-is-an-angular-http-interceptor">What is an Angular HTTP Interceptor?</h3>
<p>Angular's <code>HttpInterceptor</code> is a lightweight class that can tap into an outgoing request or an incoming response. It can be used to inspect a request or transform parts of it, like the URL or headers. If you use an interceptor instead of a proxy:</p>
<ul>
<li>You can access run-time environment variables  to determine whether to divert a request to the mock server</li>
<li>You will <em>not</em> need to re-serve the application after a change to the interceptor — code changes trigger reloads (if live reloads are enabled)</li>
</ul>
<p>The proxy and the interceptor can essentially do the same thing: tap into and transform outgoing requests. However, each option has its own pros and cons. </p>
<h3 id="heading-interceptor-vs-proxy">Interceptor vs Proxy</h3>
<ul>
<li>An interceptor will require relatively less set-up than a proxy</li>
<li>A proxy will necessitate setting build-time environment variables in the system or a <code>.env</code> file (an interceptor may need this if an API key is required)</li>
<li>A change to the proxy will require the application to be re-served while a change to an interceptor will trigger a reload</li>
<li>If you are unfamiliar with setting up a proxy in Angular, there is an expected gentle learning curve. However, there is an even gentler learning curve when creating an interceptor since it's just a class</li>
</ul>
<p>Using an interceptor seems like a more straightforward option for this simple use case.</p>
<h2 id="heading-how-to-create-a-postman-mock-server">How to Create a Postman Mock Server</h2>
<p>The first step to using a mock server is to create one. First, ensure you have a Postman account and a <a target="_blank" href="https://www.postman.com/product/workspaces/">workspace</a>. You can create both from the <a target="_blank" href="https://www.postman.com/">platform's website</a>. A Postman workspace is like a dashboard that organizes your work, tools, and collaborators.</p>
<p>Then, create a Postman collection to group and organize the requests you would like the mock server to handle. </p>
<p>Next, add a request to the collection. It can be any type of <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/CRUD">CRUDL</a> request. Use your actual server's URL – like you would when testing a real endpoint. </p>
<p>Here's a snapshot of a workspace with a collection and a GET request:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/create-and-send-req.png" alt="Image" width="600" height="400" loading="lazy">
<em>A collection with a request</em></p>
<p>Next, test your endpoint by sending the request. Do this until you get a successful response back then save the response as a Postman example. You can update the example by removing any sensitive data like user information or PII. </p>
<p>Here's a snapshot of an updated example. Some user information has been replaced with some mock data using Postman variables.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/add-example.png" alt="Image" width="600" height="400" loading="lazy">
<em>An updated example for a request</em></p>
<p>Finally, create a Postman mock server from the collection you just created. You can do this by clicking on the ellipsis beside the collection and selecting <code>Mock collection</code> (at least, at the time of this writing). Here's a snapshot of these steps.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/mock-collection.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to create a mock server from a collection</em></p>
<p>You will be presented with a simple form that will allow you to configure the mock server. </p>
<p>For example, you can rename the mock server or make it private–this means it will need an API key. </p>
<p>Once the mock server is configured, click <code>Create Mock Server</code> . You will then be provided with a URL for the server. Copy the URL.</p>
<p>To associate the mock server with your requests and examples, go into the collection and update the URLs. Replace the base URLs of the requests and examples with the copied mock server's base URL. Send a few requests within Postman to verify that your set up was successful.</p>
<p><strong>Note:</strong></p>
<ul>
<li>If your API is private, you can generate an API key from the settings in your account</li>
<li>Your mock server keeps a log of the requests it receives which you can view in your workspace</li>
</ul>
<p>After creating the mock server, create the interceptor in your Angular application.</p>
<p>For more information, you can refer to the <a target="_blank" href="https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/#creating-mock-servers">documentation</a>. </p>
<h3 id="heading-how-to-create-an-angular-http-interceptor">How to Create an Angular HTTP Interceptor</h3>
<p>An interceptor is an injectable class that implements Angular’s <code>HttpInterceptor</code> interface. </p>
<p>This interface has one required method — the <code>intercept</code> method. This method primarily does one thing: it takes request and handler arguments and passes the request to the <code>next</code> method of the handler. Requests can be altered before they are passed on to the handler.</p>
<pre><code class="lang-typescript"><span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ApiInterceptor <span class="hljs-keyword">implements</span> HttpInterceptor {
  intercept(req: HttpRequest&lt;unknown&gt;, next: HttpHandler):
    Observable&lt;HttpEvent&lt;unknown&gt;&gt;
  {
    <span class="hljs-keyword">return</span> next.handle(req);
  }
}
</code></pre>
<p>To use a created interceptor in the application, add it to the <code>providers</code> array at the same level where the <code>HttpClientModule</code> is imported:</p>
<pre><code class="lang-typescript">[{ provide: HTTP_INTERCEPTORS, useClass: ApiInterceptor, multi: <span class="hljs-literal">true</span> }]
</code></pre>
<p>This is so it can be managed by Angular’s Dependency Injection system as optional dependencies of the <code>HttpClient</code> service. The <code>HttpClient</code> service is used for making HTTP requests.</p>
<p>Note that when it comes to using interceptors, order is important. </p>
<p>For example, if you provide another interceptor that adds authentication headers after an API interceptor that adds an API key header, the request may send unnecessary headers to the mock server.</p>
<p>Finally, integrate the mock server with your application.</p>
<p>For more information, refer to the <a target="_blank" href="https://angular.io/guide/http-intercept-requests-and-responses">documentation</a>.</p>
<h3 id="heading-how-to-use-an-angular-http-interceptor-with-a-postman-mock-server">How to Use an Angular Http Interceptor with a Postman Mock Server</h3>
<p>First, s<a target="_blank" href="https://angular.io/guide/build#configuring-application-environments">pecify an environment variable</a> to toggle between mock data and real data. Environment variables in Angular are primarily defined as TypeScript variables in environment files:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// environment.ts file</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> environment = {
  production: <span class="hljs-literal">false</span>,
  useMock: <span class="hljs-literal">true</span>,
  postman: {
    baseUrl: <span class="hljs-string">"postman-mock-server-url"</span>,
    apiKey: <span class="hljs-string">"optional-mock-server-api-key"</span>
  }
};
</code></pre>
<p>At least for framework versions &lt;15.</p>
<p>Then, use the environment variable in the interceptor. Where you can clone an outgoing request and update its URL before passing it to the handler:</p>
<pre><code class="lang-typescript"><span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ApiInterceptor <span class="hljs-keyword">implements</span> HttpInterceptor {
  intercept(req: HttpRequest&lt;unknown&gt;, next: HttpHandler):
    Observable&lt;HttpEvent&lt;unknown&gt;&gt;
  {
    <span class="hljs-keyword">if</span> (environment.useMock) {
      <span class="hljs-comment">// optional headers</span>
      <span class="hljs-keyword">const</span> headers = <span class="hljs-keyword">new</span> HttpHeaders({
        <span class="hljs-string">"x-api-key"</span>: <span class="hljs-string">"my-api-key"</span>
      });
      <span class="hljs-keyword">const</span> cloneReq = req.clone({ url: <span class="hljs-built_in">this</span>.getUpdatedURL(req.url), headers });
      <span class="hljs-keyword">return</span> next.handle(cloneReq);
    }
    <span class="hljs-keyword">return</span> next.handle(req);
  }
}
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>To summarize, using mock data in applications, especially data-intensive ones, can be cumbersome. But they do have their merits. </p>
<p>Reusable mock data helps make testing better and more secure particularly if the data is varied and de-identified. Furthermore, they help progress development while real data are unavailable.</p>
<p>There are a couple of tools that help with creating and managing mock data through mock servers, like Postman. </p>
<p>These tools are not only nifty for API and back end software engineers, but also for front end software engineers.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Hide Your Angular Properties – # vs private Explained ]]>
                </title>
                <description>
                    <![CDATA[ By Deborah Kurata Have you noticed a hash symbol showing up in Angular code samples? If not, you may see it soon. What is the purpose of the # and when should you use it? The # symbol was recently added to JavaScript to denote private class propertie... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-vs-typescript-private-in-angular-explained/</link>
                <guid isPermaLink="false">66d45e0c182810487e0ce13d</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 20 Jun 2023 20:39:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/hash-v-private-thumbnail.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Deborah Kurata</p>
<p>Have you noticed a hash symbol showing up in Angular code samples? If not, you may see it soon. What is the purpose of the <code>#</code> and when should you use it?</p>
<p>The <code>#</code> symbol was recently added to JavaScript to denote private class properties. Making a class variable private means that the variable can only be accessed within its class. That allows us to encapsulate data we only want to access within a service.</p>
<p>But don't we already have a private accessor for our class fields? Yep!</p>
<p>Then why do we need the new hash syntax?</p>
<p>Let's take a look at the private accessor first, then examine the <code>#</code> syntax and why it is a better choice in our Angular applications.</p>
<p>You can watch the associated video here for a demonstration:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/487iCAnhxCM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-the-danger-of-public-class-properties">The Danger of Public Class Properties</h2>
<p>Let's start by creating a property in a service and attempt to access it from our component. For this example, we have a Product service and a Product component. </p>
<p>In the Product service, we create a property for the URL that we'll use to get our product data. And a <code>products</code> property to hold our retrieved array of products.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Service</span>
<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ProductService {
  productUrl = <span class="hljs-string">'api/products'</span>;
  products = [];

}
</code></pre>
<p>To verify the value of the URL, let's create a method to log it:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Service</span>
logUrl() {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Url:'</span>, <span class="hljs-built_in">this</span>.productUrl);
}
</code></pre>
<p>Then we'll call that method in the Product service constructor:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Service</span>
<span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
  <span class="hljs-built_in">this</span>.logUrl();
}
</code></pre>
<p>By default, variables we define in a class are public, meaning that any other code in our application can access them. So we should be able to access our Product service properties from our component.</p>
<p>Let's give it a try. In the Product component, we first inject the service. In this example, we use the new <code>inject</code> function for dependency injection instead of the constructor. And add <code>inject</code> to the import statement from <code>@angular/core</code>.</p>
<p>Then we add a constructor. And because by default any property or method of a class is public, we can change the URL that we defined in the service. For confirmation, we'll call the service method to log the URL.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Component</span>
productService = inject(ProductService);

<span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
  <span class="hljs-built_in">this</span>.productService.productUrl = <span class="hljs-string">`api/nefarious`</span>;

  <span class="hljs-built_in">this</span>.productService.logUrl();
}
</code></pre>
<p>If we run the application and open the developer tools, we first see the service log the URL, then we see the component's changed URL (Figure 1).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-191.png" alt="Console log includes api/products and api/nefarious" width="600" height="400" loading="lazy">
<em>Figure 1. Resulting console output.</em></p>
<p>Well...that's not good. Our component was able to change the URL defined in our service.</p>
<h2 id="heading-typescripts-private-accessibility-feature">TypeScript's Private Accessibility Feature</h2>
<p>To better protect our service properties from being modified outside of the service, we use <strong>private accessibility</strong>. </p>
<p>Private accessibility is a feature of TypeScript. It marks a class property or method so that it is only accessible from within the class. The property or method is not available from any other component or service. </p>
<p>To use private accessibility, we add the <code>private</code> keyword in front of the variable name.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Service</span>
<span class="hljs-keyword">private</span> productUrl = <span class="hljs-string">'api/products'</span>;
</code></pre>
<p>Since we are currently modifying this property in the component, the component code now generates an error: <code>Property 'productUrl' is private and only accessible within class 'ProductService'.</code> Great! Our component can no longer access the private property from our service.</p>
<p>By adding the TypeScript private accessibility keyword in front of a property in the service, the variable is only accessible from that service.</p>
<p>But, going back to the component, what if we try to do something like this:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Component</span>
<span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">this</span>.productService) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'properties:'</span>, i);
  }

  <span class="hljs-built_in">this</span>.productService.logUrl();
}
</code></pre>
<p>The <code>for...in</code> loop iterates over the properties of an object. In this example, we display each property to the console. The result is shown in Figure 2:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-192.png" alt="Console log includes productUrl and products" width="600" height="400" loading="lazy">
<em>Figure 2. Resulting console output</em></p>
<p>Notice that it displays both our public and private properties. Now that we can see the name of the private property, we can use it to update that private property.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Component</span>
<span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">this</span>.productService) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'properties:'</span>, i);
  }

  <span class="hljs-built_in">this</span>.productService[<span class="hljs-string">'productUrl'</span>]= <span class="hljs-string">'api/nefarious'</span>;
  <span class="hljs-built_in">this</span>.productService.logUrl();
}
</code></pre>
<p>Oops! We've again modified our service property from our component. Our private property isn't so private.</p>
<p>Why is that? It's because the <code>private</code> keyword is part of TypeScript, not JavaScript. That means that the private accessibility is only enforced during development, as part of type checking, and during compilation. We get notifications during development and compilation that we can't access the private property from outside its class.</p>
<p>But when our TypeScript code is transpiled to JavaScript and executed, the private keyword is gone. That means the JavaScript runtime constructs such as our <code>for...in</code> loop or simple property lookup, can still access a property or method defined with the <code>private</code> keyword. In other words, the component can access the private properties in our service at runtime. Yikes!</p>
<h2 id="heading-javascripts-private-class-members"><strong>JavaScript's Private Class Members (#)</strong></h2>
<p>Using the JavaScript <code>#</code> syntax solves that problem. Recently, JavaScript added private class properties and methods, denoted with a <code>#</code>. Since the <code>#</code> is part of JavaScript, it denotes our properties and methods as private during development, compilation, and at runtime.</p>
<p>In the Product service, let's remove the <code>private</code> keyword and add <code>#</code>. The <code>#</code> is a prefix on the variable itself, and becomes part of the variable name. So we need to change the variable name wherever we access it, such as in our <code>logUrl</code> method.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Service</span>
<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ProductService {
  #productUrl = <span class="hljs-string">'api/products'</span>;
  products = [];

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) { 
    <span class="hljs-built_in">this</span>.logUrl();
  }

  logUrl() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Url:'</span>,<span class="hljs-built_in">this</span>.#productUrl);
  }
}
</code></pre>
<p>We now see an error where we access the property in the Product component: <code>Property 'productUrl' does not exist on type 'ProductService'. Did you mean '#productUrl'?</code></p>
<p>We can try changing our property lookup code in the component to include a <code>#</code> as well.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Product Component</span>
<span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">this</span>.productService) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'properties:'</span>, i);
  }

  <span class="hljs-built_in">this</span>.productService[<span class="hljs-string">'#productUrl'</span>]= <span class="hljs-string">'api/nefarious'</span>;
  <span class="hljs-built_in">this</span>.productService.logUrl();
}
</code></pre>
<p>But the property is still not found: <code>Property '#productUrl' does not exist on type 'ProductService'</code>. The private property in our service is now correctly hidden from our component. We'll need to delete the property lookup line that accesses <code>#productUrl</code> for our code to compile successfully.</p>
<p>Looking at the console (Figure 3), notice that our <code>for...in loop</code> now finds the public <code>products</code> property, but not the private <code>productsUrl</code> property. Our private property is private and hidden, correctly encapsulated in our service.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-193.png" alt="Console log includes products, not productUrl" width="600" height="400" loading="lazy">
<em>Figure 3. Resulting console output</em></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>As Angular developers, we've been using the Typescript <code>private</code> accessibility keyword to make properties or methods private. But that only protects the property at development and compile type, not runtime.</p>
<p>Now we can use the JavaScript private class property syntax (denoted with the <code>#</code> symbol) to make private properties and methods truly private and hidden from other parts of our code.</p>
<p>To see these concepts in action, check out the demo provided in this video:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/487iCAnhxCM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Front End JavaScript Development Handbook – React, Angular, and Vue Compared ]]>
                </title>
                <description>
                    <![CDATA[ Frontend frameworks are indispensable in web development. They provide structured approaches and pre-defined components to streamline the coding process. These tools can also help boost productivity by offering reusable components and abstracting com... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/front-end-javascript-development-react-angular-vue-compared/</link>
                <guid isPermaLink="false">66d45d5c3a8352b6c5a2a9f5</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vue ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Adekola Olawale ]]>
                </dc:creator>
                <pubDate>Thu, 08 Jun 2023 13:57:21 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/frontend-framework-cover.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Frontend frameworks are indispensable in web development. They provide structured approaches and pre-defined components to streamline the coding process.</p>
<p>These tools can also help boost productivity by offering reusable components and abstracting complex tasks like DOM manipulation and state management. This allows developers to focus on application logic rather than writing repetitive code.</p>
<p>Frameworks promote code maintainability through modular development, making it easier to modify or replace individual components. They also make collaboration easier as multiple developers can work simultaneously on different parts of an application.</p>
<h3 id="heading-benefits-of-using-libraries-and-frameworks">Benefits of Using Libraries and Frameworks</h3>
<p>With vibrant developer communities, these frameworks offer extensive support, tutorials, and documentation. Leveraging frontend frameworks empowers developers to create beautiful and highly functional web applications that meet modern user expectations.</p>
<p>Frontend frameworks provide numerous benefits for beginners in web development as well. They offer a structured approach and pre-built components, simplifying the development process and saving time.</p>
<p>Beginners can leverage the power of these frameworks to create visually appealing and interactive user interfaces without needing to start from scratch.</p>
<p>The extensive community support and resources available for popular tools like React, Angular, and Vue make it easier for beginners to learn and grow their skills. By embracing frontend frameworks, beginners can accelerate their learning curve, and build impressive web applications.</p>
<h3 id="heading-learn-vanilla-javascript-first">Learn Vanilla JavaScript First</h3>
<p>Before delving into JavaScript frameworks, it is crucial for you to grasp the basics of plain JavaScript. Understanding the fundamentals of JavaScript, such as variables, functions, and control structures lays a strong foundation for learning and utilizing frameworks effectively.</p>
<p>By learning the core concepts of JavaScript, you also gain insights into how the language works and can solve problems without relying solely on the abstractions provided by frameworks. This knowledge empowers you to write cleaner, more efficient code and arms you with the ability to customize and extend frameworks to suit their specific needs.</p>
<p>Understanding JavaScript also enables you to troubleshoot issues, comprehend error messages, and make informed decisions when working with frameworks. By mastering the basics, you can unlock the full potential of JavaScript frameworks and leverage their power to create dynamic, interactive web applications.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-react">What is React</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-angular">What is Angular</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-vuejs">What is Vue.js</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-comparing-javascript-frameworks">Comparing JavaScript Frameworks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-choose-the-right-framework-for-your-project">How to Choose the Right Framework for Your Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#resources-for-learning-js-frameworks-and-getting-started">Resources for Learning JS Frameworks and Getting Started</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-react">What is React?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/React-Logo-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>React Logo</em></p>
<p>React is a popular JavaScript library used for building user interfaces. It follows a component-based architecture, where UI elements are divided into reusable components.</p>
<p>React utilizes a Virtual DOM, which is a lightweight representation of the actual DOM, to efficiently update and render components. This approach allows for fast and responsive user interfaces.</p>
<p>React promotes a one-way data flow, making it easier to manage application state and update UI components efficiently. It provides lifecycle methods that allow developers to perform actions at different stages of a component's lifecycle, such as fetching data, handling events, and updating the UI accordingly.</p>
<p>It has a robust ecosystem with various libraries and tools that extend its capabilities. These include React Router for routing, Redux for state management, and React Native for building native mobile applications. This ecosystem offers solutions to common development challenges and facilitates rapid development.</p>
<p>React's component-based architecture, Virtual DOM, JSX syntax, and extensive ecosystem make it a powerful choice for building dynamic and reusable user interfaces. Understanding the basics of React sets the foundation for exploring its features and capabilities in more depth.</p>
<h3 id="heading-react-setup-installation-project-creation-and-server-start">React Setup: Installation, Project Creation, and Server Start</h3>
<p>To get started with React, you need to set up your development environment by installing React, creating a new project, and starting the development server.</p>
<p>Below outlines the steps to install React, create a new React project, and start the development server:</p>
<p><strong>Step 1:</strong> Install Node.js and npm (if not already installed)</p>
<p><strong>Step 2:</strong> Open your terminal or command prompt.</p>
<p><strong>Step 3:</strong> Install the Create React App CLI globally by running the following command:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/install-react-app.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Install React App</em></p>
<pre><code class="lang-bash">npm install -g create-react-app
</code></pre>
<p><strong>Step 4:</strong> Create a new React project by running the following command:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/create-react-project.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Create React app project</em></p>
<pre><code class="lang-bash">npx create-react-app my-react-app
</code></pre>
<p><em>Note:</em> Replace <code>my-react-app</code> with the desired name of your project.</p>
<p><strong>Step 5:</strong> Once the project is created, navigate to the project directory by running the following command:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/cd-react-app.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Change Directory</em></p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> my-react-app
</code></pre>
<p><strong>Step 6:</strong> Start the development server by running the following command:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/react-npm-start.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Starting React Development Server</em></p>
<pre><code class="lang-bash">npm start
</code></pre>
<p>This will start the development server, and you can view your React app by visiting <a target="_blank" href="http://localhost:3000">http://localhost:3000</a> in your browser.</p>
<p>These steps will install React, create a new React project with Create React App, and start the development server. You can then begin building your React application.</p>
<h3 id="heading-react-and-its-key-features">React and its Key Features</h3>
<p>React's many features make it one of the most popular choices among developers. Its range of powerful features empowers developers to build dynamic and interactive user interfaces in a flexible and efficient way.</p>
<h4 id="heading-component-based-architecture">Component-Based Architecture</h4>
<p>React follows a component-based approach, where UI elements are broken down into reusable and self-contained components. This modularity promotes code reusability, maintainability, and scalability.</p>
<p>In React, the component-based architecture is a fundamental concept that promotes code reusability and modular development. Components are the building blocks of a React application, and they can be thought of as self-contained, reusable pieces of code that encapsulate both the UI (User Interface) and the logic.</p>
<p>Check out this snippet of code that exemplifies the creation of a simple functional component in React:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Greeting</span>(<span class="hljs-params">props</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {props.name}!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Greeting;
</code></pre>
<p>In the code snippet above, we define a functional component called <code>Greeting</code>. This component takes in a prop called <code>name</code> and renders a greeting message with the value of the <code>name</code> prop.</p>
<p>The component-based architecture allows you to break down your application into smaller, reusable components. Each component can have its own state, props, and lifecycle methods, making it easier to manage and maintain your codebase. Components can be composed and nested together to create complex user interfaces.</p>
<p>By separating your application into components, you can achieve better organization, code reusability, and maintainability. You can easily reuse components across different parts of your application or even in different projects. This approach also enables a more efficient development workflow, as components can be developed and tested independently.</p>
<p>With the component-based architecture in React, you have the flexibility to build modular, scalable, and maintainable applications, making React a powerful tool for front-end development.</p>
<h4 id="heading-virtual-dom">Virtual DOM</h4>
<p>React utilizes a Virtual DOM, which is a lightweight representation of the actual DOM. By using the Virtual DOM, React efficiently updates and renders components, resulting in faster and smoother user interfaces.</p>
<p>One of the key features of React is its use of a Virtual DOM (Document Object Model). The Virtual DOM is a lightweight representation of the actual DOM, a tree-like structure that represents the HTML elements of a web page. It acts as an intermediary layer between the application's logic and the browser's rendering engine.</p>
<p>Dive into this code example to understand how the Virtual DOM works in React:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-built_in">super</span>(props);
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>,
    };
  }

  handleClick() {
    <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">count</span>: <span class="hljs-built_in">this</span>.state.count + <span class="hljs-number">1</span> });
  }

  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Count: {this.state.count}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> this.handleClick()}&gt;Increment<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Counter;
</code></pre>
<p>In the code snippet above, we have a <code>Counter</code> component that displays a count value and a button to increment the count. Whenever the button is clicked, the <code>handleClick</code> function updates the component's state using <code>setState</code>, triggering a re-render of the component.</p>
<p>Behind the scenes, React creates a Virtual DOM representation of the component's UI structure. When a state change occurs, React efficiently calculates the difference between the previous Virtual DOM and the updated Virtual DOM. This process is known as reconciliation.</p>
<p>React then applies the necessary changes to the actual DOM, updating only the specific parts that have changed. This approach helps optimize performance by minimizing DOM manipulations and updates.</p>
<p>By using the Virtual DOM, React provides a more efficient way of updating the user interface. It reduces the number of direct manipulations on the actual DOM, resulting in faster rendering and improved application performance.</p>
<p>The Virtual DOM also enables a declarative programming model, where developers specify how the UI should look based on the application's state, and React takes care of updating the actual DOM accordingly.</p>
<h4 id="heading-jsx-syntax">JSX Syntax</h4>
<p>React introduced JSX, a syntax extension that combines JavaScript and XML-like syntax. It allows developers to write HTML-like code within JavaScript, making component templates more intuitive and readable.</p>
<p>JSX (JavaScript XML) is an important feature of React that allows developers to write HTML-like syntax directly within JavaScript code. It provides a concise and expressive way to define the structure and appearance of React components.</p>
<p>Let's explore a practical code snippet that demonstrates the usage of JSX in React:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Greeting</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  render() {
    <span class="hljs-keyword">const</span> name = <span class="hljs-string">'John Doe'</span>;

    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {name}!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Greeting;
</code></pre>
<p>In the code snippet above, we have a <code>Greeting</code> component that renders a heading element with a dynamic name value. Within the JSX syntax, we can embed JavaScript expressions using curly braces <code>{}</code>. In this case, the <code>name</code> variable is dynamically inserted into the rendered output.</p>
<p>JSX provides several advantages:</p>
<ol>
<li><p><strong>Readability</strong>: JSX resembles HTML syntax, making it easy to read and understand the structure of the component's UI.</p>
</li>
<li><p><strong>Expressiveness</strong>: JSX allows you to express complex UI structures and logic in a concise and declarative manner.</p>
</li>
<li><p><strong>Component composition</strong>: JSX enables the composition of multiple components, allowing you to build reusable and modular UI elements.</p>
</li>
<li><p><strong>Full power of JavaScript</strong>: Since JSX is essentially JavaScript, you can utilize the full power of the JavaScript language, including variables, functions, and control flow statements, within the JSX code.</p>
</li>
</ol>
<p>Under the hood, React's JSX code is transpiled into regular JavaScript code that creates and manipulates React elements. This transpilation process is typically handled by build tools like Babel.</p>
<p>By leveraging JSX, developers can build dynamic and interactive user interfaces with ease, combining the power of JavaScript with the familiar syntax of HTML. It simplifies the process of creating and maintaining complex UI structures, making React development more efficient and enjoyable.</p>
<h4 id="heading-one-way-data-flow">One-Way Data Flow</h4>
<p>React implements a one-way data flow, ensuring that data flows in a single direction. This makes it easier to manage application state and predict how changes will affect the UI. It promotes better control and maintainability of the application's data flow.</p>
<p>Another one of the key features of React is its one-way data flow, which ensures a predictable and efficient approach to managing data within components. In React, data flows in a unidirectional manner, from parent components to child components.</p>
<p>Here's a code snippet that illustrates the one-way data flow in React:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ParentComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-built_in">super</span>(props);
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">message</span>: <span class="hljs-string">'Hello from Parent'</span>,
    };
  }

  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> <span class="hljs-attr">message</span>=<span class="hljs-string">{this.state.message}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ChildComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  render() {
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{this.props.message}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
  }
}
</code></pre>
<p>In the code snippet above, we have a <code>ParentComponent</code> that holds a state variable called <code>message</code>. This state is then passed down to the <code>ChildComponent</code> as a prop. The child component simply renders the value of the <code>message</code> prop.</p>
<p>The one-way data flow ensures that changes in the parent component's state propagate down to child components, triggering re-rendering only in the affected components. This approach helps to maintain the integrity and predictability of the application's data.</p>
<p>By enforcing one-way data flow, React promotes better code organization and makes it easier to reason about how data changes affect the UI. It also simplifies debugging and ensures better performance by minimizing unnecessary re-renders.</p>
<p>React's one-way data flow ensures a clear and predictable flow of data from parent to child components. This feature helps in maintaining the application's state consistency, improving code readability, and optimizing rendering performance.</p>
<h4 id="heading-component-lifecycle-methods">Component Lifecycle Methods</h4>
<p>React provides lifecycle methods that allow developers to hook into different stages of a component's lifecycle. These methods enable actions like fetching data, handling events, and updating the UI based on specific triggers.</p>
<p>By leveraging these key features, React empowers developers to build interactive and scalable user interfaces. Its component-based architecture, efficient rendering with the Virtual DOM, JSX syntax, one-way data flow, and lifecycle methods make React a versatile and powerful tool for creating modern web applications.</p>
<p>To fully understand and harness the power of React, it's essential to grasp the concept of component lifecycle methods. These methods provide opportunities to perform specific actions at different stages of a component's life cycle.</p>
<p>Let's take a look at an example code snippet that demonstrates the usage of lifecycle methods in React:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-built_in">super</span>(props);
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>,
    };
  }

  componentDidMount() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Component has mounted!'</span>);
  }

  componentDidUpdate() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Component has updated!'</span>);
  }

  componentWillUnmount() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Component will unmount!'</span>);
  }

  handleClick = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">this</span>.setState(<span class="hljs-function">(<span class="hljs-params">prevState</span>) =&gt;</span> ({ <span class="hljs-attr">count</span>: prevState.count + <span class="hljs-number">1</span> }));
  };

  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Count: {this.state.count}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span>Increment<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
}
</code></pre>
<p>In the code snippet above, we have a <code>MyComponent</code> class-based component that showcases three essential lifecycle methods: <code>componentDidMount</code>, <code>componentDidUpdate</code>, and <code>componentWillUnmount</code>.</p>
<p><code>componentDidMount</code> is invoked immediately after the component is mounted in the DOM. It is an ideal place to fetch data from an API, set up event listeners, or perform other initialization tasks.</p>
<p><code>componentDidUpdate</code> is called after the component's state or props have been updated. It enables you to respond to changes and perform additional actions based on the updated data.</p>
<p><code>componentWillUnmount</code> is invoked just before the component is unmounted and destroyed. It allows you to clean up any resources, event listeners, or subscriptions to prevent memory leaks.</p>
<p>These lifecycle methods provide hooks into the various stages of a component's existence, enabling you to manage side effects, handle state updates, and maintain proper resource management.</p>
<p>By utilizing lifecycle methods effectively, you can enhance the behavior and functionality of your React components, ensuring optimal performance and seamless user experiences.</p>
<h3 id="heading-virtual-dom-and-component-based-architecture">Virtual DOM and Component-Based Architecture</h3>
<p>React's Virtual DOM and component-based architecture are foundational concepts that contribute to its efficiency and flexibility.</p>
<h4 id="heading-virtual-dom-1">Virtual DOM</h4>
<p>React introduces the concept of the Virtual DOM, which is a lightweight representation of the actual Document Object Model (DOM). The Virtual DOM serves as a virtual copy of the real DOM, allowing React to efficiently update and render components.</p>
<p>When there are changes in the application's state, React compares the Virtual DOM with the real DOM and applies only the necessary updates, minimizing the number of actual DOM manipulations. This approach significantly improves performance and makes React applications highly responsive.</p>
<p>Imagine you have a toy block tower. Instead of disassembling and reassembling each block to make changes, you take a picture of the tower. Then, you make the necessary modifications and refer to the picture to recreate the tower with the updated changes.</p>
<p>The toy block tower represents the web page or user interface of your application. The original tower is the initial state, and the picture is the Virtual DOM. When you make changes, the framework (like React) creates a new Virtual DOM, a lightweight copy of the actual DOM.</p>
<h4 id="heading-component-based-architecture-1">Component-Based Architecture</h4>
<p>React follows a component-based architecture, where UI elements are divided into reusable and independent components. Components are the building blocks of a React application, encapsulating their own state and behavior. This modular approach promotes reusability and maintainability.</p>
<p>Components can be composed together to create complex user interfaces. Changes made to one component do not affect other components unless explicitly specified. This separation of concerns simplifies development, testing, and code organization, making it easier to build and maintain large-scale applications.</p>
<p>Imagine you are building a LEGO house. Instead of building the entire house as one big piece, you break it down into smaller LEGO blocks, like walls, windows, and doors. Each block has its own unique features and functions.</p>
<p>Similarly, in component-based architecture, your web application is divided into smaller, self-contained building blocks called components. Each component represents a specific part of the user interface, such as a header, a navigation menu, or a button. These components are like the LEGO blocks that can be assembled and combined together to form the complete web application.</p>
<p>Just like LEGO blocks can be used in different structures, components can be reused across multiple pages or applications. This reusability saves time and effort as you don't need to recreate the same functionality or design from scratch. You can simply use the existing components and customize them as per your needs.</p>
<p>The combination of the Virtual DOM and component-based architecture makes React a powerful tool for building interactive and scalable user interfaces. The Virtual DOM enables efficient updates, while the component-based architecture promotes code reusability and modularity. Together, these concepts lay the foundation for creating robust and performant applications with React.</p>
<h3 id="heading-jsx-syntax-and-its-advantages">JSX Syntax and its Advantages</h3>
<p>JSX is a syntax extension used in React that allows developers to write HTML-like code within JavaScript. JSX plays a significant role in creating React components and has several advantages.</p>
<ol>
<li><p><strong>Readability and Familiarity:</strong> JSX combines the power of JavaScript with the familiarity of HTML-like syntax. It allows developers to write component templates in a declarative manner, making the code more readable and understandable. Developers can easily visualize the structure of the UI and the interactions between components, leading to more maintainable code.</p>
</li>
<li><p><strong>Component Composition:</strong> JSX facilitates the composition of components. Developers can nest components within each other, similar to how HTML tags are nested. This enables the creation of complex UI structures by assembling smaller, reusable components together. Component composition improves code organization, encourages reusability, and simplifies the management of application state.</p>
</li>
<li><p><strong>Inline JavaScript Expressions:</strong> JSX seamlessly integrates JavaScript expressions within curly braces <code>{}</code>. This enables dynamic content rendering and the execution of JavaScript code directly within the component template. Developers can embed variables, perform calculations, and handle conditional rendering, allowing for flexible and dynamic UI creation.</p>
</li>
<li><p><strong>Type Safety and Tooling:</strong> JSX enhances the development experience by providing improved tooling and type safety. Editors and IDEs can provide intelligent autocompletion and error checking for JSX syntax, helping to catch mistakes and improve productivity. Additionally, JSX can be statically analyzed for type checking, ensuring that the components receive the correct props and reducing runtime errors.</p>
</li>
</ol>
<p>JSX is a powerful feature that enables developers to build intuitive and dynamic user interfaces with React. By leveraging JSX syntax, React simplifies the creation of component templates, improves code readability, promotes component composition, and provides enhanced tooling support.</p>
<h2 id="heading-what-is-angular">What is Angular?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/2048px-Angular_full_color_logo.svg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Angular Logo</em></p>
<p>The Angular framework has revolutionized web development by providing a comprehensive set of tools and features for building robust and scalable applications. Developed and maintained by Google, Angular has its roots in the original framework, <em>AngularJS</em>.</p>
<p>With a focus on modern web development practices, Angular has evolved into a versatile and widely adopted framework. In this section, we will explore Angular, its origins, and the key features that make it a popular choice among developers.</p>
<p>Whether you are new to Angular or seeking to deepen your understanding, this overview will serve as a solid foundation to navigate the world of Angular development.</p>
<h3 id="heading-angular-framework-and-its-origins">Angular Framework and its Origins</h3>
<p>The Angular framework, often referred to as <em>Angular</em> or <em>Angular 2+</em>, is a powerful front-end development platform created and maintained by Google.</p>
<p>It is the successor of AngularJS, which was the first version of Angular released in 2010. AngularJS introduced the concept of two-way data binding and gained popularity for its ability to build dynamic and interactive web applications.</p>
<p>However, AngularJS had limitations in terms of performance, scalability, and maintainability. This led the Angular team to re-envision the framework. Angular was introduced as a complete rewrite of AngularJS, incorporating modern web development practices and addressing the shortcomings of its predecessor.</p>
<p>Angular was built from the ground up to be more efficient, modular, and developer-friendly. It embraced a component-based architecture, where UI elements are divided into reusable components. This modular approach promotes code reusability, maintainability, and scalability, allowing developers to build complex applications with ease.</p>
<p>The release of Angular introduced significant changes and improvements, resulting in a more streamlined and performant framework. It incorporated features like a more efficient change detection mechanism, a powerful template syntax known as Angular Template Syntax (based on HTML with additional features), enhanced dependency injection, and a revamped command-line interface (CLI) for scaffolding and managing projects.</p>
<p>Over time, Angular has evolved into a comprehensive platform with a wide range of capabilities, including advanced routing, form handling, internationalization, and powerful testing tools. It has gained popularity among developers for its robustness, scalability, and the extensive ecosystem of libraries and tools that support Angular development.</p>
<p>Understanding the origins of Angular helps developers appreciate the design principles, improvements, and rationale behind the framework. It sets the stage for exploring Angular's key features and best practices, and leveraging its full potential to build modern web applications.</p>
<h3 id="heading-understanding-angulars-modular-structure">Understanding Angular's Modular Structure</h3>
<p>One of the core strengths of Angular is its modular structure, which promotes code organization, reusability, and maintainability.</p>
<p>Angular applications are composed of modules, components, services, and other building blocks that work together to create a cohesive application.</p>
<h4 id="heading-modules">Modules</h4>
<p>In Angular, modules act as containers that group related components, services, directives, and other features. Each Angular application typically has a root module, known as the <em>AppModule</em>, which serves as the entry point of the application.</p>
<p>Modules help in organizing the application's functionality into manageable units, making it easier to maintain and understand the codebase. They also provide a way to encapsulate dependencies and provide a clean separation of concerns.</p>
<p>Modules in Angular can be likened to different rooms in a house. Imagine you have a big house with multiple rooms, each serving a specific purpose. The living room is for relaxing, the kitchen is for cooking, and the bedroom is for sleeping. Each room has its own unique function and contains the necessary furniture and equipment.</p>
<p>In Angular, modules are used to organize and encapsulate different parts of your application. If we continue with the house analogy, think of each module as a separate room in the house.</p>
<p>For example, you may have a living room module that handles all the components, services, and resources related to displaying and interacting with the living room features. Similarly, you can have a kitchen module that manages all the functionality related to cooking and food preparation.</p>
<p>Now, let's bring in the AppModule, which is the root module of an Angular application. In our house analogy, the AppModule can be compared to the main entrance or foyer of the house. Just as the main entrance connects all the rooms in a house, the AppModule serves as the entry point to your Angular application, connecting all the modules together.</p>
<p>The AppModule plays a crucial role in Angular applications. It imports and aggregates all the other modules, making them accessible to the application. It also bootstraps the application by specifying the root component that will be loaded initially.</p>
<p>Essentially, the AppModule sets the foundation for your Angular application, ensuring that all the necessary modules and components are properly connected and initialized.</p>
<p>By utilizing modules in Angular, including the AppModule, you can achieve better organization, separation of concerns, and maintainability in your application. Each module focuses on a specific area or functionality, making it easier to manage and extend your application as it grows.</p>
<p>Here's a short code snippet in Angular to demonstrate the usage of modules:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { BrowserModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser'</span>;
<span class="hljs-keyword">import</span> { AppComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.component'</span>;

<span class="hljs-meta">@NgModule</span>({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule { }
</code></pre>
<p>In this example, we have an <code>AppModule</code> class decorated with the <code>NgModule</code> decorator. Inside the decorator, we define the metadata for our module.</p>
<p>The <code>declarations</code> array lists all the components, directives, and pipes that belong to this module. Here, we have a single component <code>AppComponent</code> declared.</p>
<p>The <code>imports</code> array specifies other modules that this module depends on. In this case, we're importing the <code>BrowserModule</code>, which provides essential features for running Angular applications in a web browser.</p>
<p>The <code>providers</code> array is used to provide any services or dependencies required by the components in this module.</p>
<p>The <code>bootstrap</code> array indicates the root component of the application, which will be instantiated when the application starts. Here, we have <code>AppComponent</code> specified as the bootstrap component.</p>
<h4 id="heading-components">Components</h4>
<p>Components are the building blocks of Angular applications. They represent specific sections of the user interface and encapsulate their own styles, templates, and logic.</p>
<p>Components can be composed together to create complex UI structures. By breaking the UI into smaller, reusable components, the application becomes more modular and easier to develop and maintain.</p>
<p>Components in Angular are like building blocks that make up the different parts of a house, just like the React components I talked about earlier.</p>
<p>Imagine you are building a house using Lego bricks. Each Lego brick represents a component, and when you put them together, they form different parts of the house, such as walls, doors, and windows.</p>
<p>Similarly, in Angular, components are the basic building blocks of an application's user interface. They encapsulate a specific functionality or part of the user interface, just like the Lego bricks forming specific parts of a house.</p>
<p>For example, you can have a component for displaying a navigation menu, another component for showing a list of products, and yet another component for handling user registration.</p>
<p>Components consist of three main parts: the template, the class, and the styles. The template defines the structure and layout of the component, similar to how the Lego bricks come together to form a specific shape. The class contains the logic and data that the component needs to function, like the instructions that guide you on how to assemble the Lego bricks. The styles define the appearance and design of the component, just like the colors and patterns you choose for your Lego house.</p>
<p>When you put all the components together, just like assembling Lego bricks, you create a complete and interactive user interface for your Angular application. Each component works independently, but they can also communicate and interact with each other, allowing you to build complex and dynamic applications.</p>
<p>Components in Angular are the basic building blocks of an application's user interface, encapsulating specific functionalities. By combining and arranging components, you can create a complete and interactive user interface for your Angular application, just like assembling Lego bricks to build a house.</p>
<p>A short code snippet in Angular to demonstrate the usage of components:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-example'</span>,
  template: <span class="hljs-string">`
    &lt;h1&gt;Welcome to the Example Component!&lt;/h1&gt;
    &lt;p&gt;This is the content of the component.&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ExampleComponent {
  <span class="hljs-comment">// Component logic goes here</span>
}
</code></pre>
<p>In this example, we have an <code>ExampleComponent</code> class decorated with the <code>@Component</code> decorator. Inside the decorator, we define the metadata for our component.</p>
<p>The <code>selector</code> property specifies the HTML selector used to render the component. In this case, the selector is <code>app-example</code>, which means the component will be rendered as <code>&lt;app-example&gt;&lt;/app-example&gt;</code> in the HTML.</p>
<p>The <code>template</code> property defines the component's view or template. It contains the HTML markup that will be rendered when the component is used. In this example, we have a simple heading and paragraph.</p>
<p>The <code>ExampleComponent</code> class represents the logic and behavior of the component. Here, you can define properties and methods, and handle events related to the component.</p>
<p>Components are the building blocks of Angular applications. They encapsulate HTML, CSS, and JavaScript functionality into reusable and self-contained units. This makes it easier to develop and maintain complex user interfaces.</p>
<h4 id="heading-services">Services</h4>
<p>Services are used for sharing data, logic, and functionality across multiple components. They encapsulate reusable business logic, data access, and communication with external APIs. Services can be injected into components or other services, enabling a clear separation of concerns and promoting code reusability.</p>
<p>Services in Angular can be likened to the helpers or assistants that make a house function smoothly. Imagine you are living in a house and you have different people helping you with specific tasks. For example, you might have a cleaning service to keep your house tidy, a plumber to fix any water-related issues, and an electrician to take care of electrical matters.</p>
<p>Same thing in Angular – services are like professionals that handle specific tasks and provide the functionality to different parts of your application. They are designed to perform common tasks or provide shared functionality that multiple components may need. Just like the helpers in a house, services can be called upon when needed and provide specialized assistance.</p>
<p>For example, you can have a data service that retrieves and stores data from an external source, such as a server or a database. This data service can be used by multiple components to fetch and update data, ensuring consistency across your application.</p>
<p>Another example is an authentication service that manages user authentication and authorization. This allows different components to verify user credentials and control access to certain features.</p>
<p>Services act as a central hub of functionality that can be shared and reused throughout your application. They help to organize your code and promote a modular structure, making it easier to maintain and update your application over time.</p>
<p>They act as centralized helpers, allowing different parts of your application to access and utilize their specialized capabilities. By using services, you can create a modular and efficient application structure, just like having dedicated helpers in a house to ensure everything runs smoothly.</p>
<p>Here's a short code snippet in Angular to demonstrate the usage of services:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DataService {
  getData(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">'This is data retrieved from the DataService!'</span>;
  }
}
</code></pre>
<p>In this example, we have a <code>DataService</code> class decorated with the <code>@Injectable</code> decorator. This decorator marks the class as an injectable service, allowing it to be injected into other components or services.</p>
<p>Inside the <code>DataService</code> class, we define a <code>getData</code> method that returns a string. This method can be used to fetch data from an API, perform calculations, or any other logic related to data retrieval.</p>
<p>Services in Angular are responsible for handling data, business logic, and other shared functionality across components. They promote code reusability, separation of concerns, and provide a way to centralize common operations and data access within your application.</p>
<h4 id="heading-directives">Directives</h4>
<p>Directives are used to extend the behavior of HTML elements or create reusable custom elements. They allow developers to manipulate the DOM, add event listeners, apply dynamic styling, and perform other tasks to enhance the functionality and appearance of the application.</p>
<p>They can be compared to instructions or rules that you give to objects in your house. Imagine you have a set of toys or objects, and you want to assign certain behaviors or actions to them. You might use stickers or labels to indicate what each object should do.</p>
<p>Likewise, in Angular, directives are used to give instructions or behaviors to elements in your application's user interface. They are like special stickers that you can attach to HTML elements to define how they should behave or appear. Directives can control the visibility, style, and behavior of elements, allowing you to customize their functionality.</p>
<p>For example, you can have a <strong>highlight</strong> directive that adds a special effect to a specific HTML element, making it stand out with a different color or animation. This directive can be used to highlight important information or interactive elements on a web page.</p>
<p>Another example is the <strong>if</strong> directive, which conditionally shows or hides an element based on certain conditions. This can be used to dynamically display content based on user input or application state.</p>
<p>Directives help you create interactive and dynamic user interfaces by providing instructions to HTML elements. They are like labels that tell the elements how to behave and what to look like. By using directives, you can customize and control the behavior of elements in your application, making it more engaging and user-friendly.</p>
<p>In simple terms, directives in Angular are like special stickers that you can attach to objects in your house (HTML elements) to tell them how to behave or look. They allow you to add interactive features and customize the appearance of elements, making your application more engaging and enjoyable for users.</p>
<p>Here's a short code snippet in Angular to demonstrate the usage of a custom directive:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Directive, ElementRef, HostListener } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Directive</span>({
  selector: <span class="hljs-string">'[appHighlight]'</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> HighlightDirective {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> elementRef: ElementRef</span>) {}

  <span class="hljs-meta">@HostListener</span>(<span class="hljs-string">'mouseenter'</span>)
  onMouseEnter() {
    <span class="hljs-built_in">this</span>.highlight(<span class="hljs-string">'yellow'</span>);
  }

  <span class="hljs-meta">@HostListener</span>(<span class="hljs-string">'mouseleave'</span>)
  onMouseLeave() {
    <span class="hljs-built_in">this</span>.highlight(<span class="hljs-literal">null</span>);
  }

  <span class="hljs-keyword">private</span> highlight(color: <span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span>) {
    <span class="hljs-built_in">this</span>.elementRef.nativeElement.style.backgroundColor = color;
  }
}
</code></pre>
<p>In this example, we're creating a custom directive called <code>appHighlight</code>. This directive is applied to an HTML element using the selector <code>[appHighlight]</code>.</p>
<p>When the user hovers over the element, the <code>onMouseEnter</code> event listener is triggered, and it calls the <code>highlight</code> method to set the background color of the element to yellow.</p>
<p>Similarly, when the user moves the mouse away from the element, the <code>onMouseLeave</code> event listener is triggered, and it removes the highlight effect by setting the background color back to the default.</p>
<p>By attaching the <code>appHighlight</code> directive to an HTML element, we can dynamically control its appearance and behavior. This demonstrates the concept of directives in Angular, where you can define custom behaviors or instructions that can be applied to HTML elements to enhance their functionality and visual representation.</p>
<p>Here's an example of how you can apply the <code>appHighlight</code> directive to an HTML element in your template:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">appHighlight</span>&gt;</span>
  This is a highlighted element. Move your mouse over it to see the effect!
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>In this case, we have a <code>&lt;div&gt;</code> element to which we apply the <code>appHighlight</code> directive using the directive selector <code>[appHighlight]</code>. When the user hovers over this <code>&lt;div&gt;</code> element, the directive's behavior is triggered, and the background color of the element will be set to yellow, as defined in the directive's code.</p>
<p>Understanding Angular's modular structure is crucial for building scalable and maintainable applications. By organizing functionality into modules, and leveraging reusable components, services, and directives, developers can create applications that are easier to develop, test, and extend.</p>
<p>This modular approach also facilitates collaboration among team members and enables better code organization. This leads to more efficient development workflows and better overall application architecture.</p>
<h3 id="heading-angular-cli-and-typescript-integration">Angular CLI and TypeScript Integration</h3>
<p>Angular CLI (Command Line Interface) is a powerful tool that simplifies the development process of Angular applications. It provides a command-line interface for creating, building, testing, and deploying Angular projects.</p>
<p>Additionally, Angular CLI seamlessly integrates with TypeScript, a statically typed superset of JavaScript, to enhance the development experience and enable advanced features.</p>
<h4 id="heading-creating-projects">Creating Projects</h4>
<p>With Angular CLI, creating a new Angular project is as simple as running a single command. The CLI generates a basic project structure, including configuration files, boilerplate code, and a development server. This saves time and eliminates the need for manual project setup, ensuring that developers can start coding right away.</p>
<p>To create a new project in Angular, you can use the Angular CLI (Command Line Interface). Follow these steps:</p>
<ul>
<li><p>Open your terminal or command prompt.</p>
</li>
<li><p>Navigate to the directory where you want to create your Angular project.</p>
</li>
<li><p>Run the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">ng new project-name
</code></pre>
<p>Replace <code>project-name</code> with the desired name for your project (I choose frontend-frameworks). Make sure to avoid spaces or special characters.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/angular-creating-projects2-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Selecting options for Angular project</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/angular-creating-projects2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Creating Project</em></p>
<p>The Angular CLI will prompt you to choose additional options for your project, such as the stylesheet format (CSS, SCSS, Sass etc.) and whether you want to enable routing. Make your selections and press Enter.</p>
<p>Wait for the CLI to create the project. It will install the necessary dependencies and set up the basic structure.</p>
<p>Once the process is complete, navigate into the project directory:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> project-name
</code></pre>
<p>You can now start working on your Angular project. Use the <code>ng serve</code> command to run the development server and view your application in the browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/ng-serve.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>ng serve</em></p>
<pre><code class="lang-bash">ng serve
</code></pre>
<p>Your Angular project will be accessible at <code>http://localhost:4200</code>.</p>
<p>The <code>ng new</code> command is used to generate a new Angular project with the specified name. It sets up the initial project structure, installs the necessary dependencies, and configures the project files.</p>
<p>Using the Angular CLI simplifies the process of creating and managing Angular projects, allowing you to focus on development rather than boilerplate setup.</p>
<h4 id="heading-code-generation">Code Generation</h4>
<p>Angular CLI offers a variety of powerful code generation commands that help streamline the development process.</p>
<p>Developers can easily generate components, services, modules, and other Angular elements using the CLI, reducing the amount of manual coding required. This accelerates development speed and ensures consistent code patterns throughout the project.</p>
<p>Here are the commands for generating different Angular elements using the Angular CLI:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/code-generation-component-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Generating a component</em></p>
<ul>
<li><strong>Generating a Component:</strong></li>
</ul>
<pre><code class="lang-bash">ng generate component component-name
</code></pre>
<p>This command creates a new component with the specified name. It generates the component files, including the HTML template, CSS styles, TypeScript code, and the necessary component tests.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/code-generation-services.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Generating a service</em></p>
<ul>
<li><strong>Generating a Service:</strong></li>
</ul>
<pre><code class="lang-bash">ng generate service service-name
</code></pre>
<p>This command generates a new service with the specified name. Services are used for handling data, implementing business logic, and sharing functionality across components.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/code-generation-module.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Generating a module</em></p>
<ul>
<li><strong>Generating a Module:</strong></li>
</ul>
<pre><code class="lang-bash">ng generate module module-name
</code></pre>
<p>Use this command to create a new module with the specified name. Modules help organize and structure your Angular application by grouping related components, services, and other Angular elements.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/code-generation-directive.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Generating a directive</em></p>
<ul>
<li><strong>Generating a Directive:</strong></li>
</ul>
<pre><code class="lang-bash">ng generate directive directive-name
</code></pre>
<p>This command generates a new directive with the specified name. Directives allow you to modify the behavior or appearance of HTML elements in your Angular application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/code-generation-pipe.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Generating a pipe</em></p>
<ul>
<li><strong>Generating a Pipe:</strong></li>
</ul>
<pre><code class="lang-bash">ng generate pipe pipe-name
</code></pre>
<p>Use this command to create a new pipe with the specified name. Pipes are used for transforming data in your Angular templates, such as formatting dates, applying custom filters, or truncating or shortening an input text to a specified length.</p>
<p>These commands are executed in the terminal or command prompt, and Angular CLI will automatically generate the corresponding files and folder structure based on the specified name. Make sure to replace <code>component-name</code>, <code>service-name</code>, <code>module-name</code>, <code>directive-name</code>, or <code>pipe-name</code> with your desired names when using these commands.</p>
<h4 id="heading-development-server">Development Server</h4>
<p>Angular CLI includes a built-in development server that allows developers to run and test their applications locally.</p>
<p>The server automatically reloads the application whenever changes are made, providing a smooth development experience. It also offers features like hot module replacement, allowing developers to see the immediate effect of their code changes without the need for a full application reload.</p>
<h4 id="heading-typescript-integration">TypeScript Integration</h4>
<p>Angular is built using TypeScript, a <a target="_blank" href="https://www.freecodecamp.org/news/learn-typescript-with-this-crash-course/">statically typed superset of JavaScript</a>. TypeScript brings powerful features like static type checking, enhanced IDE support, better code navigation, and advanced refactoring tools.</p>
<p>Angular CLI seamlessly integrates with TypeScript, providing out-of-the-box support for compiling TypeScript code into JavaScript and handling TypeScript-specific configuration options.</p>
<p>By leveraging Angular CLI and TypeScript integration, developers can streamline their development workflow, enhance productivity, and benefit from the robustness and scalability of the Angular framework.</p>
<p>Angular CLI simplifies common tasks, automates repetitive processes, and provides a seamless TypeScript development experience, allowing developers to focus on building high-quality applications.</p>
<h2 id="heading-what-is-vuejs">What is Vue.js?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Vue.js_Logo_2.svg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Vue.js logo</em></p>
<p>Vue.js is a progressive JavaScript framework for building user interfaces. It is designed to be approachable, versatile, and easy to integrate into existing projects. Whether you're a beginner or an experienced developer, Vue.js offers a smooth learning curve and a flexible architecture that makes it a popular choice for web application development.</p>
<p>In this section, I'll teach you the fundamentals of Vue.js and help you get started with building your own Vue.js applications. We'll explore the core concepts, syntax, and key features that make Vue.js a powerful and intuitive framework.</p>
<p>If you're new to Vue.js, don't worry! I'll guide you step by step, starting from the basics and gradually diving into more advanced topics. By the end of this guide, you'll have a solid understanding of Vue.js and be well-equipped to start building your own dynamic and interactive web applications.</p>
<p>So, let's embark on this Vue.js journey together and unlock the full potential of this powerful JavaScript framework. Whether you're building a small personal project or a large-scale application, Vue.js has the tools and capabilities to bring your ideas to life.</p>
<h3 id="heading-vuejs-and-its-philosophy">Vue.js and its Philosophy</h3>
<p>Vue.js is built upon a set of guiding principles that shape its design and philosophy. Understanding these principles is crucial for effectively utilizing the framework and developing high-quality Vue.js applications.</p>
<ol>
<li><p><strong>Approachability:</strong> Vue.js prides itself on being an approachable framework, making it easy for beginners to get started. Its syntax is simple and intuitive, resembling plain HTML templates, which lowers the learning curve. Vue.js allows developers to gradually adopt its features, enabling them to integrate it into existing projects or start small and scale as needed.</p>
</li>
<li><p><strong>Versatility:</strong> Vue.js is a versatile framework that you can use for a wide range of applications. It offers a flexible architecture, allowing developers to choose the tools and libraries they prefer. Whether you want to build a single-page application (SPA), a progressive web app (PWA), or integrate Vue.js into a larger project, the framework provides the necessary flexibility to meet your specific needs.</p>
</li>
<li><p><strong>Component-Based Development:</strong> Vue.js promotes a component-based approach to development. Components are self-contained and reusable building blocks that encapsulate their own logic, styles, and templates. This modular structure facilitates code reuse, simplifies maintenance, and enables better collaboration among team members. Vue.js provides a clear and intuitive syntax for defining and using components, making it straightforward to create complex user interfaces.</p>
</li>
<li><p><strong>Reactivity:</strong> Vue.js leverages a reactive data model, which means that changes to the underlying data automatically update the corresponding views. This reactivity makes it easier to build interactive and responsive applications without the need for manual DOM manipulation. Vue.js tracks dependencies between data and views, ensuring efficient updates and optimized rendering performance.</p>
</li>
</ol>
<p>By embracing these principles, Vue.js empowers developers to build elegant, maintainable, and scalable applications. The philosophy of approachability, versatility, component-based development, and reactivity sets the foundation for creating exceptional user interfaces with Vue.js.</p>
<h3 id="heading-vues-reactivity-system-and-component-composition">Vue's Reactivity System and Component Composition</h3>
<p>Vue.js employs a powerful reactivity system that enables efficient and automatic updates to the user interface based on changes in the underlying data. This reactivity is achieved through Vue's reactive data model and makes it easy to create dynamic and responsive applications.</p>
<h4 id="heading-reactive-data-model">Reactive Data Model</h4>
<p>Vue.js uses a reactive data model, where data properties are automatically tracked for changes. When the data changes, Vue.js automatically updates the associated views, ensuring a synchronized and reactive user interface. This reactivity simplifies the development process as developers do not need to manually manipulate the DOM to reflect data changes.</p>
<p>In Vue.js, the reactive data model is like a magical connection between your data and the user interface. Imagine you have a magic box where you can put your data. Whenever the data inside the box changes, the UI automatically updates to reflect those changes. It's like having a real-time mirror of your data!</p>
<p>In this magical world of Vue.js, you define your data properties inside a Vue component, and Vue takes care of tracking those properties for you. Whenever a property changes, Vue automatically detects it and updates the corresponding parts of the UI. This means you don't have to manually update the UI elements every time the data changes. Vue does all the heavy lifting for you.</p>
<p>So, let's say you have a counter in your app. When you click a button to increase the counter value, Vue will instantly update the value in the UI without you having to write any extra code. It's as simple as that! The reactive data model in Vue.js makes it easy to keep your UI in sync with your data, saving you time and effort.</p>
<p>By embracing the reactive data model in Vue.js, you can build dynamic and interactive user interfaces with ease. It allows you to focus on manipulating the data, and Vue takes care of updating the UI accordingly. It's like having a superpower that simplifies your development process and brings your app to life.</p>
<p>So, remember, with Vue.js, you can harness the power of the reactive data model to create engaging and responsive user interfaces effortlessly.</p>
<h4 id="heading-computed-properties-and-watchers">Computed Properties and Watchers</h4>
<p>Vue.js provides computed properties and watchers to handle more complex logic and reactivity requirements.</p>
<p>Computed properties allow developers to define properties that are computed based on other reactive data properties. These computed properties are cached and updated only when their dependencies change, optimizing performance.</p>
<p>Watchers, on the other hand, allow developers to react to specific data changes and perform custom logic when those changes occur.</p>
<p>Computed properties and watchers are like special helpers that assist you in handling data transformations and reacting to changes. Imagine you have a friend who always keeps an eye on things for you and gives you updates whenever something changes. That's exactly what computed properties and watchers do in Vue.</p>
<p>Computed properties are like smart calculators that automatically compute and update values based on other data properties. It's like having a helper who can perform complex calculations for you.</p>
<p>For example, let's say you have the length and width of a rectangle, and you want to calculate its area. With computed properties, you can define a property called <code>area</code> that dynamically computes the area value whenever the length or width changes. This way, you always have the correct area value without manually recalculating it.</p>
<p>On the other hand, watchers are like attentive observers who keep an eye on specific data properties and perform actions when they change. It's like having a friend who notifies you whenever something important happens.</p>
<p>For example, let's say you have a form input field, and you want to perform some validation or execute a function whenever the input value changes. With watchers, you can define a watcher that watches the input value and triggers a function whenever it changes. This allows you to take immediate action and respond to user inputs or data changes.</p>
<p>By using computed properties and watchers in Vue.js, you can simplify complex data manipulations and react to changes effectively. They provide you with powerful tools to automate calculations, perform validations, and execute custom logic whenever necessary. It's like having reliable assistants who handle the heavy lifting for you, making your coding experience more efficient and enjoyable.</p>
<p>With computed properties and watchers in Vue.js, you have the power to automatically compute values and respond to changes effortlessly. They are your trusted companions in managing data transformations and handling dynamic behaviors in your Vue components.</p>
<h4 id="heading-component-composition">Component Composition</h4>
<p>Vue.js promotes component-based development and encourages the composition of smaller, reusable components to build larger and more complex user interfaces.</p>
<p>Components can be easily created, registered, and used throughout the application. Vue's reactivity system allows data to flow seamlessly between parent and child components, enabling a hierarchical and reactive structure.</p>
<p>Component composition, in Vue.js, is like playing with building blocks to create something amazing. Let's say you have different LEGO bricks, and each brick represents a specific part of your website or web app. With component composition in Vue, you can easily combine these bricks to build something much bigger and more powerful.</p>
<p>Think of each Vue component as a LEGO brick that has its own unique functionality and appearance. You can create components for a navigation bar, a button, an image gallery, or any other part of your web page. Now, when you want to build a complete web page, you can assemble these components together, just like stacking LEGO bricks on top of each other.</p>
<p>Component composition allows you to reuse components and nest them within each other to create complex and interactive web pages. It's like building a LEGO spaceship by combining different bricks, adding wings, a cockpit, and other parts.</p>
<p>Similarly, in Vue, you can nest components inside one another, passing data and interacting with each other to create dynamic and interactive user interfaces.</p>
<p>By using component composition in Vue.js, you can easily break down your web page into smaller, manageable parts, and then assemble them together to create a cohesive and functional whole. It's like having a box of LEGO bricks that you can use to build anything you imagine.</p>
<p>Component composition lets you create individual components for different parts of your web page and then combine them together to create a complete and interactive experience. It's a fun and creative way to build awesome websites and web apps.</p>
<h4 id="heading-props-and-events">Props and Events</h4>
<p>Vue.js facilitates communication between components through the use of props and events. Props allow data to be passed from parent components to child components, enabling a unidirectional flow of data. Events, on the other hand, allow child components to emit events and notify parent components about specific actions or changes.</p>
<p>In Vue.js, props and events are like passing messages between components, just like friends talking to each other. Think of it as you having two friends who want to share information with each other. One friend can send a message (prop) to the other friend, and the other friend can respond with a message (event) back.</p>
<p>In Vue, components can communicate with each other using props and events. Think of a prop as a message that a parent component sends to its child component. It's like a note passed from one friend to another, containing important information. The child component can receive the prop and use that information to display or modify its behavior. It's a way for components to share data with each other.</p>
<p>Now, events are like the response from the child component back to the parent component. It's the other friend replying to the message they received. The child component can emit an event to let the parent component know that something happened or that it needs to take action. It's like raising your hand and saying, <em>"Hey, something important just happened!"</em></p>
<p>With props and events in Vue.js, components can talk to each other, share information, and work together as a team. This communication between components allows you to build dynamic and interactive web pages where different parts can exchange data and work together seamlessly.</p>
<p>So, just like friends passing notes and responding with actions, props and events in Vue.js help components share information and work together as a team. It's a fun way to create interactive and collaborative web applications.</p>
<p>Vue's reactivity system and component composition provide a solid foundation for building flexible and modular applications. By leveraging the reactivity system, developers can create dynamic and responsive user interfaces, while component composition promotes code reuse, maintainability, and scalability.</p>
<p>With Vue.js, developers can easily manage complex application states and achieve a seamless and interactive user experience.</p>
<h3 id="heading-single-file-components-and-vue-cli">Single-File Components and Vue CLI</h3>
<p>Vue.js offers a convenient way to structure and organize components using Single-File Components (SFCs). SFCs encapsulate the template, script, and styles of a component into a single file, promoting better separation of concerns and improving code readability.</p>
<h4 id="heading-structure-and-organization">Structure and Organization</h4>
<p>With Single-File Components, each component is contained within a single file, which makes it easier to understand and manage.</p>
<p>The template section holds the HTML markup, the script section contains the component's logic written in JavaScript, and the style section holds the component's styles using CSS or pre-processors like SASS or LESS. This modular structure allows developers to work on different aspects of a component without navigating through multiple files.</p>
<p>Here's a short code snippet that demonstrates the structure and organization of a Vue single-file component:</p>
<pre><code class="lang-python">&lt;template&gt;
  &lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">my</span>-<span class="hljs-title">component</span>"&gt;
    &lt;!-- <span class="hljs-title">Component</span> <span class="hljs-title">HTML</span> <span class="hljs-title">template</span> --&gt;
    &lt;h1&gt;{{ message }}&lt;/h1&gt;
    &lt;button @click="increment"&gt;Click Me!&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  name:</span> <span class="hljs-string">'MyComponent'</span>,
  data() {
    <span class="hljs-keyword">return</span> {
      message: <span class="hljs-string">'Hello, Vue!'</span>,
      count: <span class="hljs-number">0</span>,
    };
  },
  methods: {
    increment() {
      this.count++;
    },
  },
};
&lt;/script&gt;

&lt;style scoped&gt;
.my-component {
  /* Component-specific styles */
}
&lt;/style&gt;
</code></pre>
<p>In this code snippet, you can see the structure of a Vue single-file component. It consists of three main sections: <code>&lt;template&gt;</code>, <code>&lt;script&gt;</code>, and <code>&lt;style&gt;</code>.</p>
<p>The <code>&lt;template&gt;</code> section contains the HTML template of the component. It defines the structure and layout of the component's content.</p>
<p>The <code>&lt;script&gt;</code> section contains the JavaScript code for the component. It includes the component's definition, which includes the component's name, data, and methods.</p>
<p>In this example, we have a <code>data</code> object that holds the component's state, including a <code>message</code> property and a <code>count</code> property. We also have a <code>methods</code> object that defines the <code>increment</code> method, which increments the <code>count</code> property when the button is clicked.</p>
<p>The <code>&lt;style&gt;</code> section contains the component-specific styles. By using the <code>scoped</code> attribute, the styles are only applied to the component's elements, ensuring encapsulation and preventing conflicts with styles from other components.</p>
<p>This structure helps in organizing and managing the code for your Vue components. It keeps the HTML, JavaScript, and styles related to a component in a single file, making it easier to understand and maintain your codebase.</p>
<h4 id="heading-scoped-styles">Scoped Styles</h4>
<p>Single-File Components provide built-in support for scoped styles. By default, styles defined within a component only apply to that component's template, preventing style conflicts with other components. This encapsulation makes it easier to style components without worrying about global style pollution.</p>
<p>Take a look at this code snippet that demonstrates the use of scoped styles in a Vue single-file component:</p>
<pre><code class="lang-python">&lt;template&gt;
  &lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">my</span>-<span class="hljs-title">component</span>"&gt;
    &lt;!-- <span class="hljs-title">Component</span> <span class="hljs-title">content</span> --&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  name:</span> <span class="hljs-string">'MyComponent'</span>,
};
&lt;/script&gt;

&lt;style scoped&gt;
.my-component {
  background-color: <span class="hljs-comment">#f1f1f1;</span>
  padding: <span class="hljs-number">20</span>px;
  border-radius: <span class="hljs-number">5</span>px;
}
&lt;/style&gt;
</code></pre>
<p>In this code snippet, you can see the use of scoped styles in Vue single-file components. The <code>&lt;style&gt;</code> section includes the component-specific styles, and the <code>scoped</code> attribute is added to the <code>&lt;style&gt;</code> tag.</p>
<p>Scoped styles mean that the styles defined within the component's <code>&lt;style&gt;</code> section only apply to the elements within that component.</p>
<p>In the example, the <code>.my-component</code> class is used to style the component's <code>&lt;div&gt;</code> element. The background color is set to <code>#f1f1f1</code>, there's padding around the component, and the border radius is set to <code>5px</code>.</p>
<p>The scoped styles ensure that these styles only affect the specific component they are defined in. This helps prevent style conflicts and allows for better encapsulation of styles within the component. It allows you to write component-specific styles without worrying about affecting other components or elements on the page.</p>
<p>Using scoped styles in Vue single-file components promotes code organization and separation of concerns, making it easier to manage and maintain your styles within your Vue project.</p>
<h4 id="heading-vue-cli">Vue CLI</h4>
<p>Vue CLI (Command Line Interface) is a powerful tool that simplifies the development of Vue.js applications. It provides a command-line interface for creating, configuring, and managing Vue projects.</p>
<p>Vue CLI includes features like project scaffolding, code generation, and an integrated development server, making it easy to set up and start building Vue applications.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/install-vue-cli.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Installing Vue CLI</em></p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install Vue CLI globally (if not already installed)</span>
npm install -g @vue/cli

<span class="hljs-comment"># Create a new Vue project</span>
vue create my-project
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/vue-create.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Create Vue Project</em></p>
<p>As you can see in code snippet above, we first install Vue CLI globally using the <code>npm install</code> command. This step is required only if you haven't installed Vue CLI before.</p>
<p>Once Vue CLI is installed, you can create a new Vue project using the <code>vue create</code> command. In the example, we're creating a project named "<em>my-project</em>". Vue CLI will prompt you to select a preset configuration for your project. You can choose from various options like default, manually select features, or use a saved preset.</p>
<p>After selecting the preset, Vue CLI will set up the project structure, install the necessary dependencies, and generate the initial files for your Vue project.</p>
<p>Using Vue CLI simplifies the process of setting up a new Vue project by providing a command-line interface and project scaffolding. It automates many common tasks, such as project configuration, dependency installation, and build setup.</p>
<p>Vue CLI also provides additional features like hot-reloading during development, ready-to-use templates, and easy project customization.</p>
<p>With Vue CLI, you can quickly start working on your Vue projects without worrying about the initial setup, allowing you to focus on writing code and building your application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/npm-build-vue.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>npm run build</code></p>
<h4 id="heading-build-and-deployment">Build and Deployment</h4>
<p>Vue CLI offers a streamlined build process that optimizes the application for production. It generates optimized bundles, minifies the code, and applies various optimizations to improve performance.</p>
<p>Additionally, Vue CLI supports easy deployment of Vue applications to various hosting platforms or content delivery networks (CDNs), simplifying the deployment process.</p>
<p>When it comes to building and deploying your Vue.js application, Vue CLI provides a simple and efficient way to handle this process. After you've developed your application locally, you'll need to generate a production-ready build that can be deployed to a web server.</p>
<p>Vue CLI offers a command called <code>npm run build</code> that compiles your Vue components, bundles your assets, and optimizes your code for production. It generates a <code>dist</code> directory containing all the necessary files for deployment. This process ensures that your application is optimized for performance and ready to be served to users.</p>
<p>Once you have your production build, you can deploy it to a web server or a hosting platform of your choice. You can simply upload the contents of the <code>dist</code> directory to your server, and your Vue.js application will be accessible to users over the internet.</p>
<p>Deploying your Vue.js application typically involves configuring your server to serve the static files correctly, setting up any necessary server-side routing or configurations, and ensuring that your server has the required dependencies installed.</p>
<p>It's important to choose a reliable and secure hosting solution that fits your application's requirements. Popular hosting options for Vue.js applications include platforms like <a target="_blank" href="https://www.netlify.com">Netlify</a>, <a target="_blank" href="https://vercel.com/">Vercel</a>, and <a target="_blank" href="https://pages.github.com/">GitHub Pages</a>, which offer seamless deployment workflows and robust infrastructure.</p>
<p>By leveraging the build and deployment features provided by Vue CLI, you can easily package and deploy your Vue.js application, making it accessible to users worldwide.</p>
<p>By utilizing Single-File Components (SFCs) and Vue CLI, developers can efficiently structure their Vue.js projects, enhance code organization, and leverage powerful development tools. This approach not only improves code maintainability but also allows for better collaboration among team members.</p>
<p>Vue's ecosystem provides a seamless development experience that empowers developers to build robust and scalable applications with ease.</p>
<h2 id="heading-comparing-javascript-frameworks">Comparing JavaScript Frameworks</h2>
<p>When it comes to choosing a frontend framework for web development, you'll need to consider your use case, the features you need, and your skillset, among other things.</p>
<p>React, Angular, and Vue are all widely adopted frameworks that offer different approaches and features. They call them "<em>The Big Three</em>". Understanding the similarities and differences between these frameworks can help you make an informed decision based on your project requirements and personal preferences.</p>
<p>In this section, we will compare React, Angular, and Vue across various aspects such as learning curve, performance, community support, ecosystem, and more. We will explore their strengths and weaknesses, highlighting the unique features and benefits they bring to the table.</p>
<p>By examining these frameworks side by side, you can gain a better understanding of their key characteristics and determine which one aligns best with your needs. Remember, there is no one-size-fits-all solution, and the right choice ultimately depends on the specific demands of your project.</p>
<p>So, let's dive into the comparison and discover the similarities and differences among the big three. This knowledge will equip you with the necessary insights to choose the frontend framework that will enhance your development workflow and enable you to create exceptional web applications.</p>
<h3 id="heading-similarities-and-differences-between-react-angular-and-vue">Similarities and Differences between React, Angular, and Vue</h3>
<p>React, Angular, and Vue are all powerful frontend frameworks, but they differ in their approach, syntax, and ecosystem. Let's explore the key similarities and differences between these frameworks:</p>
<ol>
<li><p><strong>Component-Based Architecture:</strong> React, Angular, and Vue all follow a component-based architecture, where applications are built by composing reusable components. This promotes code reusability, modularity, and scalability.</p>
</li>
<li><p><strong>Virtual DOM:</strong> React and Vue utilize a Virtual DOM, a lightweight representation of the actual DOM. This allows for efficient updates and ensures optimal rendering performance. Angular, on the other hand, uses a different change detection mechanism based on zones.</p>
</li>
<li><p><strong>Learning Curve:</strong> React and Vue are known for their gentle learning curves, making them more beginner-friendly. Angular, on the other hand, has a steeper learning curve due to its extensive feature set and complex concepts.</p>
</li>
<li><p><strong>Language and Syntax:</strong> React uses JavaScript, while Angular employs TypeScript, a superset of JavaScript. Vue supports both JavaScript and TypeScript, offering flexibility in language choice. The syntax and coding styles also differ across the frameworks, with React using JSX, Angular using a template-driven approach, and Vue utilizing a combination of template syntax and JavaScript.</p>
</li>
<li><p><strong>Ecosystem and Community Support:</strong> React, Angular, and Vue have vibrant ecosystems with active communities. React has a large and mature ecosystem with numerous libraries and tools available. Angular has strong corporate backing from Google, which ensures robust development and support. Vue has gained popularity in recent years, and although its ecosystem is smaller, it continues to grow rapidly.</p>
</li>
<li><p><strong>Popularity and Adoption:</strong> React has gained significant popularity and is widely adopted by large tech companies. Angular, being a full-fledged framework, is commonly used for enterprise-level applications. Vue has experienced rapid growth and has gained a strong following in the developer community.</p>
</li>
</ol>
<p>While these frameworks share some similarities, their differences in syntax, learning curve, and ecosystem can influence your choice. It's essential to evaluate your project requirements, team expertise, and personal preferences to determine which framework suits your needs best.</p>
<h3 id="heading-performance-considerations-and-scalability">Performance Considerations and Scalability</h3>
<p>Performance is a crucial aspect to consider when choosing a frontend framework for your web application. Let's explore the performance considerations and scalability of React, Angular, and Vue:</p>
<ol>
<li><p><strong>Rendering Performance:</strong> React, Angular, and Vue all employ different rendering approaches. React utilizes a Virtual DOM, which efficiently updates and renders only the necessary components. Angular uses its own change detection mechanism, while Vue leverages a combination of Virtual DOM and a reactive data model. These approaches aim to minimize unnecessary re-renders and enhance performance.</p>
</li>
<li><p><strong>Bundle Size:</strong> The size of the framework's bundle can impact the initial load time of your application. React and Vue have smaller footprints, allowing for faster initial loading. Angular, being a full-fledged framework, has a larger bundle size, which may require additional optimization techniques to improve load times.</p>
</li>
<li><p><strong>Optimization Techniques:</strong> All three frameworks offer various optimization techniques to improve performance. These include code splitting, lazy loading, tree shaking (also known as dead code elimination, it's a process used by modern JavaScript bundlers to remove unused code from a project), and caching strategies. By implementing these techniques correctly, you can minimize the overall bundle size, reduce network requests, and optimize the runtime performance of your application.</p>
</li>
<li><p><strong>Scalability:</strong> When it comes to scalability, all three frameworks can handle large-scale applications. However, Angular, with its opinionated structure and extensive features, is particularly suited for enterprise-level applications that require complex architecture and scalability. React and Vue, being more lightweight and flexible, can also scale well, but they may require additional setup and architectural decisions as the application grows.</p>
</li>
</ol>
<p>It's important to note that performance considerations and scalability depend on various factors, including the size and complexity of your application, the specific optimization techniques implemented, and the efficiency of your code.</p>
<p>Conducting performance testing, utilizing best practices, and staying updated with the latest optimizations can help ensure optimal performance and scalability regardless of the chosen framework.</p>
<p>Keep in mind that while performance is important, it should be balanced with other considerations such as developer productivity, community support, and project requirements. Evaluating these factors holistically will enable you to make an informed decision regarding the performance and scalability needs of your web application.</p>
<h3 id="heading-learning-curve-and-community-support">Learning Curve and Community Support</h3>
<p>The learning curve and community support are essential considerations when choosing a frontend framework like React, Angular, or Vue. Let's explore these aspects in more detail:</p>
<ol>
<li><strong>Learning Curve:</strong> The learning curve refers to the time and effort required to become proficient in a particular framework. React, Angular, and Vue have different learning curves based on their concepts, syntax, and ecosystem.</li>
</ol>
<ul>
<li><p><strong>React:</strong> React has a relatively gentle learning curve, especially for developers familiar with JavaScript. Its core concepts like components, state management, and JSX syntax are easy to grasp. But mastering advanced topics like React Hooks and state management libraries may require additional effort.</p>
</li>
<li><p><strong>Angular:</strong> Angular has a steeper learning curve (especially a difficult initial learning process) compared to React and Vue. It is a full-fledged framework with a comprehensive set of features and a specific way of doing things. Angular's learning curve stems from its powerful dependency injection system, TypeScript integration, and the extensive use of decorators.</p>
</li>
<li><p><strong>Vue:</strong> Vue strikes a balance between React and Angular in terms of learning curve. Its straightforward API, clear documentation, and gradual adoption approach make it beginner-friendly. Vue's simplicity and intuitive syntax make it relatively easy to get started with, even for developers new to frontend frameworks.</p>
</li>
</ul>
<ol start="2">
<li><strong>Community Support:</strong> The strength of the community around a framework can greatly impact your learning experience and development journey. React, Angular, and Vue all have vibrant communities with active support channels, forums, and online resources.</li>
</ol>
<ul>
<li><p><strong>React:</strong> React has a large and robust community, with countless tutorials, documentation, and third-party libraries available. The React community is known for its responsiveness and continuous innovation, making it easier to find solutions to common problems.</p>
</li>
<li><p><strong>Angular:</strong> Angular has solid community support, backed by Google. It has extensive documentation, official guides, and a dedicated team maintaining the framework. The Angular community is known for its focus on best practices, architectural patterns, and enterprise-level support.</p>
</li>
<li><p><strong>Vue:</strong> Although Vue's community is relatively smaller compared to React and Angular, it is rapidly growing and gaining momentum. Vue has a friendly and supportive community that actively contributes to its development. The Vue community is known for its inclusivity, helpfulness, and emphasis on simplicity.</p>
</li>
</ul>
<p>Considering the learning curve and community support is crucial, especially for beginners. It's important to choose a framework with a learning curve that aligns with your current skill level and project requirements. Plus, a strong and active community can provide valuable resources, guidance, and collaboration opportunities, helping you overcome challenges and stay up-to-date with the latest trends and best practices.</p>
<h2 id="heading-how-to-choose-the-right-framework-for-your-project">How to Choose the Right Framework for Your Project</h2>
<p>Selecting the most suitable frontend framework for your project requires careful consideration of several factors. Here are some key points to keep in mind when making your decision:</p>
<h3 id="heading-project-requirements">Project Requirements</h3>
<p>Start by evaluating your project's specific requirements. Consider factors such as the complexity of the application, the size of the development team, scalability needs, and performance requirements. You should also think about any existing technical constraints such as the technology stack being used, integration with existing systems or libraries, and compatibility with specific platforms or frameworks.</p>
<p>Understanding these requirements will help you determine which framework aligns best with your project goals.</p>
<h3 id="heading-learning-curve">Learning Curve</h3>
<p>Assess your team's skillset and experience level. If you have a team of developers who are already proficient in a particular framework, it may be more efficient to leverage their existing expertise.</p>
<p>On the other hand, if you have a team of beginners or developers with a broad range of skills, opting for a framework with a gentler learning curve can facilitate a smoother onboarding process.</p>
<h3 id="heading-community-and-ecosystem">Community and Ecosystem</h3>
<p>Consider the size and vibrancy of the framework's community and ecosystem. A robust community provides access to a wealth of resources, tutorials, libraries, and support channels.</p>
<p>A thriving ecosystem ensures that you have a wide range of tools, plugins, and extensions to enhance your development process. It also indicates the long-term viability and sustainability of the framework.</p>
<h3 id="heading-compatibility-and-integration">Compatibility and Integration</h3>
<p>Evaluate how well the framework integrates with your existing technology stack. Consider factors such as compatibility with backend frameworks, support for APIs, and the availability of plugins or packages that can facilitate integration with other tools and services you may be using.</p>
<h3 id="heading-flexibility-and-customization">Flexibility and Customization</h3>
<p>Each framework has its own conventions and patterns. Assess whether the framework's structure and design principles align with your development preferences and project requirements.</p>
<p>Consider the flexibility and extensibility of the framework, as well as the ease with which you can customize and adapt it to suit your specific needs.</p>
<p>By carefully evaluating these factors, you can make an informed decision and select the right frontend framework that will empower you to build scalable, performant, and maintainable web applications that meet your project requirements and developer team's expertise.</p>
<h2 id="heading-resources-for-learning-and-getting-started">Resources for Learning and Getting Started</h2>
<p>When embarking on your journey to learn and master frontend frameworks like React, Angular, or Vue, it's important to have access to high-quality learning resources.</p>
<p>Here are some recommended resources to help you get started:</p>
<h3 id="heading-official-documentation">Official Documentation</h3>
<p>The official documentation of each framework is an invaluable resource. It provides comprehensive guides, tutorials, and examples that cover the core concepts, features, and best practices.</p>
<p>Start by exploring the official documentation of React (<a target="_blank" href="https://react.dev/">react.dev</a>), Angular (<a target="_blank" href="https://angular.io/">angular.io</a>), and Vue (<a target="_blank" href="https://vuejs.org/">vuejs.org</a>) to gain a solid foundation.</p>
<h3 id="heading-online-courses-and-tutorials">Online Courses and Tutorials</h3>
<p>Online courses and tutorials offer structured learning paths and hands-on exercises that can accelerate your understanding of frontend frameworks.</p>
<p>Platforms like <a target="_blank" href="https://www.udemy.com/">Udemy</a>, <a target="_blank" href="https://www.coursera.org/">Coursera</a>, <a target="_blank" href="https://www.udacity.com/">Udacity</a>, and <a target="_blank" href="https://www.pluralsight.com/">Pluralsight</a> offer a wide range of courses taught by industry experts. Look for courses that cater to beginners and offer practical projects to apply your knowledge.</p>
<h3 id="heading-youtube-channels-and-video-series">YouTube Channels and Video Series</h3>
<p>YouTube is a treasure trove of tutorial videos and in-depth explanations of frontend frameworks. Channels like <a target="_blank" href="https://www.youtube.com/@TraversyMedia">Traversy Media</a>, <a target="_blank" href="https://www.youtube.com/@NetNinja">The Net Ninja</a>, <a target="_blank" href="https://www.youtube.com/@freecodecamp">freeCodeCamp</a>, and <a target="_blank" href="https://www.youtube.com/@academind">Academind</a> provide comprehensive video series that cover various aspects of React, Angular, and Vue, from basics to advanced topics. These videos offer a visual and interactive learning experience.</p>
<h3 id="heading-online-communities-and-forums">Online Communities and Forums</h3>
<p>Joining online communities and forums dedicated to frontend development can greatly enhance your learning experience.</p>
<p>Platforms like <a target="_blank" href="https://stackoverflow.com/">Stack Overflow</a>, <a target="_blank" href="https://www.reddit.com/">Reddit</a>, <a target="_blank" href="https://forum.freecodecamp.org/">freeCodeCamp</a>, <a target="_blank" href="https://hashnode.com/">Hashnode</a>, <a target="_blank" href="https://hackernoon.com/">Hackernoon</a>, and <a target="_blank" href="https://dev.to/">Dev.to</a> have active communities where you can ask questions, seek guidance, and engage in discussions with fellow developers. The supportive nature of these communities can help you overcome challenges and expand your knowledge.</p>
<h3 id="heading-books-and-ebooks">Books and eBooks</h3>
<p>Books are another valuable resource for in-depth learning. Look for recommended books on React, Angular, and Vue that cater to beginners and cover the fundamental concepts.</p>
<p>Some popular titles include <em>React Up and Running</em> by Stoyan Stefanov, <em>Angular: Up and Running</em> by Shyam Seshadri and Brad Green, and <em>Vue.js 2 Cookbook</em> by Andrea Passaglia.</p>
<p>By utilizing these resources, you can access a variety of learning materials that cater to different learning styles and preferences.</p>
<p>Remember to combine theory with hands-on practice to reinforce your understanding of the frameworks. As you progress, keep exploring additional resources, attending workshops, and contributing to the community to further enhance your skills and stay up-to-date with the latest developments in frontend development.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Frontend frameworks such as React, Angular, and Vue play a crucial role in modern web development. They provide powerful tools and abstractions that simplify the creation of interactive and dynamic user interfaces. Throughout this guide, we've explored the key features and benefits of these frameworks, as well as their similarities and differences.</p>
<p>Understanding the core concepts of each framework, such as React's component-based architecture, Angular's modular structure, and Vue's reactivity system will allow to make informed decisions on which framework suits your project requirements and personal preferences.</p>
<p>It's important to consider factors like performance, scalability, learning curve, and community support when choosing the right framework for your development endeavors.</p>
<p>Remember, learning a frontend framework is an ongoing process. It's essential to continuously expand your knowledge, stay updated with the latest trends and best practices, and keep honing your skills.</p>
<p>Explore the abundance of resources available, such as official documentation, online courses, tutorials, and community forums, to deepen your understanding and proficiency in using these frameworks.</p>
<p>As you delve deeper into the world of frontend development, don't limit yourself to just one framework. Familiarize yourself with multiple frameworks to broaden your skill set and adapt to different project requirements. Embrace the opportunities for collaboration and learning from other developers within the vibrant communities surrounding these frameworks.</p>
<p>Frontend frameworks have revolutionized web development, empowering developers to create immersive, responsive, and highly interactive web applications. By harnessing the power of React, Angular, Vue, or other frameworks, you can unlock endless possibilities and bring your ideas to life on the web. So, continue exploring, experimenting, and pushing the boundaries of frontend development to achieve remarkable results.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Angular Upgrades That Will Improve Your Developer Experience ]]>
                </title>
                <description>
                    <![CDATA[ When we talk about the Developer Experience, we're referring to the level of difficulty a developer faces when completing essential tasks.  Factors like the complexity of a development framework or the absence of syntactic sugar in a programming lang... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/angular-upgrades-to-improve-developer-experience/</link>
                <guid isPermaLink="false">66b9fa152d0f884246b52442</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brenda Chepkorir ]]>
                </dc:creator>
                <pubDate>Wed, 17 May 2023 23:40:59 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/pexels-thisisengineering-3861958.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When we talk about the <a target="_blank" href="https://microsoft.github.io/code-with-engineering-playbook/developer-experience/">Developer Experience</a>, we're referring to the level of difficulty a developer faces when completing essential tasks. </p>
<p>Factors like the complexity of a development framework or the absence of <a target="_blank" href="https://www.techopedia.com/definition/10212/syntactic-sugar">syntactic sugar</a> in a programming language can negatively impact it.</p>
<p>A robust modern framework can be complex. But Angular wouldn’t be so beloved if it didn't get easier to use with each new version. </p>
<p>Versions 14, 15, and 16 have many improvements that you may not know about and may want to take advantage of when you're migrating from one version to the next. </p>
<p>These improvements include:</p>
<ul>
<li>succinct tree-shakable error messages</li>
<li>template auto-magic</li>
<li>required inputs</li>
<li>page title in route options</li>
<li>component-bound route data</li>
<li>CLI completion</li>
</ul>
<p>Let's look at each of these features in more depth so you can use them in your Angular applications.</p>
<h2 id="heading-succinct-tree-shakablehttpsdevelopermozillaorgen-usdocsglossarytreeshaking-error-messages">Succinct <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking">Tree-Shakable</a> Error Messages</h2>
<p>Now, tree-shaking mostly gets rid of unused code from a bundle. In this instance, it refers to the trimming of runtime error messages in production. </p>
<p>Runtime error messages and codes in Angular are not new. What is new are the less verbose production error messages. </p>
<p>In version 14, instead of long messages, you get their related error codes. And you can quickly look up these codes in the <a target="_blank" href="https://angular.io/errors">Angular documentation</a> for debugging. You can view the longer detailed messages in development for further debugging.</p>
<h2 id="heading-templatehttpsangularioguidetemplate-syntax-auto-magic"><a target="_blank" href="https://angular.io/guide/template-syntax">Template</a> Auto-Magic</h2>
<p>In version 16, template self-closing tags help developers forgo the need to add closing tags to component selectors in templates. This is similar to the ubiquitous <code>input</code> HTML element that doesn't need a closing tag. For example: </p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!--Before--&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">app-root</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-root</span>&gt;</span>

<span class="hljs-comment">&lt;!--After--&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">app-root</span> /&gt;</span>
</code></pre>
<p>Furthermore, upgrades to the Angular language service in version 16 make automatic imports of standalone pipes and components in templates possible. Like automatic class imports within components. Most code editors, like VS Code, <a target="_blank" href="https://code.visualstudio.com/docs/editor/intellisense#_intellisense-features">use language services</a> to support automatic imports through <em>quick fixes</em>.</p>
<p>In addition, version 14 introduced an additional template compiler option, <a target="_blank" href="https://angular.io/guide/angular-compiler-options">a TypeScript configuration</a>, called <code>[extendedDiagnostics](https://angular.io/extended-diagnostics)</code> to supplement template insights. This configuration helps the compiler find common template pitfalls like an optional chain when a value will never be <code>null</code>. If it is <code>null</code>, it’s either a bug or a mis-typed value. </p>
<p>These types of syntax errors are usually harder to spot since they don't always break the application.</p>
<h2 id="heading-required-inputshttpsangularioapicoreinput">Required <a target="_blank" href="https://angular.io/api/core/Input">Inputs</a></h2>
<p>Inputs in Angular are vital in data-sharing from parent to child components. They specify what values are being passed to the child. Version 16 introduced <a target="_blank" href="https://angular.io/api/core/Input#required">required</a> inputs to help developers remember to pass these data when using child components. </p>
<p>Missing data assigned to required inputs will trigger compile-time errors.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChildComponent {
    <span class="hljs-meta">@Input</span>({ required: <span class="hljs-literal">true</span> }) someList: unknown[];
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!--In parent template--&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">child-one</span>  /&gt;</span> <span class="hljs-comment">&lt;!--triggers compile-time error--&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">child-one</span> [<span class="hljs-attr">someList</span>]=<span class="hljs-string">"list"</span> /&gt;</span> <span class="hljs-comment">&lt;!--no compile-time error--&gt;</span>
</code></pre>
<p>Perhaps further updates to required inputs may help delay rendering child components while the data is still <code>falsy</code>. </p>
<h2 id="heading-page-title-in-route-options">Page Title in Route Options</h2>
<p>Page titles are important. Even more so for the <a target="_blank" href="https://web.dev/the-accessibility-tree/">Accessiblity Tree</a>. You can see them in the pages’ browser tabs, like headings. The Accessibility Tree is the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction">DOM</a> that Accessibility tools, like screen readers, use to navigate through the web page.</p>
<p>Page titles summarize content for users which is useful for navigation. It can be easy to forget to set them, especially if setting them seems a little counterintuitive in development.</p>
<p>Version 14 introduced a <code>title</code> option to the <code>[Route](https://angular.io/api/router/Route)</code> interface  which you can  use to configure application routes. This allows each route to set its own page title. In addition, this option can be configured as a <code>string</code> or a function that resolves to a string for more dynamic titles.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> appRoutes: Route[] = [
{
    path: <span class="hljs-string">'/customers'</span>,
    component: CustomersComponent,
    title: <span class="hljs-string">'Customers'</span>,
    children: [{
        path: <span class="hljs-string">':id/customer'</span>,
        component: CustomerComponent,
        title: <span class="hljs-function">(<span class="hljs-params">route: ActivatedRouteSnapshot, state:     RouterStateSnapshot</span>) =&gt;</span> <span class="hljs-built_in">this</span>.getRouteTitleForCustomer()
      }]
}
];
</code></pre>
<h2 id="heading-component-bound-route-data">Component-Bound Route Data</h2>
<p>While inputs have always been used for data-sharing between components in parent-child relationships, you can also use them for data-sharing between routed components in version 16.</p>
<p>Some application routing scenarios require passing data, like IDs, to components being routed to. This was possible through use of the injectable <code>[ActivatedRoute](https://angular.io/api/router/ActivatedRoute)</code> class in the components needing the data.</p>
<p>Developers can now get these data in through the components’ inputs, whether it's from the route resolvers or path and query parameters. These data values get tied to component inputs with matching names. So, a <code>customerId</code> data value from the route will correspond to a <code>customerId</code> input in the component. </p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CustomerComponent {
    <span class="hljs-meta">@Input</span>() customerId: <span class="hljs-built_in">string</span>;
}
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> appRoutes: Route[] = [
{
    path: <span class="hljs-string">'/customers'</span>,
    component: CustomersComponent,
    title: <span class="hljs-string">'Customers'</span>,
    children: [{
        path: <span class="hljs-string">':id/customer'</span>,
        component: CustomerComponent,
        title: <span class="hljs-string">'Customer'</span>,
        resolve: { customerId: <span class="hljs-function">(<span class="hljs-params">route: ActivatedRouteSnapshot, state:     RouterStateSnapshot</span>) =&gt;</span> <span class="hljs-built_in">this</span>.getCustomerId()
          }
      }]
}
];
</code></pre>
<p>Be sure to <a target="_blank" href="https://angular.io/guide/router#getting-route-information">enable component binding through the router</a>.</p>
<h2 id="heading-cli-completionhttpsangularioclicompletion"><a target="_blank" href="https://angular.io/cli/completion">CLI Completion</a></h2>
<p>As for <a target="_blank" href="https://dev.to/ruizb/declarative-vs-imperative-4a7l">imperative coders</a> and terminal lovers, version 14 brought command auto-completion through <code>ng completion</code>. This allows developers to get quick intuitive references for commands and their applicable options with a <code>tab</code> key press in the terminal. This makes using the CLI easier and faster.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>The latest Angular versions 14, 15, and 16 contain many more requested changes that not only boost the Developer Experience, but also address many framework issues. </p>
<p>The <a target="_blank" href="https://blog.angular.io/">Angular Blog</a> and the <a target="_blank" href="https://angular.io/docs">documentation</a> provide more details about all these changes with specific examples.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Signals in Angular – How to Write More Reactive Code ]]>
                </title>
                <description>
                    <![CDATA[ By Deborah Kurata An exciting new feature is coming to Angular: signals! Signals provide a new way for our code to tell our templates (and other code) that our data has changed. This improves Angular's change detection, which also improves performanc... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/angular-signals/</link>
                <guid isPermaLink="false">66d45e01706b9fb1c166b920</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 05 Apr 2023 00:53:15 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/thumbnail.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Deborah Kurata</p>
<p>An exciting new feature is coming to Angular: signals! Signals provide a new way for our code to tell our templates (and other code) that our data has changed. This improves Angular's change detection, which also improves performance, and makes our code more reactive.</p>
<p>You can try out this powerful new feature now. Signals are available for developer preview in Angular v16, due to be released in May of 2023. You can get early versions of Angular v16 to try it out now. I'll walk through how later in this tutorial.</p>
<p>Watch the associated video here for the concepts and a demonstration:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/oqYQG7QMdzw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Find the sample code here: https://stackblitz.com/edit/angular-signals-deborahk</p>
<p>Before we jump into the details of the "what?" and "how?", let's start with the "why?". Why would you want to use this new signals feature?</p>
<h2 id="heading-why-do-we-need-signals"><strong>Why Do We Need Signals?</strong></h2>
<p>Let's start with a simple example without the use of signals. Say you are writing code to perform some basic math operations.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> x = <span class="hljs-number">5</span>;
<span class="hljs-keyword">let</span> y = <span class="hljs-number">3</span>;
<span class="hljs-keyword">let</span> z = x + y;
<span class="hljs-built_in">console</span>.log(z);
</code></pre>
<p>What does this code log to the console? Yep, it logs out <code>8</code>.</p>
<p>Some time later in the code, we change the value of <code>x</code>. What does <code>z</code> log out now?</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> x = <span class="hljs-number">5</span>;
<span class="hljs-keyword">let</span> y = <span class="hljs-number">3</span>;
<span class="hljs-keyword">let</span> z = x + y;
<span class="hljs-built_in">console</span>.log(z);

x = <span class="hljs-number">10</span>;
<span class="hljs-built_in">console</span>.log(z);
</code></pre>
<p>It still logs out <code>8</code>! That's because a value is assigned to <code>z</code> when the expression is first evaluated. The <code>z</code> variable does not react to changes in <code>x</code> or <code>y</code>.</p>
<p>But we want our variables to react to changes!</p>
<p>One of the reasons we use Angular is to build reactive websites, like Figure 1. When the user updates the quantity, the related variables (such as subtotal and tax) should react and adjust the costs. If the user selects to delete an item from the cart, we again want the related variables to react and correctly recalculate the costs.</p>
<p><img src="https://lh5.googleusercontent.com/b3SbnD_bufoicCX2VGyQiA624LQEC7yIEAVeEj0aVHjxvwmNnTPs-qE565koSuPWUrjAj-UDSw9otj6fXRWHPtr9jce2fnLt8FFAiLP0KRijjpuUiN_cb9lFwe_IbmsSWSzWqV36zBa8Bsnh7ciX4zo" alt="Image" width="600" height="400" loading="lazy">
<em>Figure 1. The cart reacts and recalculates when the user changes the quantity.</em></p>
<p>With signals, our code can be more reactive. Our prior example implemented with signals would look like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> x = signal(<span class="hljs-number">5</span>);
<span class="hljs-keyword">const</span> y = signal(<span class="hljs-number">3</span>);
<span class="hljs-keyword">const</span> z = computed(<span class="hljs-function">() =&gt;</span> x() + y());
<span class="hljs-built_in">console</span>.log(z()); <span class="hljs-comment">// 8</span>

x.set(<span class="hljs-number">10</span>);
<span class="hljs-built_in">console</span>.log(z()); <span class="hljs-comment">// 13</span>
</code></pre>
<p>We'll look at this syntax in detail shortly. For now, the code above defines two signals: <code>x</code> and <code>y</code> and gives them initial values of <code>5</code> and <code>3</code>. We then define a computed signal, <code>z</code>, which is the sum of <code>x</code> and <code>y</code>. Since signals provide change notifications, when the <code>x</code> or <code>y</code> signals change, any values computed from those signals will automatically recalculate. This code is now reactive! Nice!</p>
<p>Computed signals react and recalculate when any of its dependent signals change. If a signal is bound in a template, when the signal changes, Angular's change detection automatically updates any view that reads the signal. And the user sees the changed value.</p>
<p>So the answer to "why do we need signals?":</p>
<ul>
<li>Signals provide more reactivity</li>
<li>Using signals gives us finer control over change detection, which can improve performance.</li>
</ul>
<p>Let's dive a bit deeper into what a signal is and how it is used.</p>
<h2 id="heading-what-is-a-signal"><strong>What Is a Signal?</strong></h2>
<p>You can think of a signal as a value plus a change notification. A signal is just a special type of variable that holds a value. But unlike other variables, a signal also provides notification when the variable value changes.</p>
<p>Think of a normal variable as a shelf, like on the left side of Figure 2. When a value is assigned to the variable, it sits on that shelf. Any code within scope can simply read that variable on the shelf.</p>
<p><img src="https://lh6.googleusercontent.com/VNW2DY2fkiBRNox5DIGkh2qr_yRgurq7I3vLumHSqT2ACNKq6I3GiGcMpVvU6f2AImTNIJ3quMh7lzerxfRjD3WBiLPEKBWGRgxGfvsrWpwuvBpvbpllPKJ-lZWHzQLRBguqAHWnITJU3xajiV2BoZM" alt="Image" width="600" height="400" loading="lazy">
<em>Figure 2. Metaphorically, a normal variable sits on a shelf. A signal is stored in a box that glows when it changes.</em></p>
<p>A signal is more like a box, as shown on the right side of Figure 2. Creating a signal metaphorically creates a box and puts the value inside of that box. The box glows when the value of the signal changes. To read the signal, first open the box using parentheses: <code>x()</code>. Technically speaking, we call the signal's getter function to read the signal.</p>
<p>We now have the answer to "what is a signal?":</p>
<ul>
<li>A signal is a variable + change notification</li>
<li>A signal is reactive, and is called a "reactive primitive"</li>
<li>A signal always has a value</li>
<li>A signal is synchronous</li>
<li>A signal is <em>not</em> a replacement for RxJS and Observables for asynchronous operations, such as <code>http.get</code></li>
</ul>
<p>Where can we use signals?</p>
<ul>
<li>Use them in <strong>components</strong> to track local component state</li>
<li>Use them in <strong>directives</strong></li>
<li>Use them in a <strong>service</strong> to share state across components</li>
<li>Read them in a <strong>template</strong> to display signal values</li>
<li>Or use them <strong>anywhere else</strong> in your code</li>
</ul>
<p>Next let's walk through how to create and use signals.</p>
<h2 id="heading-how-to-create-a-signal"><strong>How to Create a Signal</strong></h2>
<p>To use a signal, you first create one.</p>
<pre><code class="lang-typescript">quantity = signal&lt;<span class="hljs-built_in">number</span>&gt;(<span class="hljs-number">1</span>);
</code></pre>
<p>The above syntax creates and initializes a signal using the signal constructor function.</p>
<p>Optionally, provide a generic type parameter to define the signal's data type. A signal can be a string, number, array, object, or any data type. In many cases, the data type can be inferred and the generic type parameter is unnecessary.</p>
<p>Pass to the constructor the default value of the signal. A signal always has a value, starting with that default.</p>
<p>Here are some additional examples:</p>
<pre><code class="lang-typescript">quantity = signal(<span class="hljs-number">1</span>);

qtyAvailable = signal([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>]);

selectedVehicle = signal&lt;Vehicle&gt;({ 
  id: <span class="hljs-number">1</span>,
  name: <span class="hljs-string">'AT-AT'</span>, 
  price: <span class="hljs-number">19416.13</span>
});

vehicles = signal&lt;Vehicle[]&gt;([]);
</code></pre>
<p>The first code line above creates a numeric signal with a default value of <code>1</code>. Because the default value is a number, the <code>quantity</code> is a signal that holds a number. The generic type parameter isn't needed.</p>
<p>The second line is a signal that holds an array of numbers. The default provides an array of values 1 through 6. Again, the generic type parameter isn't needed in this case because it can be inferred from the default value.</p>
<p>The <code>selectedVehicle</code> signal holds a <code>Vehicle</code> object. In this example, the type cannot be inferred, so we specify a generic type parameter of <code>Vehicle</code>.</p>
<p>The <code>vehicles</code> signal holds an array of <code>Vehicle</code> objects. Its default is an empty array. To strongly type the array, we add a generic type parameter of <code>&lt;Vehicle[]&gt;</code>.</p>
<p>A signal created with the signal constructor function is writable, so you can set it to a new value, update it based on the current value, or mutate its content. We'll see examples of these operations shortly.</p>
<p>Once you've created a signal, you may want to read its value.</p>
<h2 id="heading-how-to-read-a-signal"><strong>How to Read a Signal</strong></h2>
<p>Earlier, we represented a signal as a box. Metaphorically speaking, to read a signal's value you must first open the box. You do that by adding parentheses as shown below.</p>
<pre><code class="lang-typescript">quantity();
</code></pre>
<p>Start with the signal name and follow it with open and closing parentheses. Technically speaking, this calls the signal's getter function. The getter function is created behind the scenes – you won't see it in your code.</p>
<p>When working with Angular, a common place to read signals is in the template.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">select</span>
    [<span class="hljs-attr">ngModel</span>]=<span class="hljs-string">"quantity()"</span>
    (<span class="hljs-attr">change</span>)=<span class="hljs-string">"onQuantitySelected($any($event.target).value)"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">option</span> *<span class="hljs-attr">ngFor</span>=<span class="hljs-string">"let q of qtyAvailable()"</span>&gt;</span>{{ q }}<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Vehicle: {{ selectedVehicle().name }}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Price: {{ selectedVehicle().price }}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> [<span class="hljs-attr">style.color</span>]=<span class="hljs-string">"color()"</span>&gt;</span>Total: {{ totalPrice() }}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>The above template displays a select box for selection of a quantity. The <code>[ngModel]</code> reads the value of the <code>quantity</code> signal, binding to that value.</p>
<p>The <code>change</code> event binding calls the <code>onQuantitySelected()</code> method in the component.</p>
<p>The <code>option</code> element uses <code>ngFor</code> to iterate through each array element in the <code>qtyAvailable</code> signal. It reads the signal and creates a select <code>option</code> for each array element.</p>
<p>Below the <code>select</code> element are three <code>div</code> elements. The first one reads the <code>selectedVehicle</code> signal, then accesses its <code>name</code> property. The second <code>div</code> element reads the <code>selectedVehicle</code> signal, then displays its <code>price</code> property. The last <code>div</code> element reads the <code>totalPrice</code> signal (which we have not yet defined). And it sets the text color to the value from the <code>color</code> signal (which we also have not defined).</p>
<p>It's important to note that reading a signal always reads the current signal value. The code doesn't have any knowledge of any prior signal values.</p>
<p>When the user picks a different quantity from the <code>select</code> element, we want to change the value of the <code>quantity</code> signal. That way the <code>quantity</code> signal becomes the "source of truth" for the user's selected quantity. Let's look at how to do that next.</p>
<h2 id="heading-how-to-change-the-value-of-a-signal"><strong>How to Change the Value of a Signal</strong></h2>
<p>The signal <code>set</code> method replaces the value of a signal with a new value. It basically opens the box, removes the current item, and sets in a new item to take its place.</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.quantity.set(qty);
</code></pre>
<p>A common scenario is to change the signal value based on a user action. For example:</p>
<ul>
<li>The user selects a new quantity using the <code>select</code> element</li>
<li>The <code>select</code> element event binding calls the <code>onQuantitySelected()</code> method and passes in the selected quantity</li>
<li>The user action is handled in that event handler within the component</li>
<li>The new value is set into the <code>quantity</code> signal.</li>
</ul>
<p>Here is an example event handler:</p>
<pre><code class="lang-typescript">onQuantitySelected(qty: <span class="hljs-built_in">number</span>) {
  <span class="hljs-built_in">this</span>.quantity.set(qty);
}
</code></pre>
<p>Whenever the signal is set, the code notifies any consumers that the signal has changed. In this context, a <em>consumer</em> is any code that is interested in receiving change notifications.</p>
<p>How does the consumer indicate that it's interested in receiving notifications about a particular signal?</p>
<p>If <strong>code reads a signal</strong>, that code is notified when the signal changes.</p>
<p>If a <strong>template reads a signal</strong>, that template is notified when the signal changes and the view is scheduled to be re-rendered.</p>
<p>So the act of reading a signal registers the consumer's interest in watching that signal. The Angular team calls this the <strong>golden rule</strong> of signal components: "change detection for a component will be scheduled when <em>and only when</em> a signal read in the template notifies Angular that it has changed."</p>
<p>Here is an example to illustrate the process. Let's say that there is some work going on within the method below that needs to adjust the quantity. Maybe if the quantity is 5 or more you get one free, for example. The point is that the <code>quantity</code> signal could change several times within the execution of the method.</p>
<pre><code class="lang-typescript">onQuantitySelected(qty: <span class="hljs-built_in">number</span>) {
  <span class="hljs-built_in">this</span>.quantity.set(qty);

  <span class="hljs-built_in">this</span>.quantity.set(<span class="hljs-number">5</span>);
  <span class="hljs-built_in">this</span>.quantity.set(<span class="hljs-number">42</span>);
}
</code></pre>
<p>The quantity is displayed in the template using Angular's binding as shown below. Since the binding <em>reads</em> the <code>quantity</code> signal, the template registers its interest in receiving change notifications.</p>
<pre><code class="lang-html">{{ quantity() }}
</code></pre>
<p>When the user selects a quantity, the <code>onQuantitySelected()</code> method executes. The code in the method first sets the signal to the user-selected quantity. When the new signal is set, the signal generates a notification. At this point, Angular's change detection is scheduled to run. But it doesn't have an opportunity to run until <em>after</em> the execution of the <code>onQuantitySelected()</code> method.</p>
<p>The <code>onQuantitySelected()</code> method continues, setting the signal to <code>5</code>. The signal generates another change notification. Again Angular's change detection is reminded that it needs to run, but it still can't run because the <code>onQuantitySelected()</code> method is still executing. The method then sets the signal to <code>42</code> and the process repeats.</p>
<p>When the <code>onQuantitySelected()</code> method has completed its execution, Angular's change detection can finally run. The template reads the signal, and gets the current value of that signal, which is <code>42</code>. The template is not aware of any of the prior signal values. The view is then re-rendered, and the new <code>quantity</code> signal value is displayed.</p>
<p>If a signal is changed, any consumer interested in reading that signal is notified. But the consumer is not given the new value. The next time it's their turn to execute, the consumer reads the current value from the signal.</p>
<p>If you are familiar with RxJS and Observables, signals are quite different. Signals don't <em>emit</em> values like Observables do. And signals don't require a subscription.</p>
<p>In addition to the <code>set()</code>, there are two other ways to change a signal: <code>update()</code> and <code>mutate()</code>.</p>
<p>The <code>set()</code> method replaces a signal with a new value, metaphorically replacing the contents of the signal box. Pass the new value into the set method.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Replace the value</span>
<span class="hljs-built_in">this</span>.quantity.set(qty);
</code></pre>
<p>The <code>update()</code> method updates the signal based on its current value. Pass to the update method an arrow function. The arrow function provides the current signal value so you can update it as needed. In the code below, the quantity is doubled.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Update value based on current value</span>
<span class="hljs-built_in">this</span>.quantity.update(<span class="hljs-function"><span class="hljs-params">qty</span> =&gt;</span> qty * <span class="hljs-number">2</span>);
</code></pre>
<p>The <code>mutate()</code> method modifies the content of a signal value, not the signal value itself. Use it with arrays to modify array elements, and objects to modify object properties. In the code below, a vehicle's price is increased by 20%.</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.selectedVehicle.mutate(<span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> v.price = v.price + (v.price * <span class="hljs-number">.20</span>));
</code></pre>
<p>Regardless of how the signal is modified, consumers are notified that the signal was changed. The consumers can then read the new signal value when it's their turn to execute.</p>
<h2 id="heading-how-to-define-a-computed-signal"><strong>How to Define a Computed Signal</strong></h2>
<p>Oftentimes we have variables in our code that depend on other variables. For example, the total price for an item is the price for that item times the desired quantity of that item. If the user changes the quantity, we want to change the total price. For that, we use <strong>computed signals</strong>.</p>
<p>Define a computed signal by calling the computed creation function. The <code>computed()</code> function creates a new signal that depends on other signals.</p>
<p>Pass to the computed function a computation function that performs the desired operation. The operation reads the value of one or more signals to perform its computation.</p>
<pre><code class="lang-typescript">totalPrice = computed(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.selectedVehicle().price * <span class="hljs-built_in">this</span>.quantity());

color = computed(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.totalPrice() &gt; <span class="hljs-number">50000</span> ? <span class="hljs-string">'green'</span> : <span class="hljs-string">'blue'</span>);
</code></pre>
<p>The first line of code above defines a <code>totalPrice</code> computed signal by calling the <code>computed()</code> creation function. The computation function passed into this computed function reads the <code>selectedVehicle</code> and <code>quantity</code> signals. If either signal changes, this computed signal is notified and will update when it is its turn to execute.</p>
<p>The second line of code defines a <code>color</code> computed signal. It sets the color to <code>green</code> or <code>blue</code> depending on the value of the <code>totalPrice</code> signal. The template can bind to this signal to display the appropriate style.</p>
<p>A computed signal is read only. It <strong>cannot</strong> be modified with <code>set()</code>, <code>update()</code> or <code>mutate()</code>.</p>
<p>The value of a computed signal is re-computed when:</p>
<ul>
<li>One or more of its dependent signals is changed.</li>
<li>AND the value of the computed signal is read.</li>
</ul>
<p>The computed signal value is <em>memoized</em>, meaning it stores the computed result. That computed value is reused the next time the computed value is read.</p>
<p>Say for example we have this in our template:</p>
<pre><code class="lang-typescript">Extended price: {{ totalPrice() }}
Total price: {{ totalPrice() }}
Amount due: {{ totalPrice() }}
</code></pre>
<p>The first time that the template reads the <code>totalPrice</code> computed signal, the value is calculated and stored in memory. The other two times the <code>totalPrice</code> signal is read, the stored value is reused. The value is not recalculated unless one of its dependent signals changes.</p>
<h2 id="heading-how-to-use-an-effect"><strong>How to Use an Effect</strong></h2>
<p>There may be times that you need to run code when a signal changes, and that code has side effects. By side effects I mean code that calls an API or performs another operation not related to the signal. In these cases, you'll use an <code>effect()</code>.</p>
<p>For example, you want to debug your signals and log out the signal value each time the code reacts to a change to that signal. Calling <code>console.log()</code> is a side effect.</p>
<p>To define an effect, call the <code>effect()</code> creation function. Pass to the function the operation to perform. This operation is re-executed every time the code reacts to a change in any dependent signal.</p>
<pre><code class="lang-typescript">effect(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.selectedVehicle()));
</code></pre>
<p>The <code>effect()</code> function can be called within other function. Since the effect sets up a handler of sorts, it is often called in the constructor or other startup code.</p>
<p>Alternatively, an effect can be defined declaratively as shown below:</p>
<pre><code class="lang-typescript">e = effect(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.selectedVehicle()));
</code></pre>
<p>An effect should <strong>not</strong> change the value of any signals. If you need to change a signal based on a change to a dependent signal, use a computed signal instead.</p>
<p>You'll find that you won't use effects often. Though they are useful for logging, or calling other external APIs. (But don't use them to work with RxJS and Observables. There will be signal features to convert to and from Observables.)</p>
<h2 id="heading-when-to-use-signals"><strong>When to Use Signals</strong></h2>
<p>Here are some suggestions for when to use signals.</p>
<p>First, continue to use event handlers in a component as you do now for user actions. Actions such as a selection from a drop down list, a click on a button, or an entry in a textbox.</p>
<p>Use a signal or a computed signal in a component for any state that could change. In this context, state refers to any data that the component manages. Everything from an <code>isLoading</code> flag to the current displayed "page" of data to the user's selected filter criteria could be signals. Signals are especially useful when displaying data in the template when that data should react to other actions.</p>
<p>Put shared signals in services. The array of vehicles returned in an Observable could be transformed into a signal. Any totals could also be signals in a service if those signals are shared between components.</p>
<p>Continue to use Observables for asynchronous operations, such as <code>http.get()</code>. There are more features coming to signals to map a signal to and from an Observable.</p>
<h2 id="heading-wrapping-up"><strong>Wrapping Up</strong></h2>
<p>Signals represent a major advancement in Angular's reactive programming capabilities and change detection features. </p>
<p>This tutorial answered the questions: "Why?", "What?" and "How?". And we threw in "Where?" and "When?", too.</p>
<p>Signals are available as a developer preview in Angular v16. As part of that preview, signals are integrated into the existing change detection model. Future signal features expect to improve change detection and mark components for check, somewhat like OnPush change detection that we have today with the async pipe.</p>
<p>An easy way to try out signals is to use stackblitz, which is an online editor that works well with Angular and doesn't require any installation. To use stackblitz with signals:</p>
<ol>
<li>Navigate to the stackblitz website: <a target="_blank" href="http://www.stackblitz.com">www.stackblitz.com</a>.</li>
<li>Click the Angular icon to create an Angular project.</li>
<li>Edit the resulting <code>package.json</code> file and change the versions of the @angular packages to the latest pre-release of Angular v16.</li>
<li>Save the project to refresh dependencies.</li>
<li>Try out signals!</li>
</ol>
<p>To see these steps in action, check out the demo provided near the end of this video:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/oqYQG7QMdzw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Or start with my stackblitz link: <a target="_blank" href="https://stackblitz.com/edit/angular-signals-deborahk">https://stackblitz.com/edit/angular-signals-deborahk</a>. Be sure to fork my project to try out your own changes.</p>
<p>Signals are coming! They'll improve our code's reactivity and change detection. They'll make our code easier to create and read. And they are great fun!  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Integrate Chart.js in Angular Using Data from a REST API ]]>
                </title>
                <description>
                    <![CDATA[ Charts are a great way of visually displaying large sets of data in formats that are easy to understand and analyze. They are a great way of showing the relationship that exists between two or more data sets. Different types of charts exist, some of ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-integrate-chart-js-in-angular-using-data-from-a-rest-api/</link>
                <guid isPermaLink="false">66d45e01f855545810e93415</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chartjs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ deji adesoga ]]>
                </dc:creator>
                <pubDate>Thu, 30 Mar 2023 15:54:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/Copy-of-Copy-of-Orange-and-White-Vibrant-Food-YouTube-Thumbnail--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Charts are a great way of visually displaying large sets of data in formats that are easy to understand and analyze. They are a great way of showing the relationship that exists between two or more data sets.</p>
<p>Different types of charts exist, some of which includes bar chart, line chart, pie chart, radar chart, etc.</p>
<p>In this article, you will make use of a frontend framework called Angular as well as a JavaScript library called <a target="_blank" href="https://www.chartjs.org/">Chart.js</a> to display data from a cryptocurrency platform called <a target="_blank" href="https://coinranking.com/">Coinranking</a>. You will also make use of the Coinranking API to visualize a list of Cryptocurrencies along with their prices.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow along with this tutorial, make sure you are familiar with the basics of the technologies listed below:</p>
<ul>
<li><p>HTML</p>
</li>
<li><p>JavaScript</p>
</li>
<li><p>TypeScript</p>
</li>
<li><p>npm</p>
</li>
</ul>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-install-and-create-the-angular-application">How to Install and Create the Angular Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-integrate-chartjs-in-angular">How to Integrate Chart.js in Angular</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-integrate-the-rest-api">How to Integrate the REST API</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-display-the-data-in-the-chart">How to Display the Data in the Chart</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<p>You can also watch the video version of this article below, or on my <a target="_blank" href="https://www.youtube.com/thecodeangle">YouTube channel</a>:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/WCI4yvrzFwc" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-to-install-and-create-the-angular-application">How to Install and Create the Angular Application</h2>
<p>Firstly, you need to install and set up Angular using the following steps:</p>
<h3 id="heading-step-1-install-npm-node-package-manager">Step 1: Install NPM (Node Package Manager)</h3>
<p>To install npm, you need to download Node.js. This can be done through the Node.js <a target="_blank" href="https://nodejs.org/en/download/">website</a>.</p>
<p>Node.js is an open-source cross platform server environment that can run on Windows, Linux, Unix, macOS, and more. It allows us to make use of npm to install libraries like Chart.js into our Angular application.</p>
<h3 id="heading-step-2-install-the-angular-cli-command-line-interface">Step 2: Install the Angular CLI (Command Line Interface)</h3>
<p>Once Node.js is installed, you can now download Angular into your machine with the terminal/command line using the command below:</p>
<pre><code class="lang-javascript">npm install -g @angular/cli
</code></pre>
<p>To confirm Angular has been installed, you can view the version by running the command <code>ng v</code>, which will give us the result below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/capture2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Angular CLI Version</em></p>
<h3 id="heading-step-3-create-a-new-angular-project">Step 3: Create a New Angular Project</h3>
<p>Now that Angular has been installed, you can now create a new project by running the following commands in the terminal:</p>
<pre><code class="lang-javascript">ng <span class="hljs-keyword">new</span> ng-chart --routing=<span class="hljs-literal">false</span> --style=css
cd ng-chart
code .
</code></pre>
<p>With the commands above, we've created a new Angular project using the <code>ng new</code> command, disabled the routing and set the styling format to CSS.</p>
<p>Next, navigate into the project directory using the <code>cd</code> command, and open the project in Visual Studio Code.</p>
<p>You do not need to generate a new component for this project. You will use the two default files created by the Angular CLI — <code>app.component.ts</code> and <code>app.component.hmtl</code> — to render the chart. These files are in the <code>app</code> directory of your project.</p>
<p>The <code>app.component.html</code> file contains some boilerplate code which you need to get rid of. The Chart.js library can now be integrated into your application.</p>
<h2 id="heading-how-to-integrate-chartjs-in-angular">How to Integrate Chart.js in Angular</h2>
<p>To add the chart.js library to the Angular app, you need to run the following command inside your terminal:</p>
<pre><code class="lang-javascript">npm i chart.js
</code></pre>
<p>To confirm chart.js has been installed, you can check the <code>package.json</code> file in your project. You should see the chart.js version in the <code>dependencies</code> object shown in the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/capture4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Chart.js version</em></p>
<p>You can now import the chart.js library inside your project in the <code>app.component.ts</code> file as can be seen below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Chart <span class="hljs-keyword">from</span> <span class="hljs-string">'chart.js/auto'</span>;
</code></pre>
<p>Next, create a variable called <code>chart</code> and set it to an empty array:</p>
<pre><code class="lang-javascript">chart: any = []
</code></pre>
<p>Navigate to the getting started page of the chart.js <a target="_blank" href="https://www.chartjs.org/docs/latest/getting-started/">documentation</a> and grab the boilerplate code with static data, and paste it into the <code>ngOnInit</code> lifecycle hook:</p>
<p><strong>Note</strong>: The <code>ngOnInit</code> lifecycle hook in Angular gets triggered once after a component is initialized. That is, it gets called only when the first change detection occurs in an Angular component.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppComponent</span> </span>{
  title = <span class="hljs-string">'ng-chart'</span>;
  chart: any = [];

  <span class="hljs-keyword">constructor</span>() {}

  ngOnInit() {
    <span class="hljs-built_in">this</span>.chart = <span class="hljs-keyword">new</span> Chart(<span class="hljs-string">'canvas'</span>, {
      <span class="hljs-attr">type</span>: <span class="hljs-string">'bar'</span>,
      <span class="hljs-attr">data</span>: {
        <span class="hljs-attr">labels</span>: [<span class="hljs-string">'Red'</span>, <span class="hljs-string">'Blue'</span>, <span class="hljs-string">'Yellow'</span>, <span class="hljs-string">'Green'</span>, <span class="hljs-string">'Purple'</span>, <span class="hljs-string">'Orange'</span>],
        <span class="hljs-attr">datasets</span>: [
          {
            <span class="hljs-attr">label</span>: <span class="hljs-string">'# of Votes'</span>,
            <span class="hljs-attr">data</span>: [<span class="hljs-number">12</span>, <span class="hljs-number">19</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>],
            <span class="hljs-attr">borderWidth</span>: <span class="hljs-number">1</span>,
          },
        ],
      },
      <span class="hljs-attr">options</span>: {
        <span class="hljs-attr">scales</span>: {
          <span class="hljs-attr">y</span>: {
            <span class="hljs-attr">beginAtZero</span>: <span class="hljs-literal">true</span>,
          },
        },
      },
    });
  }
}
</code></pre>
<p>In the code above, within the data object, there is a <code>labels</code> key which contains an array with different values. Beneath that you have the <code>datasets</code> array which contains an object.</p>
<p>Within the object, there is an array called <code>data</code> with values of different numbers. These values represent the data that will get displayed on the chart in the browser.</p>
<p>Before the chart gets displayed in the browser, you'll need to also grab the <code>&lt;canvas&gt;&lt;/canvas&gt;</code> html tag and paste it in the <code>app.component.html</code> file as seen below:</p>
<pre><code class="lang-javascript">&lt;div&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"canvas"</span>&gt;</span>{{chart}}<span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span></span>
&lt;/div&gt;
</code></pre>
<p><strong>Note</strong>: In the <code>app.component.html</code> file, the <code>&lt;canvas&gt;</code> tag has an <code>id</code> called <code>canvas</code>. This must have the same name as the value inside the parentheses before the <code>new Chart</code> object in the <code>app.component.ts</code> file. If the names are not the same, the chart will not display.</p>
<p>You can now compile and serve the project by running the <code>ng serve --open</code> command in the terminal. You should have the following results:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/capture6.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Displaying the charts with static data</em></p>
<h2 id="heading-how-to-integrate-the-rest-api">How to Integrate the REST API</h2>
<p>To integrate the REST API, head over to the Coinranking website using this <a target="_blank" href="https://developers.coinranking.com/api">link</a>. You should see a page like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/capture8.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Coinranking website</em></p>
<p>Start by clicking on the "Get API Key" button. You will be directed to a page where you can create an account and have access to an <strong>API</strong> key.</p>
<p>Copy the API key and open the <code>environment.ts</code> file in your Angular project. Within the object, create a variable called <code>API_KEY</code> and paste in the API key generated from CoinRanking as seen below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> environment = {
  <span class="hljs-attr">production</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">API_KEY</span>: <span class="hljs-string">'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'</span>,
};
</code></pre>
<p>Next, you need to copy the API to get all cryptocurrency coins from the CoinRanking <a target="_blank" href="https://developers.coinranking.com/api/documentation/coins">documentation</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/capture9.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Coinranking API documentation</em></p>
<p>To use the API link copied above, you need to create an Angular Service by running the command below:</p>
<pre><code class="lang-javascript">ng g service services/chart
</code></pre>
<p>With the <code>chart.service.ts</code> file created, you can now paste in the code that helps us consume the REST API as seen below:</p>
<p>To summarize the above code, here's what we did:</p>
<ul>
<li><p>We imported the <code>HttpClient</code>, <code>HttpHeaders</code> in <strong>line 2</strong>, as well as the <code>environment</code> file in <strong>line 3</strong>.</p>
</li>
<li><p>Between <strong>line 5</strong> and <strong>line 11</strong>, we created a variable called <code>httpOptions</code>. The <code>httpOptions</code> variable holds an object that contains the <code>HttpHeaders</code> configuration imported above. Here we set the <strong>content-type</strong>, passed the <code>API_KEY</code> variable from the <code>environment</code> file to the headers, and then set the <code>Access-Control-Allow-Origin</code> to a wildcard. This means the browser should allow request code from the origin.</p>
</li>
<li><p>In <strong>line 17</strong>, we created a private variable called <code>baseUrl</code> to hold the <strong>REST API</strong>, while in <strong>line 28</strong>, we created a variable called <code>proxyUrl</code> to hold the <strong>CORS Anywhere</strong> link. The <strong>CORS Anywhere</strong> link is a NodeJS proxy that adds CORS headers to the proxied request and helps to prevent CORS errors in the process.</p>
</li>
<li><p>In <strong>line 20</strong>, we injected the <code>HttpClient</code> into the constructor which makes it accessible within the Service.</p>
</li>
<li><p>Finally, we created a function called <code>cryptoData()</code> in <strong>line 22</strong>. Within this function lies a variable called <code>url</code>. We used the <code>url</code> variable to append both the <code>proxyUrl</code> and <code>baseUrl</code> variables to construct our API. Furthermore, in the <code>return</code> statement, we used the <code>get()</code> http method to fetch the data from the REST API.</p>
</li>
</ul>
<p>To make the <code>HttpClient</code> work, you need to import and inject the <code>HttpClientModule</code> into the <code>app.module.ts</code> file which can be seen below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { BrowserModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser'</span>;
<span class="hljs-keyword">import</span> { HttpClientModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/common/http'</span>;

<span class="hljs-keyword">import</span> { AppComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.component'</span>;

@NgModule({
  <span class="hljs-attr">declarations</span>: [AppComponent],
  <span class="hljs-attr">imports</span>: [BrowserModule, HttpClientModule],
  <span class="hljs-attr">providers</span>: [],
  <span class="hljs-attr">bootstrap</span>: [AppComponent],
})
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppModule</span> </span>{}
</code></pre>
<p>As seen above, the <code>HttpClientModule</code> was imported and injected into the <code>imports</code> array.</p>
<h2 id="heading-how-to-display-the-data-in-the-chart">How to Display the Data in the Chart</h2>
<p>To display the data on the chart, you need to head to the <code>app.component.ts</code> file and bring in your Chart service file as seen below:</p>
<ul>
<li><p>As seen above, we begin by importing the Chart Service and injecting it into our component in <strong>line 3</strong> and <strong>line 17</strong> respectively.</p>
</li>
<li><p>We created three variables called <code>result</code>, <code>coinPrice</code>, and <code>coinName</code>. These variables will be used later in the project to hold data.</p>
</li>
<li><p>Within the <code>ngOnInit()</code> lifecycle hook, we called the <code>cryptoData()</code> function in <code>line 20</code>, which returns an observable that gets subscribed to. This allows us to return a response from the data in the process.</p>
</li>
<li><p>In <strong>line 21</strong>, we called the <code>result</code> variable using the <code>this</code> keyword and set it to hold the data.</p>
</li>
<li><p>Next, in <strong>line 22</strong> and <strong>line 23</strong>, we called the <strong>coinPrice</strong> and <strong>coinName</strong> variables, mapped through the data, and attached the coin price and coin name to them respectively.</p>
</li>
<li><p>To see the results of the data in the browser, we used the <code>console.log()</code> function to display the data, as seen below:</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/capture10-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Data from the CoinRanking API displayed on the console.</em></p>
<p>The final thing to be done is to plot the data seen in the image above into chart.</p>
<ul>
<li><p>As seen above, we first replaced the static data in the labels in <strong>line 12</strong> with the coin name gotten from the CoinRanking API.</p>
</li>
<li><p>Next, we replaced the static data in <strong>line 15</strong> with the price gotten from the CoinRanking API.</p>
</li>
</ul>
<p>Now compile the project by running the <code>ng serve --open</code> command and see the results in the browser as seen below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/capture11.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Final results of the chart</em></p>
<p><strong>Note</strong>: There is a possibility that you'll run into an error that says <strong>(Failed to load resource: the server responded with a status of 403 (Forbidden))</strong> after compiling the project.</p>
<p>What you need to do is to click on the CORS Anywhere link in the console which will open up in a new tab, with a button that says <strong>Request temporary access to the demo server.</strong> Click the button and then refresh the page. The data should now reflect on the chart.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned how to install and integrate the Chart.js library and a REST API in an Angular application. If you want access to the code base, you can clone the repo <a target="_blank" href="https://github.com/desoga10/ng-chart">here</a> on GitHub.</p>
<p>If you enjoyed this article, you can show your support by subscribing to my <a target="_blank" href="https://www.youtube.com/TheCodeAngle">YouTube channel</a> where I create awesome tutorials on web development technologies like JavaScript, React, Angular, Node.js, and more.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Chart.js Tutorial – How to Make Marimekko Charts in Angular ]]>
                </title>
                <description>
                    <![CDATA[ By Swatej Patil Data visualization is an essential part of data analysis. And charts are one of the most effective ways to present data in a clear and concise manner.  Marimekko charts are an excellent choice for displaying complex data sets in a com... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/chart-js-tutorial-how-to-make-marimekko-charts-in-angular/</link>
                <guid isPermaLink="false">66d46149706b9fb1c166b9ab</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chartjs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ charts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data visualization ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 21 Mar 2023 17:51:26 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/austin-distel-DfjJMVhwH_8-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Swatej Patil</p>
<p>Data visualization is an essential part of data analysis. And charts are one of the most effective ways to present data in a clear and concise manner. </p>
<p>Marimekko charts are an excellent choice for displaying complex data sets in a compact and visually appealing format. </p>
<p>A Marimekko chart, also known as a mosaic chart or mekko chart, is a combination of a stacked bar chart and a 100% stacked bar chart. The width of each bar represents the total value of the corresponding category, and the height of each bar represents the relative contribution of each sub-category to that total. </p>
<p>In this tutorial, we will explore how to create a Marimekko chart using Chart.js, a powerful charting library. We'll delve into the details of how to structure the data for Marimekko charts, as well as how to customize the chart's appearance and behavior using Chart.js options and APIs.</p>
<h1 id="heading-getting-started"><strong>Getting Started</strong></h1>
<p>I am assuming that you already have familiarity with creating simple line and bar charts using Chart.js in an Angular application. In this guide, there are certain concepts that will be easier to comprehend if you have prior knowledge.</p>
<p>Don't worry if you don't – I've got you covered. You can follow my <a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-bar-and-line-charts-using-chartjs-in-angular/">Chart.js Tutorial – How to Make Bar and Line Charts in Angular</a> to get started.</p>
<h2 id="heading-how-to-structure-data-for-marimekko-charts">How to Structure Data for Marimekko Charts</h2>
<p>Let's discuss the data structure required for Marimekko charts before creating the chart. </p>
<p>Marimekko charts need an array of objects, with each object representing a category. Each object must have a label and a sub-array of objects, where each sub-object represents a sub-category. </p>
<p>Each sub-object must have a label and a value. The value represents the proportion of the sub-category in relation to the total of its category.</p>
<p>Here's an example of how to structure data for a Marimekko chart:</p>
<pre><code class="lang-jsx">data: [
  {
    <span class="hljs-attr">label</span>: <span class="hljs-string">'Category 1'</span>,
    <span class="hljs-attr">subcategories</span>: [
      { <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 1'</span>, <span class="hljs-attr">value</span>: <span class="hljs-number">10</span> },
      { <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 2'</span>, <span class="hljs-attr">value</span>: <span class="hljs-number">20</span> },
      { <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 3'</span>, <span class="hljs-attr">value</span>: <span class="hljs-number">30</span> }
    ]
  },
  {
    <span class="hljs-attr">label</span>: <span class="hljs-string">'Category 2'</span>,
    <span class="hljs-attr">subcategories</span>: [
      { <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 1'</span>, <span class="hljs-attr">value</span>: <span class="hljs-number">40</span> },
      { <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 2'</span>, <span class="hljs-attr">value</span>: <span class="hljs-number">50</span> },
      { <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 3'</span>, <span class="hljs-attr">value</span>: <span class="hljs-number">60</span> }
    ]
  }
]
</code></pre>
<p>In this example, we have two categories: Category 1 and Category 2, with three subcategories each. The values for the subcategories represent the proportion of the subcategory in relation to the total of its category. For example, in Category 1, Subcategory 1 represents 10 out of 60, or 16.7% of the total.</p>
<h2 id="heading-how-to-create-a-marimekko-chart-with-chartjs">How to Create a Marimekko Chart with Chart.js</h2>
<p>Now that we have our data structured correctly, let's move on to creating our Marimekko chart using Chart.js. </p>
<p>First, we need to create a canvas element in our HTML code to hold the chart:</p>
<pre><code class="lang-jsx">&lt;canvas id=<span class="hljs-string">"marimekkoChart"</span>&gt;&lt;/canvas&gt;
</code></pre>
<p>Next, we'll need to install Chart.js and import it into our Angular component:</p>
<pre><code class="lang-jsx">npm install chart.js
</code></pre>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> Chart <span class="hljs-keyword">from</span> <span class="hljs-string">'chart.js/auto'</span>;
</code></pre>
<p>In our component class, we can then create a new Chart object and pass in our data and options:</p>
<pre><code class="lang-jsx">ngAfterViewInit() {
  <span class="hljs-keyword">const</span> canvas = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'marimekkoChart'</span>) <span class="hljs-keyword">as</span> HTMLCanvasElement;
  <span class="hljs-keyword">const</span> ctx = canvas.getContext(<span class="hljs-string">'2d'</span>) <span class="hljs-keyword">as</span> CanvasRenderingContext2D;

  <span class="hljs-keyword">const</span> data = {
    <span class="hljs-attr">labels</span>: [<span class="hljs-string">'Category 1'</span>, <span class="hljs-string">'Category 2'</span>],
    <span class="hljs-attr">datasets</span>: [
      {
        <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 1'</span>,
        <span class="hljs-attr">data</span>: [<span class="hljs-number">10</span>, <span class="hljs-number">40</span>],
        <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">'rgba(255, 99, 132, 0.7)'</span>,
        <span class="hljs-attr">borderWidth</span>: <span class="hljs-number">1</span>
      },
      {
        <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 2'</span>,
        <span class="hljs-attr">data</span>: [<span class="hljs-number">20</span>, <span class="hljs-number">50</span>],
        <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">'rgba(54, 162, 235, 0.7)'</span>,
        <span class="hljs-attr">borderWidth</span>: <span class="hljs-number">1</span>
      },
      {
        <span class="hljs-attr">label</span>: <span class="hljs-string">'Subcategory 3'</span>,
        <span class="hljs-attr">data</span>: [<span class="hljs-number">30</span>, <span class="hljs-number">60</span>],
        <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">'rgba(255, 206, 86, 0.7)'</span>,
        <span class="hljs-attr">borderWidth</span>: <span class="hljs-number">1</span>
      }
    ]
  };

  <span class="hljs-keyword">const</span> options = {
    <span class="hljs-attr">indexAxis</span>: <span class="hljs-string">'y'</span>,
    <span class="hljs-attr">plugins</span>: {
      <span class="hljs-attr">legend</span>: {
        <span class="hljs-attr">position</span>: <span class="hljs-string">'bottom'</span>
      }
    }
  };

  <span class="hljs-keyword">const</span> marimekkoChart = <span class="hljs-keyword">new</span> Chart(ctx, {
    <span class="hljs-attr">type</span>: <span class="hljs-string">'bar'</span>,
    <span class="hljs-attr">data</span>: data,
  });
}
</code></pre>
<p>In this example, we're creating a Marimekko chart with three subcategories for two categories. We've set the type of chart to 'bar', and we're passing in our data and options. The 'indexAxis' option is set to 'y' to make the chart horizontal, and the 'legend' option is set to position the legend at the bottom of the chart.</p>
<p>Congratulations! If you have followed along carefully then you shouldn’t run into any errors and your output may look like the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/Mekkochart.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And that's it! With this code, we can create a Marimekko chart in Chart.js in Angular. </p>
<p>You can further customize your chart using various Chart.js options and APIs, such as adjusting the colors, labels, and tooltip behaviors, to make it even more informative and engaging.</p>
<h1 id="heading-conclusion">C<strong>onclusion</strong></h1>
<p>Chart.js is a very useful and powerful library. In this quick tutorial, we've covered how to create a Marimekko chart in Chart.js in Angular. If you want to include any type of chart in your Angular application, then it is very easy to make them with Chart.js.</p>
<p>The full code for this Angular application is hosted on my <a target="_blank" href="https://github.com/SwatejPatil/Chart.js-Tutorial-How-to-Make-a-Marimekko-Chart-in-Angular">GitHub Repo</a>.</p>
<p>I hope you found this tutorial helpful and informative. If you have any questions or feedback, feel free to to contact me on <a target="_blank" href="http://www.linkedin.com/in/swatejpatil/">LinkedIn</a>!</p>
<h3 id="heading-related-articles-ive-written-about-chartjs"><strong>Related Articles I've Written about Chart.js:</strong></h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/chart-js-zooom-plugin/">How to Make Bar and Line Charts using Chart.js in Angular</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-pie-and-doughnut-charts-using-chartjs-in-angular/">Chart.js Tutorial – How to Make Pie and Doughnut Charts in Angular</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/chart-js-zooom-plugin/">How to Add the Chart.js Zoom Plugin to an Angular App</a></li>
</ul>
<p>Photo by <a target="_blank" href="https://unsplash.com/@austindistel?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Austin Distel</a> on <a target="_blank" href="https://unsplash.com/photos/DfjJMVhwH_8?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Chart.js Tutorial – How to Make Pie and Doughnut Charts in Angular ]]>
                </title>
                <description>
                    <![CDATA[ By Swatej Patil In this tutorial we will learn how to create a simple pie and doughnut chart using the Chart.js library in an Angular application. What is Chart.js? Chart.js is a JavaScript library for building charts. It's designed to be intuitive a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-pie-and-doughnut-charts-using-chartjs-in-angular/</link>
                <guid isPermaLink="false">66d46150d14641365a050973</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chartjs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data analysis ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 31 Jan 2023 17:03:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/piechart-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Swatej Patil</p>
<p>In this tutorial we will learn how to create a simple pie and doughnut chart using the Chart.js library in an Angular application.</p>
<h2 id="heading-what-is-chartjs">What is Chart.js?</h2>
<p>Chart.js is a JavaScript library for building charts. It's designed to be intuitive and simple, but it's powerful enough to build complex visualizations. </p>
<p>It has a wide range of chart types, including bar charts, line charts, pie charts, scatter plots, and many more. Chart.js is open-source and can be used without any restrictions on private or commercial projects.</p>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<p>Before we get started with making the charts, just make sure you meet the following prerequisites:</p>
<ul>
<li>Basic understanding of HTML /CSS and TypeScript especially the understanding of Object Oriented concepts of TypeScript classes and methods.</li>
<li>Node.js version 10 or higher and NPM or Yarn package manager. You can download node.js from <a target="_blank" href="https://nodejs.org/en/download/">here</a>.</li>
</ul>
<h2 id="heading-how-to-install-angular-cli">How to Install Angular CLI</h2>
<p>We will be using the Angular CLI to generate a starter application for our project. You can install Angular CLI by executing the following command on a terminal or Powershell window:</p>
<pre><code>npm install -g @angular/cli
</code></pre><p>If you have Angular CLI installed already, you can skip this step.</p>
<h2 id="heading-how-to-create-a-angular-application">How to Create a Angular Application</h2>
<p>Now let’s create an Angular application that will hold our graphs. In a terminal, execute the following commands:</p>
<pre><code class="lang-bash"> ng new angular-chartjs
</code></pre>
<p>Now that our Angular application has been created, navigate to the project folder and start the local development server using the following command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> angular-chartjs
ng serve -o
</code></pre>
<p>A browser window will open on <code>http://localhost:4200/</code>  and you can see your running Angular application.</p>
<h2 id="heading-how-to-install-the-chartjs-package">How to Install the Chart.js Package</h2>
<p>Now open a new terminal window in the same directory and install the Chart.js library using the following:</p>
<pre><code class="lang-bash">npm install chart.js
</code></pre>
<p>Now we need to create two Angular components, one for the Pie graph and the other for the Doughnut chart. You can create them easily with the angular CLI by executing the following commands:</p>
<pre><code class="lang-bash">ng generate component pie-chart
ng generate component doughnut-chart
</code></pre>
<h2 id="heading-how-to-create-a-pie-chart-in-chartjs">How to Create a Pie Chart in Chart.js</h2>
<p>A pie chart is a circular graph that displays data in slices, where each slice represents a category of data. The size of each slice represents the proportion of the category in relation to the whole data set.</p>
<p>Pie charts are an effective way to show the breakdown of data into categories, especially when the data represents parts of a whole. They are useful when you want to show how much each category contributes to the total.</p>
<p>When to use pie charts:</p>
<ul>
<li>To show the proportions of different categories in a whole</li>
<li>To compare the relative sizes of different categories</li>
<li>To demonstrate how each category contributes to the whole </li>
</ul>
<p>Pie charts are commonly used in business and economics to show the distribution of expenditures, market shares, or other aspects of the company's performance.</p>
<p>Now that we have created the components, we will move on with creating the pie chart.</p>
<p>Navigate to the <code>/src/app/pie-chart</code> component and open the <code>pie-chart.component.html</code> file and paste the following code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chart-container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>  <span class="hljs-attr">id</span>=<span class="hljs-string">"MyChart"</span> &gt;</span>{{ chart }}<span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We have simply created a container, and inside that container a canvas with an id of <code>MyChart</code>. We have used Angular’s string interpolation to render the <code>chart</code> variable, which we will create soon.</p>
<p>Inside the pie-chart component, open the <code>pie-chart.component.ts</code> file and import the Chart.js library using the following command:</p>
<pre><code class="lang-bash">import Chart from <span class="hljs-string">'chart.js/auto'</span>;
</code></pre>
<p>Now let’s make the <code>chart</code> variable we mentioned earlier. This variable will hold the information of our graphs.</p>
<pre><code class="lang-tsx">public chart: any;
</code></pre>
<p>Now we will create a method for the pie chart. This will include the data and labels for our chart.  </p>
<p>Copy the following code and paste it in the <code>pie-chart.component.ts</code> file below the <code>ngOnInit()</code> function:</p>
<pre><code class="lang-tsx">createChart(){

    this.chart = new Chart("MyChart", {
      type: 'pie', //this denotes tha type of chart

      data: {// values on X-Axis
        labels: ['Red', 'Pink','Green','Yellow','Orange','Blue', ],
           datasets: [{
    label: 'My First Dataset',
    data: [300, 240, 100, 432, 253, 34],
    backgroundColor: [
      'red',
      'pink',
      'green',
            'yellow',
      'orange',
      'blue',            
    ],
    hoverOffset: 4
  }],
      },
      options: {
        aspectRatio:2.5
      }

    });
  }
</code></pre>
<p>Here we have set the <code>type</code> of chart as <code>pie</code>. We have given labels as the names of common colors. And we've added data values, which will be automatically allocated a portion of pie in the pie chart.</p>
<p>We want our <code>createChart()</code> function to run as soon as the page loads. In order to do that, we need to call the function in the <code>ngOnInit()</code>:</p>
<pre><code class="lang-tsx">ngOnInit(): void {
    this.createChart();
  }
</code></pre>
<p>Finally, we need to add the HTML selector of the pie-chart component to the <code>app.component.html</code>  file. Remove the initial template code of Angular and add the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">app-pie-chart</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-pie-chart</span>&gt;</span>
</code></pre>
<p>Save all the files and the browser window will refresh automatically. Your first pie chart is ready!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/piechart.png" alt="Image" width="600" height="400" loading="lazy">
<em>Our pie chart</em></p>
<h2 id="heading-how-to-create-a-doughnut-chart-in-chartjs">How to Create a Doughnut Chart in Chart.js</h2>
<p>A doughnut chart is a variation of the pie chart and serves the same purpose of representing data in a circular format. It is made up of multiple sectors, where each sector represents a data value, with the size of each sector proportional to its value.</p>
<p>You can use a doughnut chart:</p>
<ul>
<li>To show a parts-to-whole relationship in data</li>
<li>To compare different categories of data</li>
<li>To show progress towards a goal or target</li>
</ul>
<p>Now we will move on with creating the doughnut chart. Since Doughnut charts and Pie charts can be used interchangeably, we don’t need to modify anything except the type of chart. Just follow the same steps  you have done so far and make sure to do them on the doughnut chart component.</p>
<p>Paste the same code for <code>createChart()</code> method on the <code>doughnut-chart.component.ts</code> file below the <code>ngOnInit()</code> function. You just need to change the keyword for type of chart from <code>pie</code> to <code>doughnut</code>. Your code should look like the following:</p>
<pre><code class="lang-tsx">createChart(){

    this.chart = new Chart("MyChart", {
      type: 'doughnut', //this denotes tha type of chart

      data: {// values on X-Axis
        labels: ['Red', 'Pink','Green','Yellow','Orange','Blue', ],
           datasets: [{
    label: 'My First Dataset',
    data: [300, 240, 100, 432, 253, 34],
    backgroundColor: [
      'red',
      'pink',
      'green',
            'yellow',
      'orange',
      'blue',            
    ],
    hoverOffset: 4
  }],
      },
      options: {
        aspectRatio:2.5
      }

    });
  }
</code></pre>
<p>Call the <code>createChart()</code> function in <code>ngOnInit()</code> and your line chart will be ready.</p>
<pre><code class="lang-tsx">ngOnInit(): void {
    this.createChart();
  }
</code></pre>
<p>Finally, we need to add the HTML selector for the line-chart component to the <code>app.component.html</code> file.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">app-doughnut-chart</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-doughnut-chart</span>&gt;</span>
</code></pre>
<p>Your output may look like the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/doughtnutchart.png" alt="Image" width="600" height="400" loading="lazy">
<em>Our doughnut chart</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Chart.js is a very useful and powerful library. If you want to include any type of chart in your Angular application, then it is very easy to make them with Chart.js.</p>
<p>The full code for this Angular application is hosted on my <a target="_blank" href="https://github.com/SwatejPatil/Pie-and-Doughnut-Charts-using-ChartJs-in-Angular/upload/main">GitHub Repo</a>.</p>
<p>I hope you found this tutorial helpful. Thank you for reading!</p>
<h3 id="heading-related-articles">Related Articles</h3>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/chart-js-zooom-plugin/">How to Make Bar and Line Charts using Chart.js in Angular</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add ESLint to an Angular Application ]]>
                </title>
                <description>
                    <![CDATA[ By Rodrigo Kamada In this article, we'll build a web application using the latest version of Angular. Then we'll add ESLint which analyzes the JavaScript code statically to find any problems. Prerequisites Before you start, you need to install and co... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-eslint-to-an-angular-application/</link>
                <guid isPermaLink="false">66d460c9c7632f8bfbf1e495</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ eslint ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 15 Nov 2022 16:39:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/angular-eslint-cover-hashnode.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Rodrigo Kamada</p>
<p>In this article, we'll build a web application using the latest version of <a target="_blank" href="https://angular.io/">Angular</a>. Then we'll add <a target="_blank" href="https://eslint.org/">ESLint</a> which analyzes the JavaScript code statically to find any problems.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start, you need to install and configure the tools below (if you don't already have them installed) to create the Angular application:</p>
<ul>
<li><a target="_blank" href="https://git-scm.com/">Git</a>: Git is a distributed version control system. We'll use it to sync the repository.</li>
<li><a target="_blank" href="https://nodejs.org/">Node.js and npm</a>: Node.js is a JavaScript code runtime software based on Google's V8 engine. npm is a package manager for Node.js (Node Package Manager). We'll use them to build and run the Angular application and install the libraries.</li>
<li><a target="_blank" href="https://angular.io/cli">Angular CLI</a>: Angular CLI is a command line utility tool for Angular. We'll use it to create the base structure of the Angular application.</li>
<li>IDE (for example <a target="_blank" href="https://code.visualstudio.com/">Visual Studio Code</a> or <a target="_blank" href="https://www.jetbrains.com/webstorm/">WebStorm</a>): an Integrated Development Environment is a tool with a graphical interface to help in the development of applications. We'll use it to develop the Angular application.</li>
</ul>
<h2 id="heading-getting-started">Getting Started</h2>
<h3 id="heading-create-the-angular-application">Create the Angular application</h3>
<p>Angular is a development platform for building web, mobile and desktop applications using HTML, CSS, and TypeScript (JavaScript). Currently, Angular is at version 14 and Google is the main maintainer of the project.</p>
<p>First, let's create the application with the Angular base structure using the <code>@angular/cli</code> with the route file and the SCSS style format.</p>
<pre><code>ng <span class="hljs-keyword">new</span> angular-eslint --routing <span class="hljs-literal">true</span> --style scss
CREATE angular-eslint/README.md (<span class="hljs-number">1067</span> bytes)
CREATE angular-eslint/.editorconfig (<span class="hljs-number">274</span> bytes)
CREATE angular-eslint/.gitignore (<span class="hljs-number">548</span> bytes)
CREATE angular-eslint/angular.json (<span class="hljs-number">3136</span> bytes)
CREATE angular-eslint/package.json (<span class="hljs-number">1045</span> bytes)
CREATE angular-eslint/tsconfig.json (<span class="hljs-number">863</span> bytes)
CREATE angular-eslint/.browserslistrc (<span class="hljs-number">600</span> bytes)
CREATE angular-eslint/karma.conf.js (<span class="hljs-number">1431</span> bytes)
CREATE angular-eslint/tsconfig.app.json (<span class="hljs-number">287</span> bytes)
CREATE angular-eslint/tsconfig.spec.json (<span class="hljs-number">333</span> bytes)
CREATE angular-eslint/.vscode/extensions.json (<span class="hljs-number">130</span> bytes)
CREATE angular-eslint/.vscode/launch.json (<span class="hljs-number">474</span> bytes)
CREATE angular-eslint/.vscode/tasks.json (<span class="hljs-number">938</span> bytes)
CREATE angular-eslint/src/favicon.ico (<span class="hljs-number">948</span> bytes)
CREATE angular-eslint/src/index.html (<span class="hljs-number">299</span> bytes)
CREATE angular-eslint/src/main.ts (<span class="hljs-number">372</span> bytes)
CREATE angular-eslint/src/polyfills.ts (<span class="hljs-number">2338</span> bytes)
CREATE angular-eslint/src/styles.scss (<span class="hljs-number">80</span> bytes)
CREATE angular-eslint/src/test.ts (<span class="hljs-number">749</span> bytes)
CREATE angular-eslint/src/assets/.gitkeep (<span class="hljs-number">0</span> bytes)
CREATE angular-eslint/src/environments/environment.prod.ts (<span class="hljs-number">51</span> bytes)
CREATE angular-eslint/src/environments/environment.ts (<span class="hljs-number">658</span> bytes)
CREATE angular-eslint/src/app/app-routing.module.ts (<span class="hljs-number">245</span> bytes)
CREATE angular-eslint/src/app/app.module.ts (<span class="hljs-number">393</span> bytes)
CREATE angular-eslint/src/app/app.component.scss (<span class="hljs-number">0</span> bytes)
CREATE angular-eslint/src/app/app.component.html (<span class="hljs-number">23364</span> bytes)
CREATE angular-eslint/src/app/app.component.spec.ts (<span class="hljs-number">1097</span> bytes)
CREATE angular-eslint/src/app/app.component.ts (<span class="hljs-number">219</span> bytes)
✔ Packages installed successfully.
    Successfully initialized git.
</code></pre><p>Now we will install the libraries and add the ESLint settings.</p>
<pre><code>ng add @angular-eslint/schematics
ℹ Using package manager: npm
✔ Found compatible package version: @angular-eslint/schematics@<span class="hljs-number">14.2</span><span class="hljs-number">.5</span>.
✔ Package information loaded.

The package @angular-eslint/schematics@<span class="hljs-number">14.2</span><span class="hljs-number">.5</span> will be installed and executed.
Would you like to proceed? Yes
✔ Packages successfully installed.

    All @angular-eslint dependencies have been successfully installed 🎉

    Please see https:<span class="hljs-comment">//github.com/angular-eslint/angular-eslint for how to add ESLint configuration to your project.</span>

    We detected that you have a single project <span class="hljs-keyword">in</span> your workspace and no existing linter wired up, so we are configuring ESLint <span class="hljs-keyword">for</span> you automatically.

    Please see https:<span class="hljs-comment">//github.com/angular-eslint/angular-eslint for more information.</span>

CREATE .eslintrc.json (<span class="hljs-number">984</span> bytes)
UPDATE package.json (<span class="hljs-number">1511</span> bytes)
UPDATE angular.json (<span class="hljs-number">3447</span> bytes)
✔ Packages installed successfully.
</code></pre><p>Next, we will run the command below to validate the ESLint installation and configuration:</p>
<pre><code>npm run lint

&gt; angular-eslint@<span class="hljs-number">1.0</span><span class="hljs-number">.0</span> lint /home/rodrigokamada/angular-eslint
&gt; ng lint


Linting <span class="hljs-string">"angular-eslint"</span>...

All files pass linting.
</code></pre><p>And you're all set! The message "<em>All files pass linting</em>" shows that no problems were found.</p>
<p>The application repository is <a target="_blank" href="https://github.com/rodrigokamada/angular-eslint.">available here</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This is what we covered in this article:</p>
<ul>
<li>We created an Angular application.</li>
<li>We added ESLint to analyze and find problems with the code.</li>
</ul>
<p>You can use this to check your application code before deploying to your environment.</p>
<p>Thank you for reading and I hope you enjoyed the article!</p>
<p>This tutorial was posted on my <a target="_blank" href="https://rodrigo.kamada.com.br/blog/adicionando-o-eslint-em-uma-aplicacao-angular">blog</a> in Portuguese.</p>
<p>To stay updated whenever I post new articles, follow me on <a target="_blank" href="https://twitter.com/rodrigokamada">Twitter</a> and <a target="_blank" href="https://www.linkedin.com/in/rodrigokamada">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Build a Webshop with Angular, Node.js, TypeScript, & Stripe ]]>
                </title>
                <description>
                    <![CDATA[ Learn how to build a webshop from scratch! We just published a course on the freeCodeCamp.org YouTube channel that will teach you how to build a webshop or e-commerce store using Angular/TypeScript, Express.js, and Stripe.  You will learn how to use ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-webshop-with-angular-node-js-typescript-stripe/</link>
                <guid isPermaLink="false">66b200ec09c44225ad2c3973</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 12 Oct 2022 13:46:34 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/webshop.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Learn how to build a webshop from scratch!</p>
<p>We just published a course on the freeCodeCamp.org YouTube channel that will teach you how to build a webshop or e-commerce store using Angular/TypeScript, Express.js, and Stripe. </p>
<p>You will learn how to use Angular material and Tailwind to structure the UI and how to integrate a store API into the app. Also at the end, you will build a checkout, and learn how to integrate Stripe so that the app can process payments.</p>
<p>Slobodan Gajic created this course. Slobodan is a senior frontend developer and an experienced course creator.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Oct-12-2022-09-44-32.gif" alt="Image" width="600" height="400" loading="lazy">
<em>You will build this.</em></p>
<p>Here are the sections in this course:</p>
<ul>
<li>Installing dependencies and project setup</li>
<li>Building home page</li>
<li>Building cart page</li>
<li>Implementing Cart logic</li>
<li>Implementing Store API</li>
<li>Stripe payment implementation</li>
</ul>
<p>Watch the full course below or on <a target="_blank" href="https://youtu.be/Kbauf9IgsC4">the freeCodeCamp.org YouTube channel</a> (4-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Kbauf9IgsC4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add the Chart.js Zoom Plugin to an Angular App ]]>
                </title>
                <description>
                    <![CDATA[ By Swatej Patil In this tutorial you will learn how to the Add Chart.js Zoom plugin to an Angular application. When you have a lot of data in a chart, you may want to zoom in and see the details. Line charts are a good way to visualise large amounts ]]>
                </description>
                <link>https://www.freecodecamp.org/news/chart-js-zooom-plugin/</link>
                <guid isPermaLink="false">66d4614b4a0edd9b48e83591</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chartjs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ charts ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 12 Sep 2022 18:38:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/chartjsZoom.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Swatej Patil</p>
<p>In this tutorial you will learn how to the Add Chart.js Zoom plugin to an Angular application.</p>
<p>When you have a lot of data in a chart, you may want to zoom in and see the details. Line charts are a good way to visualise large amounts of data. You can use the zooming feature in Chart.js to explore your data more closely.</p>
<p>Chart.js is an open-source library you can use to create beautiful charts in any part of your Angular application. The Zooming feature was created to allow you to magnify certain data points for closer inspection. You can quickly and easily zoom by scrolling with the mouse wheel.</p>
<p>Let's see how it works.</p>
<h2 id="heading-getting-started">Getting Started</h2>
<p>I'm going to assume that you already know how to use Chart.js in an Angular application to create simple line and bar charts. </p>
<p>Don't worry if you don't – I've got you covered. You can follow my <a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-bar-and-line-charts-using-chartjs-in-angular/">Chart.js Tutorial – How to Make Bar and Line Charts in Angular</a> to get started.</p>
<p>We will create a new Angular component just for the line chart and then incorporate the zoom plugin into it. We will be using a large amount of data to see how useful the Zoom plugin is.</p>
<p>But first, in your Angular application, you'll need to install the Chart.js Zoom plugin if you don't already have it. </p>
<p>Open up a new terminal in the Angular project folder and paste in the following command:</p>
<pre><code class="lang-bash">npm install chartjs-plugin-zoom
</code></pre>
<p>This will install the plugin into your Angular application.</p>
<p>Now let’s create a new Angular component and make the line chart. Use the following to create a new Angular component:</p>
<pre><code class="lang-bash">ng g c line-chart
</code></pre>
<p>This will create a new Angular component in the <code>/src</code> directory. </p>
<p>Then open the <code>line-chart.component.html</code> file and paste in the following code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chart-container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>  <span class="hljs-attr">id</span>=<span class="hljs-string">"MyChart"</span> &gt;</span>{{ chart }}<span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Now open the <code>line-chart.component.ts</code> file and delete all the code inside it. Then paste in the following code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Component, OnInit } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> Chart <span class="hljs-keyword">from</span> <span class="hljs-string">'chart.js/auto'</span>;

@Component({
  <span class="hljs-attr">selector</span>: <span class="hljs-string">'app-line-chart'</span>,
  <span class="hljs-attr">templateUrl</span>: <span class="hljs-string">'./line-chart.component.html'</span>,
  <span class="hljs-attr">styleUrls</span>: [<span class="hljs-string">'./line-chart.component.css'</span>]
})
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LineChartComponent</span> <span class="hljs-title">implements</span> <span class="hljs-title">OnInit</span> </span>{

  <span class="hljs-keyword">constructor</span>() { }

  ngOnInit(): <span class="hljs-keyword">void</span> {
    <span class="hljs-built_in">this</span>.createChart();
  }
  public chart: any;

  createChart() {

    <span class="hljs-built_in">this</span>.chart = <span class="hljs-keyword">new</span> Chart(<span class="hljs-string">"MyChart"</span>, {
      <span class="hljs-attr">type</span>: <span class="hljs-string">'line'</span>, <span class="hljs-comment">//this denotes tha type of chart</span>

      <span class="hljs-attr">data</span>: {<span class="hljs-comment">// values on X-Axis</span>
        <span class="hljs-attr">labels</span>: [<span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>,
          <span class="hljs-string">"Monday"</span>, <span class="hljs-string">"Tuesday"</span>, <span class="hljs-string">"Wednesday"</span>, <span class="hljs-string">"Thursday"</span>, <span class="hljs-string">"Friday"</span>, <span class="hljs-string">"Saturday"</span>, <span class="hljs-string">"Sunday"</span>],
        <span class="hljs-attr">datasets</span>: [
          {
            <span class="hljs-attr">label</span>: <span class="hljs-string">"Sales"</span>,
            <span class="hljs-attr">data</span>: [<span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>,
            <span class="hljs-string">'467'</span>, <span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>, <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>, ],
            <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">'blue'</span>,
            <span class="hljs-attr">borderColor</span>: <span class="hljs-string">"#084de0"</span>
          }
        ]
      },
      <span class="hljs-attr">options</span>: {
        <span class="hljs-attr">aspectRatio</span>: <span class="hljs-number">3</span>
      }

    });
  }

}
</code></pre>
<p>Again, if you don’t know how this code works, you can always refer back to this <a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-bar-and-line-charts-using-chartjs-in-angular/">Chart.js Tutorial</a>.</p>
<p>We need to add the HTML selector of the line-chart component to the <code>app.component.html</code> file. Remove the initial template code of Angular and add the following:</p>
<pre><code>&lt;app-line-chart&gt;&lt;/app-line-chart&gt;
</code></pre><p>Start the local development server using the following command:</p>
<pre><code class="lang-bash">ng serve -o
</code></pre>
<p> A browser window will open on http://localhost:4200/ and you can see your running Angular application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/NotZoomLine.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As you can see, in order to present the entire chart, this graph begins to skip some labels. It will seem more worse if the graph has more data.</p>
<p>Let's now add a zooming function to our chart so we can enlarge the data points for a closer look.</p>
<h2 id="heading-how-to-add-the-chartjs-zoom-plugin">How to Add the Chart.js Zoom Plugin</h2>
<p>Open the <code>line-chart.component.ts</code> file and import the chart.js Zoom plugin. Make sure you register it after importing it. The following code will show you how to do it:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> zoomPlugin <span class="hljs-keyword">from</span> <span class="hljs-string">'chartjs-plugin-zoom'</span>;
Chart.register(zoomPlugin);
</code></pre>
<p>Now that you have imported the plugin, in the Chart.js option we will add the plugin and enable the zoom on the wheel.</p>
<pre><code class="lang-js">options: {
        <span class="hljs-attr">aspectRatio</span>: <span class="hljs-number">3</span>,
        <span class="hljs-attr">plugins</span>: {
          <span class="hljs-attr">zoom</span>: {
            <span class="hljs-attr">zoom</span>: {
              <span class="hljs-attr">wheel</span>: {
                <span class="hljs-attr">enabled</span>: <span class="hljs-literal">true</span>,
              },
              <span class="hljs-attr">pinch</span>: {
                <span class="hljs-attr">enabled</span>: <span class="hljs-literal">true</span>
              },
              <span class="hljs-attr">mode</span>: <span class="hljs-string">'xy'</span>,
            }
          }
        }
      }
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/09/ChartjsZoom.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As you can see , now we can zoom in into the point we want to see closely. </p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>The full code for this Angular application is hosted on my <a target="_blank" href="https://github.com/SwatejPatil/ChartJs-Zoom-Plugin-Tutorial">GitHub</a>.</p>
<p>I hope you found this tutorial helpful.If you have any questions or comments, please do not hesitate to contact me on <a target="_blank" href="http://www.linkedin.com/in/swatejpatil/">LinkedIn</a>. I'll be more than pleased to assist you with your questions.</p>
<p>Thank you for reading!</p>
<p>Photo by <a href="https://unsplash.com/@isaacmsmith?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Isaac Smith</a> on <a href="https://unsplash.com/s/photos/line-chart?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Angular for Beginners Course + TypeScript [Full Front-End Tutorial] ]]>
                </title>
                <description>
                    <![CDATA[ Angular is a popular TypeScript-based open-source web application framework created by Google. We just published a comprehensive 18-hour Angular course for beginners on the freeCodeCamp.org YouTube channel. In this course you will first you will lear... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/angular-for-beginners-course/</link>
                <guid isPermaLink="false">66b20079297cd6de0bd545e7</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ beginner ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 07 Sep 2022 16:45:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/angular.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Angular is a popular TypeScript-based open-source web application framework created by Google.</p>
<p>We just published a comprehensive 18-hour Angular course for beginners on the freeCodeCamp.org YouTube channel.</p>
<p>In this course you will first you will learn the basics of TypeScript. Then you will learn about important Angular concepts such as binding, dependency injection, forms, routing, and more.</p>
<p>Santosh Yadav created this course. He is a Google Developer Expert for Angular, a GitHub Star, and an active contributor to both Angular and NgRx. So he is the perfect person to teach you Angular.</p>
<p>Here are the sections covered in this course:</p>
<h3 id="heading-introduction">Introduction</h3>
<ul>
<li>Introduction to Angular</li>
<li>Introduction to Typescript</li>
<li>SPA and Local Setup</li>
</ul>
<h3 id="heading-typescript">Typescript</h3>
<ul>
<li>Typescript Data Types and Functions</li>
<li>Classes and Interface</li>
<li>Typescript decorators and tsconfig file</li>
</ul>
<h3 id="heading-angular-installation-and-basics">Angular Installation and Basics</h3>
<ul>
<li>Angular Installation and Binding Syntax</li>
<li>Built-in Directives</li>
<li>Built-in Pipes</li>
<li>Adding Bootstrap CSS to App</li>
</ul>
<h3 id="heading-lifecycle-hook-and-component-communication">Lifecycle Hook and Component Communication</h3>
<ul>
<li>ngOnInt and Component Communication using Input and Output</li>
<li>Change Detection and ngOnChanges</li>
<li>ngDoCheck</li>
<li>ViewChild, ViewChildren and AfterViewInit</li>
<li>Content Projection, AfterContentInit and OnDestroy</li>
</ul>
<h3 id="heading-dependency-injection">Dependency Injection</h3>
<ul>
<li>Introduction</li>
<li>Resolution Modifiers</li>
<li>Value Providers</li>
</ul>
<h3 id="heading-httpclient-and-rxjs">HttpClient and RxJs</h3>
<ul>
<li>Setting Up HttpClientModule</li>
<li>HttpService , RxJs observables and http get</li>
<li>RxJs Observable and Observer</li>
<li>Http Put and Delete</li>
<li>Http Request</li>
<li>ShareReplay RxJs Operators</li>
<li>Async Pipe</li>
<li>catchError operator</li>
<li>map operator</li>
<li>Http Interceptor</li>
<li>APP_INITIALIZER</li>
</ul>
<h3 id="heading-routing-basics">Routing Basics</h3>
<ul>
<li>Angular Router and default Route</li>
<li>Adding Angular material and navigation</li>
<li>Wild card, dynamic route and ActivatedRoute service</li>
<li>ParamMap and Activate Route Service</li>
</ul>
<h3 id="heading-template-driven-forms">Template Driven Forms</h3>
<ul>
<li>Introduction</li>
<li>Validation</li>
<li>Pristine, Dirty State and Reset Form</li>
<li>Custom Directives and Custom Validation</li>
</ul>
<h3 id="heading-advanced-routing">Advanced Routing</h3>
<ul>
<li>Navigation using Router Service</li>
<li>Feature and Routing Module</li>
<li>Nested and Child Route</li>
<li>Lazy Loading</li>
<li>Configure Lazy Loading using CLI</li>
<li>Using ProvidedIn Any</li>
<li>Router Events</li>
<li>Listening to Router Events</li>
</ul>
<h3 id="heading-route-guards">Route Guards</h3>
<ul>
<li>CanActivate</li>
<li>CanActivateChild</li>
<li>CanLoad</li>
</ul>
<h3 id="heading-reactive-forms">Reactive Forms</h3>
<ul>
<li>Introduction</li>
<li>Using Material Controls</li>
<li>Nested Form Controls</li>
<li>Dynamic Forms</li>
<li>Built-in Validators</li>
<li>Reset Form</li>
<li>Control Level Validation</li>
<li>SetValue and PatchValue</li>
<li>ValueChanges and UpdateOn</li>
<li>map operator with Form</li>
<li>Custom Validator</li>
</ul>
<h3 id="heading-candeactivate-guard">CanDeactivate Guard</h3>
<ul>
<li>CanDeactivate Guard and Form</li>
</ul>
<h3 id="heading-custom-pipes-and-errors">Custom Pipes and Errors</h3>
<ul>
<li>Custom Pipe</li>
<li>Resolve Guard</li>
<li>Error Handling</li>
</ul>
<h3 id="heading-testing-basics">Testing Basics</h3>
<ul>
<li>Introduction</li>
<li>First test</li>
<li>Testing Component and Service</li>
<li>Deployment and CI/CD</li>
<li>Using Netlify for Deployment</li>
<li>GitHub Actions to Automate Tasks</li>
</ul>
<p>Watch the full course below or <a target="_blank" href="https://youtu.be/3qBXWUpoPHo">on the freeCodeCamp.org YouTube channel</a> (18-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/3qBXWUpoPHo" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Chart.js Tutorial – How to Make Bar and Line Charts in Angular ]]>
                </title>
                <description>
                    <![CDATA[ By Swatej Patil In this tutorial we will learn how to create simple bar and line charts using the Chart.js library in an Angular application. But first of all, what is Chart.js and what does it do? What is Chart.js? Chart.js is a JavaScript library f... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-bar-and-line-charts-using-chartjs-in-angular/</link>
                <guid isPermaLink="false">66d4614da326133d12440a8e</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ charts ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 23 Aug 2022 15:35:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/Line-Bar-4.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Swatej Patil</p>
<p>In this tutorial we will learn how to create simple bar and line charts using the Chart.js library in an Angular application.</p>
<p>But first of all, what is Chart.js and what does it do?</p>
<h2 id="heading-what-is-chartjs">What is Chart.js?</h2>
<p>Chart.js is a JavaScript library for building charts. It's designed to be intuitive and simple, but powerful enough to build complex visualizations. It has a wide range of chart types including bar charts, line charts, pie charts, scatter plots, and many more. </p>
<p>ChartJs is open-source and you can use it without any restrictions on private or commercial projects. It's written in pure JavaScript and has no dependencies on other libraries such as jQuery or D3. </p>
<p>It also provides options for animating data updates and adding interactivity to charts such as tooltips and click events.</p>
<p>It was created by the team at Plotly and it’s free to use.</p>
<p>Now we can move on with creating our first bar graph in Chart.js</p>
<p>##Prerequisites
Before we get started making the charts, just make sure you meet the following prerequisites:</p>
<ul>
<li>You have a basic understanding of HTML, CSS, and TypeScript, especially Object Oriented concepts of TypeScript classes and methods.</li>
<li>You have Node.js version 10 or higher and NPM or Yarn package manager. You can download Node.js from <a target="_blank" href="https://nodejs.org/en/download/">here</a>.</li>
</ul>
<h2 id="heading-how-to-install-angular-cli">How to Install Angular CLI</h2>
<p>Angular CLI is an official tool from the developers of Angular. It is a command-line interface tool which is very useful for initialising and developing Angular applications.  </p>
<p>You can install Angular CLI by executing the following command in a terminal or powershell window:</p>
<pre><code class="lang-shell">npm install -g @angular/cli
</code></pre>
<h2 id="heading-how-to-create-an-angular-application">How to Create an Angular Application</h2>
<p>Now let’s create an Angular application that will hold our graphs. In a terminal, execute the following commands:</p>
<pre><code class="lang-bash"> ng new angular-chartjs
</code></pre>
<p>Now that you've created your angular application, navigate to the project folder and start the local development server using the following command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> angular-chartjs
ng serve -o
</code></pre>
<p>A browser window will open on <code>http://localhost:4200/</code> and you can see your running Angular application there.</p>
<p>Now open a new terminal window in the same directory and install the Chart.js library using the following command:</p>
<pre><code class="lang-bash">npm install chart.js
</code></pre>
<p>Now we need to create two angular components: one for the Bar graph and the other for the line chart. </p>
<p>You can create them easily with the Angular CLI by executing the following commands:</p>
<pre><code class="lang-bash">ng generate component bar-chart
ng generate component line-chart
</code></pre>
<h2 id="heading-how-to-create-a-bar-graph-with-chartjs">How to Create a Bar Graph with Chart.js</h2>
<p>A bar graph is a graphical representation of data, in which the horizontal and vertical axes represent the values, and the length of each bar represents the values specified on the axis. </p>
<p>Bar graphs are one of the most common forms of graphs when it comes to representing data visually. We use them to identify trends and patterns in various data sets.</p>
<p>When to use bar charts:</p>
<ul>
<li>To show multiple values at once</li>
<li>To provide a graphical representation of data</li>
<li>To compare datasets</li>
<li>To examine relationships between different variables.</li>
</ul>
<p>A bar chart is often used in business and economics to show comparisons between products, services, or companies. In our example, we have taken the data of sales and profits made on each day during an 8-day period.</p>
<p>Now that we have created the components, we will move on with creating the bar chart.</p>
<p>Inside the bar-chart component, open the <code>bar-chart.component.html</code> file and paste the following code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"chart-container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>  <span class="hljs-attr">id</span>=<span class="hljs-string">"MyChart"</span> &gt;</span>{{ chart }}<span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We have simply created a container and inside that container a canvas with an id of <code>MyChart</code>. We have used Angular’s string interpolation to render the <code>chart</code> variable, which we will create in the canvas.</p>
<p>Inside the bar-chart component, open the <code>bar-chart.component.ts</code> file and import the Chart.js library using the following commands:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> Chart <span class="hljs-keyword">from</span> <span class="hljs-string">'chart.js/auto'</span>;
<span class="hljs-comment">//or</span>
<span class="hljs-keyword">import</span> Chart <span class="hljs-keyword">from</span> <span class="hljs-string">'chart.js'</span>;
</code></pre>
<p>Now let’s make the <code>chart</code> veritable we mentioned earlier. This variable will hold the information of our graphs.</p>
<pre><code class="lang-js">public chart: any;
</code></pre>
<p>Now we will create a method for the bar chart. This will include the data and labels for our bar chart. Copy the following code and paste it in the <code>bar-chart.component.ts</code> file below the <code>ngOnInit()</code> function:</p>
<pre><code class="lang-js">createChart(){

    <span class="hljs-built_in">this</span>.chart = <span class="hljs-keyword">new</span> Chart(<span class="hljs-string">"MyChart"</span>, {
      <span class="hljs-attr">type</span>: <span class="hljs-string">'bar'</span>, <span class="hljs-comment">//this denotes tha type of chart</span>

      <span class="hljs-attr">data</span>: {<span class="hljs-comment">// values on X-Axis</span>
        <span class="hljs-attr">labels</span>: [<span class="hljs-string">'2022-05-10'</span>, <span class="hljs-string">'2022-05-11'</span>, <span class="hljs-string">'2022-05-12'</span>,<span class="hljs-string">'2022-05-13'</span>,
                                 <span class="hljs-string">'2022-05-14'</span>, <span class="hljs-string">'2022-05-15'</span>, <span class="hljs-string">'2022-05-16'</span>,<span class="hljs-string">'2022-05-17'</span>, ], 
           <span class="hljs-attr">datasets</span>: [
          {
            <span class="hljs-attr">label</span>: <span class="hljs-string">"Sales"</span>,
            <span class="hljs-attr">data</span>: [<span class="hljs-string">'467'</span>,<span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>,
                                 <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>, <span class="hljs-string">'576'</span>],
            <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">'blue'</span>
          },
          {
            <span class="hljs-attr">label</span>: <span class="hljs-string">"Profit"</span>,
            <span class="hljs-attr">data</span>: [<span class="hljs-string">'542'</span>, <span class="hljs-string">'542'</span>, <span class="hljs-string">'536'</span>, <span class="hljs-string">'327'</span>, <span class="hljs-string">'17'</span>,
                                     <span class="hljs-string">'0.00'</span>, <span class="hljs-string">'538'</span>, <span class="hljs-string">'541'</span>],
            <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">'limegreen'</span>
          }  
        ]
      },
      <span class="hljs-attr">options</span>: {
        <span class="hljs-attr">aspectRatio</span>:<span class="hljs-number">2.5</span>
      }

    });
  }
</code></pre>
<p>The above code might look daunting at first, but it's quite simple. We are providing the type of chart, the labels, and the data.</p>
<p>We want our <code>createChart()</code> function to run as soon as the page loads. In order to do that we need to call the function in the <code>ngOnInit()</code> like this:</p>
<pre><code class="lang-ts">ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.createChart();
  }
</code></pre>
<p>Finally, we need to add the HTML selector of the bar-chart component to the <code>app.component.html file.</code>. Remove the initial Angular template code and add the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">app-bar-chart</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-bar-chart</span>&gt;</span>
</code></pre>
<p>Congratulations! If you have followed along carefully then you shouldn’t run into any errors and your output may look like the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/barchart.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-create-a-line-graph-with-chartjs">How to Create a Line Graph with Chart.js</h2>
<p>Line charts similar to bar charts are often used to show trends in data over time, such as economic growth or changes in stock prices. </p>
<p>Line charts are also useful for showing changes in quantities, such as population over time or weight loss over a period of weeks. </p>
<p>With a line graph, as opposed to a bar graph, you draw individual points on the two axes and connect nearby points with straight lines.</p>
<p>When to use bar charts:</p>
<ul>
<li>When the differences in data points are smaller</li>
<li>To show trends over the course of time</li>
</ul>
<p>If you have created the bar graph, then creating a line graph is quite simple. Just follow the same steps you have done so far (and make sure to do them on the line chart component).</p>
<p>Paste the same code for <code>createChart()</code> method on the <code>line-chart.component.ts</code> file below the <code>ngOnInit()</code> function. You just need to change the keyword for type of chart from <code>bar</code> to <code>line</code>. </p>
<p>Your code should look like the following:</p>
<pre><code class="lang-ts">createChart(){

    <span class="hljs-built_in">this</span>.chart = <span class="hljs-keyword">new</span> Chart(<span class="hljs-string">"MyChart"</span>, {
      <span class="hljs-keyword">type</span>: <span class="hljs-string">'line'</span>, <span class="hljs-comment">//this denotes tha type of chart</span>

      data: {<span class="hljs-comment">// values on X-Axis</span>
        labels: [<span class="hljs-string">'2022-05-10'</span>, <span class="hljs-string">'2022-05-11'</span>, <span class="hljs-string">'2022-05-12'</span>,<span class="hljs-string">'2022-05-13'</span>,
                                 <span class="hljs-string">'2022-05-14'</span>, <span class="hljs-string">'2022-05-15'</span>, <span class="hljs-string">'2022-05-16'</span>,<span class="hljs-string">'2022-05-17'</span>, ], 
           datasets: [
          {
            label: <span class="hljs-string">"Sales"</span>,
            data: [<span class="hljs-string">'467'</span>,<span class="hljs-string">'576'</span>, <span class="hljs-string">'572'</span>, <span class="hljs-string">'79'</span>, <span class="hljs-string">'92'</span>,
                                 <span class="hljs-string">'574'</span>, <span class="hljs-string">'573'</span>, <span class="hljs-string">'576'</span>],
            backgroundColor: <span class="hljs-string">'blue'</span>
          },
          {
            label: <span class="hljs-string">"Profit"</span>,
            data: [<span class="hljs-string">'542'</span>, <span class="hljs-string">'542'</span>, <span class="hljs-string">'536'</span>, <span class="hljs-string">'327'</span>, <span class="hljs-string">'17'</span>,
                                     <span class="hljs-string">'0.00'</span>, <span class="hljs-string">'538'</span>, <span class="hljs-string">'541'</span>],
            backgroundColor: <span class="hljs-string">'limegreen'</span>
          }  
        ]
      },
      options: {
        aspectRatio:<span class="hljs-number">2.5</span>
      }

    });
  }
</code></pre>
<p>Call the <code>createChart()</code> function in <code>ngOnInit()</code> and your line chart is ready.</p>
<pre><code class="lang-ts">ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.createChart();
  }
</code></pre>
<p>Finally, we need to add the HTML selector of the line-chart component to the <code>app.component.html</code> file.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">app-line-chart</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-line-chart</span>&gt;</span>
</code></pre>
<p>Your output may look like the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/linechart.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The full code for this Angular application is hosted on my <a target="_blank" href="https://github.com/SwatejPatil/Bar-and-Line-Charts-using-ChartJs-in-Angular">GitHub Repo</a>. </p>
<p>I hope you found this tutorial helpful. Thank you for reading!</p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@lukechesser">Luke Chesser</a> | Unsplash</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
