<?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, 24 May 2026 16:30:37 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/angularjs/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 Transform an Angular Application with Signals ]]>
                </title>
                <description>
                    <![CDATA[ Angular is a famous framework for building robust and complex enterprise applications. It is widely used by large companies. Therefore, having the skills to build a performant application using Angular is one of the top skills for a developer.. Angul... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-transform-an-angular-appl-with-signals/</link>
                <guid isPermaLink="false">66e03251e308fdd18efc9b15</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Anujkumarsinh Donvir ]]>
                </dc:creator>
                <pubDate>Tue, 10 Sep 2024 11:49:37 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725482117668/26d8fde9-0ff5-4496-9de2-c9e0deb8a02c.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Angular is a famous framework for building robust and complex enterprise applications. It is widely used by large companies. Therefore, having the skills to build a performant application using Angular is one of the top skills for a developer..</p>
<p>Angular's rise to fame can be attributed to a special feature called reactivity. Reactivity is the ability of the framework to change the user interface (UI) when underlying data or state of the application changes.</p>
<p>This change can be due to asynchronous events like getting response from an API call, or from a user action such as clicking a button. To achieve this reactivity, Angular deploys a mechanism called change detection. Reactivity is a double-edged sword though, and can often lead to performance issues due to unwanted updates to UI.</p>
<p>Angular recently released a new feature called signals, which allows developers to improve the performance of existing applications built with Angular, as well build new applications which have significant performance gains over traditional Angular applications.</p>
<p>Signals give you control over change detection, and prevent unwanted updates to UI. It can be very tricky to transform existing applications to use signals, and this tutorial aims to guide you on getting started with it. In this tutorial, an existing Angular application, which was built traditionally, will be transformed step by step to use signals.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-run-an-existing-application">How to Run an Existing Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-the-existing-application-code">Understanding the Existing Application Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-transform-the-application-to-use-angular-signals">How to Transform the Application to Use Angular Signals</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow this tutorial you must meet below prerequisites:</p>
<ul>
<li><p>Have an understanding of JavaScript, TypeScript and the Angular framework.</p>
</li>
<li><p>Node.js and NPM installed on your machine. You can verify this using these commands: <code>node -v</code> and <code>npm --version</code>.</p>
</li>
<li><p>Git installed on your machine. You can verify this using <code>git --version</code>.</p>
<p>  <img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeA5rN06IP7YBlURVo8cJ24QdPVik3dxCci04fP3Yp9otnbB5A13q49K5OrmOKon9EUDRgEpxWXKV08dmkcSJtDkT0u4Ceq3mD_ER2aqJSCyshULZIcQBWz9MP-JC3faqWqE79fHIfsrfRvLw63JAQs0pQ?key=SIi3jhbWSizs2BNTxpZ_RQ" alt="node, npm, and git version in the terminal" class="image--center mx-auto" width="316" height="224" loading="lazy"></p>
</li>
<li><p>A code editor installed on your machine. This tutorial has been developed using Visual Studio Code, but any code editor should work.</p>
</li>
</ul>
<h2 id="heading-how-to-run-an-existing-application">How to Run an Existing Application</h2>
<p>We'll transform an existing application using Angular signal. The application is a timesheet management application in which a team lead/shift manager can see the number of hours each employee has worked each week, as well as team total hours.</p>
<p>The team lead can also update the hours of an employee as well. Follow the steps below to clone and run the application locally on your machine:</p>
<ul>
<li><p>Clone the application using the GitHub URL - https://github.com/anujkumartech/emp-time-tracker-1.git. You can use terminal or clone it directly inside your editor.</p>
</li>
<li><p>After cloning the app, open a new terminal if not already opened and go to the application folder using <code>cd emp-time-tracker-1</code>.</p>
</li>
<li><p>Once you are inside the application folder, install the project dependencies using <code>npm install</code>.</p>
</li>
</ul>
<p>After dependencies have been installed, open the application using <code>npm start</code>. Once the application has started, navigate to http://localhost:4200/ and you should see the below page rendered.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXei6amdCIZzGq01anHIe4QYHU-EA8Zy3NyjNoDbU1zAx8na_xOHs6-uSZh2Eorqhu7UrHdFwmV_A5hT0xsOS5xMiHm94Z6wxsmpagiPQqecjQUNkJqiuzgA9q64H05f2N3GGj_VA0YsAJO9xkZa3KNNHcVU?key=SIi3jhbWSizs2BNTxpZ_RQ" alt="Existing Application Home Page" width="1427" height="879" loading="lazy"></p>
<h3 id="heading-understanding-the-existing-application-code">Understanding the Existing Application Code</h3>
<p>It is very important to understand the code and component architecture which renders the application. Open the application in your code editor by navigating to <strong>src -&gt; app</strong>. You should see a structure like this.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeoOadAD5vMfCyV1ZamtdaYe0cSCEyeySD82_q1jDmvLfi1eGDDa2Gs7m0C5L-8I8yQgdiI9vWXaBuB-W3KgDv8PC0jyKajzHtq16fpVUssb-EgCO_0a5W_5KmwGkoPq9UdDLIqjRjVb0NhU1IQBEj8qL7W?key=SIi3jhbWSizs2BNTxpZ_RQ" alt="Code Directory" class="image--center mx-auto" width="449" height="219" loading="lazy"></p>
<p>This application has two main components, the parent component and the child component. The parent component displays the team’s cumulative hours as well a list of employees reporting to the team lead and each employee’s total hours and overtime hours. The parent component has necessary code to render the list as well calculate cumulative team hours from this list. Moreover, the parent component also provides the details of the selected employee to the child component.</p>
<p>The child component receives the selected employee details as its input and allows editing the regular as well overtime hours. Once the team lead is satisfied, a save action is initiated. The save action emits an event from the child component back to the parent component. Parent component acts on this event and does necessary updates to hours of the selected employee. This update triggers recalculation of cumulative hours.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcipNqPsU-ACMQnJ578FL51paiBdzoNtWygqAACkWIdJmhP8SPAxQPg-SInKOoev7dmSNMINdmFFCNDntFly1ZpkKe6HgwbvNGRZZmhIYfFGtwUXgb2TZpMBC67B7sRcoDNmdsIbLSij8YHzp5AfjKuEtg?key=SIi3jhbWSizs2BNTxpZ_RQ" alt="Component Architecture of Existing Application" width="1125" height="732" loading="lazy"></p>
<p>Please go through the code in the editor as well, and pay special attention to code inside files <strong>parent-component.ts</strong> and <strong>child-component.ts</strong>. In the next section you will transform both of these components to use the new feature Angular Signals.</p>
<h2 id="heading-how-to-transform-the-application-to-use-angular-signals">How to Transform the Application to Use Angular Signals</h2>
<p>The transformation of the code can begin with parent component code. Change the <code>managerName</code> variable to use signals. This highlights how a new signal variable can be created. A signal can be initiated with the <code>signal</code> keyword and option type definition along with initial value for the signal. Code below showcases how a new signal called <code>managerName</code> which has a type of <code>string</code> can be initiated with the initial value of <code>John Doe</code>.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// parent-component.ts</span>
managerName = signal&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">'John Doe'</span>);
</code></pre>
<p>You would observe rendering issues once you update <code>managerName</code> in the component file to use the signal. This is because, to read a signal value, it needs to be executed. Update the component HTML code to below to read the value of the signal properly.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- parent-component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-3xl font-bold mb-6"</span>&gt;</span>Hello {{managerName()}}!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
</code></pre>
<p>List of employees inside parent component is a simple array, transform it to signal as well.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// parent-component.ts</span>
 employees = signal&lt;Employee[]&gt;([
    {
      id: <span class="hljs-number">1</span>,
      name: <span class="hljs-string">'Jon Snow'</span>,
      regularHours: <span class="hljs-number">40</span>,
      overtimeHours: <span class="hljs-number">5</span>
    },
    ...restOfEmployees
    }
  ])
</code></pre>
<p>As soon as the employee array is transformed to a signal, the parent component will observe several errors. For the moment, comment out the code inside  <code>getTeamRegularHoursTotal</code>, <code>getTeamOvertimeHoursTotal</code> and <code>employeeChange</code> methods as highlighted in the illustration given below.</p>
<pre><code class="lang-typescript">  <span class="hljs-comment">// parent-component.ts</span>
  getTeamRegularHoursTotal() {
    <span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span>;
    <span class="hljs-comment">// this.employees.forEach(employee =&gt; total += employee.regularHours);</span>
    <span class="hljs-keyword">return</span> total;
  }

  getTeamOvertimeHoursTotal() {
    <span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span>;
    <span class="hljs-comment">// this.employees.forEach(employee =&gt; total += employee.overtimeHours);</span>
    <span class="hljs-keyword">return</span> total;
  }

  employeeChange(updatedEmployee: Employee | <span class="hljs-literal">null</span>) {
    <span class="hljs-comment">// if (updatedEmployee) {</span>
    <span class="hljs-comment">//   const index = this.employees.findIndex(emp =&gt; emp.id === updatedEmployee.id);</span>
    <span class="hljs-comment">//   if (index !== -1) {</span>
    <span class="hljs-comment">//     this.employees[index] = updatedEmployee;</span>
    <span class="hljs-comment">//   }</span>
    <span class="hljs-comment">// }</span>
    <span class="hljs-comment">// this.selectedEmployee = null;</span>
  }
</code></pre>
<p>To render the application again, update the parent component template HTML and execute employee signal as per the code given below.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- parent-component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex items-center py-4 space-x-4 group border-b cursor-pointer hover:bg-gray-50"</span> *<span class="hljs-attr">ngFor</span>=<span class="hljs-string">"let employee of employees()"</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"selectEmployee(employee)"</span>&gt;</span>
</code></pre>
<p>It's time to transform logic to calculate the value of regular hours which are showing as zero currently. This leads to examination of another important type of signal known as "computed".</p>
<p>Computed signals<strong>,</strong> as the name implies, rely on other signals for their value. Their value updates as soon as underlying signals change, without the need of any additional code to handle the change.</p>
<p>Create a computed signal <code>teamRegularHoursTotal</code> as shown in the code below, which depends on the <code>employees</code> signal directly. Thus, whenever an <code>employees</code> signal changes, the value of <code>teamRegularHoursTotal</code> gets updated automatically.</p>
<p>Define the computed signal as shown in the code below, and ensure the computed dependency is imported from Angular's core package. Also, remove or comment out method <code>getTeamRegularHoursTotal</code> completely.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// parent-component.ts</span>
 teamRegularHoursTotal = computed(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span>;
    <span class="hljs-built_in">this</span>.employees().forEach(<span class="hljs-function"><span class="hljs-params">employee</span> =&gt;</span> total += employee.regularHours);
    <span class="hljs-keyword">return</span> total;
  })
</code></pre>
<p>Update the HTML template of the parent component to reflect this change and show total hours value.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- parent-component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-lg font-medium text-gray-700"</span>&gt;</span>Regular Hours: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"font-bold"</span>&gt;</span>
{{teamRegularHoursTotal() }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>Similarly, overtime hours can be transformed to a computed signal as well. Refer to the code below to update both the component code and its HTML template. Also, comment out or remove the <code>getTeamOvertimeHoursTotal</code> method completely.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// parent-component.ts</span>
 teamOvertimeHoursTotal = computed(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span>;
    <span class="hljs-built_in">this</span>.employees().forEach(<span class="hljs-function"><span class="hljs-params">employee</span> =&gt;</span> total += employee.overtimeHours);
    <span class="hljs-keyword">return</span> total;
  })
</code></pre>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- parent-component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-lg font-medium text-gray-700"</span>&gt;</span>Overtime Hours: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"font-bold"</span>&gt;</span>
{{teamOvertimeHoursTotal() }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>It is time to convert the <code>selectedEmployee</code> variable in the parent component to a signal. Transform it using the code below:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// parent-component.ts</span>
selectedEmployee = signal&lt;Employee | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
</code></pre>
<p>As soon as this change is made, the <code>selectEmployee</code> method in the parent component will have errors. These errors are a great opening to an important topic: changing values of a signal. Angular signals can be updated using the <code>set</code> or <code>update</code> API from signals.</p>
<p>As the name implies, the <code>set</code> method assigns a new value to a signal, and the <code>update</code> method updates the value of a signal. Use the <code>set</code> method to change the <code>selectedEmployee</code> signal value. You'll be seeing update method in the action soon.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// parent-component.ts</span>
selectEmployee(employee: Employee): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.selectedEmployee.set(employee);
}
</code></pre>
<p>Along with this change, the parent component’s template needs to be updated. Update the code containing the child component as shown in the code below.</p>
<p>After this change, verify that the application is rendering properly and you are able to select an employee and see the details on the screen. This is important as because we'll be taking this signal transformation journey to the child component.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- parent-component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-full md:w-1/2 bg-white p-6 rounded-lg shadow-lg border border-gray-200 order-1 md:order-2 mb-4 md:mb-0"</span>
      *<span class="hljs-attr">ngIf</span>=<span class="hljs-string">"selectedEmployee() !== null"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">app-child-component</span> [<span class="hljs-attr">employee</span>]=<span class="hljs-string">"selectedEmployee()"</span> (<span class="hljs-attr">employeeChange</span>)=<span class="hljs-string">"employeeChange($event)"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-child-component</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
</code></pre>
<p>The child component receives the value of the selected employee through its input, which is currently defined using the <code>@Input</code> decorator. This can be transformed using a signal conveniently known as <code>input</code>. Change the employee variable to be of type <code>input</code> as shown in the code below. Comment out the code shown in <code>saveChanges</code> and <code>resetForm</code> method as highlighted.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// child-component.ts</span>
employee  = input&lt;Employee | <span class="hljs-literal">null</span>&gt;();
saveChanges() {
    <span class="hljs-comment">// this.employee.regularHours = this.editedRegularHours;</span>
    <span class="hljs-comment">// this.employee.overtimeHours = this.editedOvertimeHours;</span>
    <span class="hljs-comment">// this.employeeChange.emit(this.employee);</span>
}

<span class="hljs-keyword">private</span> resetForm() {
    <span class="hljs-comment">// this.editedRegularHours = this.employee.regularHours;</span>
    <span class="hljs-comment">// this.editedOvertimeHours = this.employee.overtimeHours;</span>
}
</code></pre>
<p>The form inside the child component displays selected employee’s regular hours and overtime hours using two model variables: <code>editedRegularHours</code> and <code>editedOvertimeHours</code>.</p>
<p>These variables are no longer necessary and the inputs inside the form of the child components can be updated to use the signal’s value directly.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- child-component.html --&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> 
     <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> 
     <span class="hljs-attr">id</span>=<span class="hljs-string">"regularHours"</span> 
     [<span class="hljs-attr">ngModel</span>]=<span class="hljs-string">"editedRegularHours"</span>
     (<span class="hljs-attr">ngModelChange</span>)=<span class="hljs-string">"onRegularHoursChange($event)"</span>
      <span class="hljs-attr">class</span>=<span class="hljs-string">"shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"</span> 
 /&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">input</span> 
      <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> 
      <span class="hljs-attr">id</span>=<span class="hljs-string">"overtimeHours"</span> 
      [<span class="hljs-attr">ngModel</span>]=<span class="hljs-string">"editedOvertimeHours"</span>
      (<span class="hljs-attr">ngModelChange</span>)=<span class="hljs-string">"onOvertimeHoursChange($event)"</span>
      <span class="hljs-attr">class</span>=<span class="hljs-string">"shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"</span> 
  /&gt;</span>
</code></pre>
<p>The logic to capture updated values for regular and overtime hours can be transformed as well. Ideally, updating the code below should work but you will get an error as highlighted below.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXf3Zhm_Buy_VvhnYrZcx4YBNFjxoA4jR47L75eLEE2An9xt-aHNWI7iO9uEFp7KlzfoofoUGjaSW6CR-raKXjuVe0_XDhl8SMfMWBTpiQ5eHIfQxoS5qqeFKcu3k3Rb246K8cB7xiIpK4ein7-4xBhkgeA?key=SIi3jhbWSizs2BNTxpZ_RQ" alt="Component Error" class="image--center mx-auto" width="718" height="195" loading="lazy"></p>
<p>The reason behind the error is that the <code>input</code> type signal can not be mutated with <code>set</code> and <code>update</code> methods. Angular provides a different kind of signal known as <code>model</code> to have input to components which can be mutated within the component itself. Change the employee to type <code>model</code> as seen below.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// child-component.ts</span>
employee = model&lt;Employee | <span class="hljs-literal">null</span>&gt;();
</code></pre>
<p>Update the overtime update method as shown in the code below. With this, the child component regains the ability to update regular and overtime hours values of the received employee from the parent component.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// child-component.ts</span>
  onOvertimeHoursChange(event: <span class="hljs-built_in">number</span>) {
    <span class="hljs-built_in">this</span>.employee.set({
      ...this.employee(),
      overtimeHours: event
    })
  }
</code></pre>
<p>Currently, the child component is communicating back the changes to the parent component using the <code>@Output</code> decorator. Similar to the <code>input</code> and the <code>model</code>, Angular has a signal of type <code>output</code> to enable two way communication between child and parent components. Update <code>employeeChange</code> event to <code>output</code> type as seen below.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// child-component.ts </span>
employeeChange = output&lt;Employee | <span class="hljs-literal">null</span>&gt;();
</code></pre>
<p>Update the <code>saveChanges</code> method and emit an updated employee object.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// child-component.ts </span>
 saveChanges() {
    <span class="hljs-built_in">this</span>.employeeChange.emit(<span class="hljs-built_in">this</span>.employee());
 }
</code></pre>
<p>For the final step in the child component update the <code>resetForm</code> and <code>cancelChanges</code> methods to reflect the changes made as shown in the code below.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// child-component.ts   </span>
cancelChanges() {
    <span class="hljs-built_in">this</span>.employeeChange.emit(<span class="hljs-literal">null</span>);
 }
resetForm() {
    <span class="hljs-built_in">this</span>.employee.set(<span class="hljs-literal">null</span>);
}
</code></pre>
<p>Moving back to the parent component now, it is important to make changes to the template to ensure smooth communication between both components.</p>
<p>The <code>employee</code> input in the child component has changed to a <code>model</code> type input. A model has two ways of data binding. Make updates to the code as seen below to use banana in the box (special syntax <code>[( )]</code>, which is a shorthand for two-way data binding) notation for the input.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- parent-component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-full md:w-1/2 bg-white p-6 rounded-lg shadow-lg border border-gray-200 order-1 md:order-2 mb-4 md:mb-0"</span>
    *<span class="hljs-attr">ngIf</span>=<span class="hljs-string">"selectedEmployee() !== null"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">app-child-component</span> [(<span class="hljs-attr">employee</span>)]=<span class="hljs-string">"selectedEmployee"</span> (<span class="hljs-attr">employeeChange</span>)=<span class="hljs-string">"employeeChange($event)"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-child-component</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
</code></pre>
<p>It’s time to update the <code>employeeChange</code> method in the parent component so that updated hour values of the selected employee can be reflected back to the screen. </p>
<p>To achieve this, another key method used for mutating values can be leveraged. This is the <code>update</code> method, which takes in a function as argument instead of full value. The function passes the current value of the signal as the first parameter and returns the updated value of the signal.</p>
<p>Refer to the updated code for the  <code>employeeChange</code> method as seen below to understand this better.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// parent-component.ts  </span>
employeeChange() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.selectedEmployee()) {
      <span class="hljs-built_in">this</span>.employees.update(<span class="hljs-function"><span class="hljs-params">employees</span> =&gt;</span> employees.map(<span class="hljs-function"><span class="hljs-params">employee</span> =&gt;</span> {
        <span class="hljs-keyword">if</span> (employee.id === <span class="hljs-built_in">this</span>.selectedEmployee().id) {
          employee.regularHours = <span class="hljs-built_in">this</span>.selectedEmployee().regularHours;
          employee.overtimeHours = <span class="hljs-built_in">this</span>.selectedEmployee().overtimeHours;
        }
        <span class="hljs-keyword">return</span> employee;
      }))
    }
    <span class="hljs-built_in">this</span>.selectedEmployee.set(<span class="hljs-literal">null</span>);
  }
</code></pre>
<p>With this change the entire transformation of the app to use signals is complete. Ensure all loads properly and all the functionality are working as expected as well.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations on completing this tutorial. During this journey, you have created regular a signal and updated its value using <code>set</code> and <code>update</code> methods.</p>
<p>You also learned how computed signals are defined and utilized. Additionally you have enabled communication between two components using <code>input</code>, <code>model</code> and <code>output</code> signals.</p>
<p>If you encounter any issues during this transformation journey, you can check the code in the <code>feature/signals</code> branch of the same repo you had cloned earlier. It is recommended that you follow along instead of copying the solution from this feature branch.</p>
<p>Once you feel confident about the signal types discussed above, continue your learnings by exploring RxJS Interop from the Angular team to manage your signal integration with RxJS observables.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ AngularJS Interview Questions ]]>
                </title>
                <description>
                    <![CDATA[ Here’s a list of the concepts that are frequently asked about in AngularJS interviews. What is AngularJS? What is the Model View Controller (MVC)? Two way data binding What is dependency injection and how does it work? What is $scope in AngularJS? W... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/angular-js-interview-questions/</link>
                <guid isPermaLink="false">66c344b652e2abc555bfcc09</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ interview questions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 11 Jan 2020 20:49:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9df9740569d1a4ca3aa8.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Here’s a list of the concepts that are frequently asked about in AngularJS interviews.</p>
<ul>
<li>What is AngularJS?</li>
<li>What is the Model View Controller (MVC)?</li>
<li>Two way data binding</li>
<li>What is dependency injection and how does it work?</li>
<li>What is $scope in AngularJS?</li>
<li>What is $rootScope in AngularJS?</li>
<li>How to implement routing in Angular?</li>
<li>Explain directives</li>
<li>How can we create a custom directive in Angular?</li>
<li>Explain difference bewteen service and factory</li>
<li>Explain $q service, deferred and promises</li>
</ul>
<h1 id="heading-example-questions-and-answers"><strong>Example Questions and Answers</strong></h1>
<h3 id="heading-question-list-out-the-directives-in-angularjs">Question: List out the Directives in AngularJS?</h3>
<p>Answer: ngBind, ngModel, ngClass, ngApp, ngInit, ngRepeat</p>
<h3 id="heading-question-what-is-scope-in-angularjs">Question: What is $scope in AngularJS?</h3>
<p>Answer: $scope in AngularJS is an object which refers to an application model. It is an object that binds view (DOM element) with the controller. In controller, model data is accessed via $scope object. As we know, AngularJS supports the MV<em> pattern, $scope object becomes the model of MV</em>.</p>
<h3 id="heading-question-what-is-a-spa-single-page-application-in-angularjs">Question: What is a SPA (Single page application) in AngularJS?</h3>
<p>Answer: Single-Page Applications (SPAs) are web applications that load a single HTML page and dynamically update that page as the user interacts with the app. </p>
<p>SPAs use AJAX and HTML to create fluid and responsive web apps, without constant page reloads. However, this means much of the work happens on the client side, in JavaScript. </p>
<p>A single HTML page here means UI response page from the server. The source can be ASP, ASP.NET, ASP.NET MVC, JSP and so on. </p>
<p>A single-page web application, however, is delivered as one page to the browser and typically does not require the page to be reloaded as the user navigates to various parts of the application. This results in faster navigation, more efficient network transfers, and better overall performance for the end user.</p>
<h3 id="heading-question-what-is-routing-in-angularjs">Question: What is routing in AngularJS?</h3>
<p>Answer: Routing is a core feature in AngularJS. This feature is useful in building SPAs (Single Page Applications) with multiple views. In SPAs, all views are different HTML files and we use Routing to load different parts of the application. It’s helpful to divide the application logically and make it manageable. In other words, Routing helps us to divide our application into logical views and bind them with different controllers.</p>
<h3 id="heading-question-explain-ng-repeat-directive">Question: Explain ng-repeat directive.</h3>
<p>Answer: The ng-repeat directive is the most used AngularJS Directive feature. It iterates over a collection of items and creates DOM elements. It constantly monitors the source of data to re-render a template in response to change.</p>
<h3 id="heading-question-what-is-the-difference-between-ng-if-and-ng-showng-hide">Question: What is the difference between ng-If and ng-show/ng-hide.</h3>
<p>Answer: The ng-If directive only renders DOM element if the condition is true. Whereas ng-show/ng-hide directive renders the DOM element but changes the class of ng-hide/ng-show to maintain visibility of the element on the page.</p>
<h3 id="heading-question-how-do-you-cancel-a-timeout-with-angularjs">Question: How do you cancel a timeout with AngularJs?</h3>
<p>Answer: $timeout is AngularJs’ wrapper for window.setTimeout, you cancel a timeout applying the function:</p>
<pre><code class="lang-text">$timeout.cancel(function (){
  // write your code.
});
</code></pre>
<h3 id="heading-question-what-is-dependency-injection">Question: What is Dependency Injection?</h3>
<p>Answer: Dependency Injection (DI) is a software design pattern that deals with how components get ahold of their dependencies. </p>
<p>The AngularJS injector subsystem is in charge of creating components, resolving their dependencies, and providing them to other components as requested.</p>
<h3 id="heading-question-explain-the-ng-app-directive">Question : Explain the ng-App directive.</h3>
<p>Answer: The ng-app directive starts an AngularJS Application. It defines the root element. It automatically initializes or bootstraps the application when web page containing the AngularJS Application is loaded. It is also used to load various AngularJS modules in AngularJS Applications.</p>
<h3 id="heading-question-explain-the-ng-init-directive">Question: Explain the ng-init directive</h3>
<p>Answer: The ng-init directive initializes an AngularJS Application's data. It is used to put values to the variables to be used in the application. </p>
<p>For example, in the below code we have initialized an array of countries using JSON syntax to define the array of countries.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ng-app</span> = <span class="hljs-string">""</span> <span class="hljs-attr">ng-init</span> = <span class="hljs-string">"countries = [{locale:'en-US',name:'United States'}, {locale:'en-GB',name:'United Kingdom'}, {locale:'en-FR',name:'France'}]"</span>&gt;</span>
   ...
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h3 id="heading-question-how-do-you-share-data-between-controllers">Question: How do you share data between controllers?</h3>
<p>Answer: Create an AngularJS service that will hold the data and inject it inside of the controllers. Using a service is the cleanest, fastest and easiest way to test. </p>
<p>However, there are couple of other ways to implement data sharing between controllers, like:</p>
<ul>
<li>Using events</li>
<li>Using $parent, nextSibling, controllerAs, and so on to directly access the controllers</li>
<li>Using the $rootScope to add the data on (not a good practice)</li>
</ul>
<h3 id="heading-question-what-is-the-difference-between-the-ng-if-and-ng-showhide-directives">Question: What is the difference between the ng-if and ng-show/hide directives?</h3>
<p>Answer: ng-if will only create and display the DOM element when its condition is true. If the condition is false or changes to false it will not create or destroy the created one. </p>
<p>ng-show/hide will always generate the DOM element but it will apply the CSS display property based on the evaluation of the condition.</p>
<h2 id="heading-more-info-on-angularjs">More info on AngularJS:</h2>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/angular-vs-angularjs/">Angular vs AngularJS</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/best-angular-tutorial-angularjs/">The best Angular and AngularJS tutorials</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Angular Views, Routing, and NgModules Explained ]]>
                </title>
                <description>
                    <![CDATA[ Angular vs AngularJS AngularJS (versions 1.x) is a JavaScript-based open source framework. It is cross platform and is used to develop Single Page Web Application (SPWA).  AngularJS implements the MVC pattern to separate the logic, presentation, and ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/angular-vs-angularjs/</link>
                <guid isPermaLink="false">66c344c4ccd54aa295e92ca8</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 06 Jan 2020 21:22:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9e1f740569d1a4ca3b6e.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-angular-vs-angularjs">Angular vs AngularJS</h2>
<p>AngularJS (versions 1.x) is a JavaScript-based open source framework. It is cross platform and is used to develop Single Page Web Application (SPWA). </p>
<p>AngularJS implements the MVC pattern to separate the logic, presentation, and data components. It also uses dependency injection to make use of server-side services in client side applications.</p>
<p>Angular (versions 2.x and up) is a Typescript-based open source framework used to develop front-end web applications. Angular has the following features like generics, static-typing, dynamic loading, and also some ES6 features.</p>
<h2 id="heading-version-history"><strong>Version History</strong></h2>
<p>Google released the initial version of AngularJS on October 20,2010. The first stable release of AngularJS was on December 18, 2017 of version 1.6.8. </p>
<p>The Angular 2.0 release took place on September 22 2014 at the ng-Europe conference. </p>
<p>After some modifications, Angular 4.0 was released in December 2016. Angular 4 is backward compatible with Angular 2.0. The HttpClient library is one of the new features of Angular 4.0. </p>
<p>Angular 5 release was on November 1, 2017. Support for progressive web apps (PWAs)  was one of the improvements to Angular 4.0. </p>
<p>And finally, Angular 6 was released in May 2018. The latest stable version is <a target="_blank" href="https://blog.angular.io/angular-v6-1-now-available-typescript-2-9-scroll-positioning-and-more-9f1c03007bb6">6.1.9</a></p>
<h2 id="heading-how-to-install-it">How to install it</h2>
<p>We can add Angular either by referencing the sources available or downloading the framework.</p>
<h3 id="heading-link-to-source">Link To Source</h3>
<p>AngularJS: We can add AngularJS (Angular 1.x versions) by referencing the Content Delivery Network from Google.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Download/install: We can download the framework with npm, Bower, or composer</p>
<p><strong>Angular</strong>JS <strong>1.x</strong>:</p>
<p>npm</p>
<pre><code class="lang-shell">npm install angular
</code></pre>
<p>Then add a <code>&lt;script&gt;</code> to your <code>index.html</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/node_modules/angular/angular.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>bower</p>
<pre><code class="lang-shell">bower install angular
</code></pre>
<p>Then add a <code>&lt;script&gt;</code> to your <code>index.html</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/bower_components/angular/angular.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p><strong>Angular:</strong></p>
<p>For more information regarding the documentation, refer to the official site of <a target="_blank" href="https://docs.angularjs.org/api">AngularJS</a>.</p>
<p>You can install <strong>Angular 2.x</strong> and other versions by following the steps from the official documentation of <a target="_blank" href="https://angular.io/guide/quickstart">Angular</a>.</p>
<p>Now let's learn a bit more about Angular, shall we?</p>
<h1 id="heading-introduction"><strong>Introduction</strong></h1>
<p>Views offer a necessary layer of abstraction. They keep Angular independent of platform specific utilities. As a cross-platform technology, Angular uses its views to connect with the platform.</p>
<p>For every element in Angular’s template HTML, there is a corresponding view. Angular recommends interacting with the platforms through these views. While direct manipulation is still possible, Angular warns against it. Angular offers its own application programming interface (API) to replace the native manipulations.</p>
<p>Shunning views for platform-specific API has its consequences. When developing Angular in a web browser, elements exist in two places: the DOM and the view. Messing only with the DOM does not impact the view.</p>
<p>Since Angular does not interface with the platform, this creates a discontinuity. Views should mirror the platform one-to-one. Otherwise Angular wastes resources managing elements that mismatch it. This is terrible in the event of deleted elements.</p>
<p>These sorts of discrepancies make views appear unnecessary. Never forget that Angular is a universal development platform above all. Views are a necessary abstraction for this end.</p>
<p>By adhering to views, Angular applications will function across all supported development platforms. Platforms include the Web, Android, and Apple iOS.</p>
<h4 id="heading-note"><strong>Note</strong></h4>
<p>From here-on, this article assumes a web browser environment. Feel free to mentally replace the DOM with something more applicable to your preferred platform.</p>
<h2 id="heading-what-are-views">What are Views?</h2>
<p>Views are almost like their own virtual DOM. Each view contains a reference to a corresponding section of the DOM. Inside a view are nodes that mirror what is in the this section. Angular assigns one view node per DOM element. Each node holds a reference to a matching element.</p>
<p>When Angular checks for changes, it checks the views. Angular avoids the DOM under the hood. The views reference the DOM on its behalf. Other mechanisms are in place to ensure that view changes render to the DOM. Conversely, changes to the DOM do not affect the views.</p>
<p>Again, views are common across all development platforms besides the DOM. Even if developing for one platform, views are still considered best practice. They guarantee Angular has a correct interpretation of the DOM.</p>
<p>Views may not exist on third-party libraries. Direct DOM manipulation is an escape hatch for this kind of scenario. Granted, do not expect the application to function cross-platform.</p>
<h3 id="heading-types-of-views">Types of Views</h3>
<p>There are two main types of views: embedded and host.</p>
<p>There also exists view containers. They hold embedded and host views and are often referred to as simple “views”.</p>
<p>Every <code>@Component</code> class registers a view container (view) with Angular. New components generate a custom selector targeting a certain DOM element. The view attaches to that element wherever it appears. Angular now knows the component exists looking at the view model.</p>
<p>Host views attach to components created dynamically with factories. Factories provide a blueprint for view instantiation. That way the application can instantiate the component’s host view during runtime. A host view attaches to a component’s wrapper per its instantiation. This view stores data describing conventional component capabilities.</p>
<p><code>&lt;ng-template&gt;&lt;/ng-template&gt;</code> is a akin to the HTML5 <code>&lt;template&gt;&lt;/template&gt;</code> element. Angular’s <code>ng-template</code> works with embedded views. These views do not attach to DOM elements unlike host views. They are identical to host views in that they both types exist inside of view containers.</p>
<p>Keep in mind, <code>ng-template</code> is not a DOM element. It gets commented out later leaving nothing but the embedded view nodes behind.</p>
<p>The difference depends on input data; embedded views store no component data. They store a series of elements as nodes comprising its template. The template makes up all the innerHTML of <code>ng-template</code>. Each element within the embedded view is its own separate view node.</p>
<h3 id="heading-host-views-and-containers">Host Views and Containers</h3>
<p>Host views <em>host</em> dynamic components. View containers (views) attach automatically to elements already in the template. Views can attach to any element beyond what is unique to component classes.</p>
<p>Think of the traditional method of component generation. It begins by creating a class, decorating it with <code>@Component</code>, and filling in metadata. This approach occurs for any pre-defined component element of the template.</p>
<p>Try using the Angular command-line interface (CLI) command: <code>ng generate component [name-of-component]</code>. It yields the following.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, OnInit } <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>,
  templateUrl: <span class="hljs-string">'./example.component.html'</span>,
  styleUrls: [<span class="hljs-string">'./example.component.css'</span>]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ExampleComponent <span class="hljs-keyword">implements</span> OnInit {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) { }

  ngOnInit() { }
}
</code></pre>
<p>This creates the component with the selector <code>app-example</code>. This attaches a view container to <code>&lt;app-example&gt;&lt;/app-example&gt;</code> in the template. If this were the root of the application, its view would encapsulate all other views. The root view marks the beginning of the application from Angular’s perspective.</p>
<p>Creating components dynamically and registering them in the Angular view model takes a few extra steps. Structural directives help manage dynamic content (<code>*ngIf, *ngFor, and *ngSwitch…</code>). Directives do not scale to bigger applications however. Too many structural directives complicates the template.</p>
<p>This is where instantiating components from existing class logic comes in handy. These components need to create a host view that can insert into the view model. Host views holds data for components so that Angular recognizes their structural purpose.</p>
<h3 id="heading-host-views-continued">Host Views Continued</h3>
<p>Every component has a class definition. Yet JavaScript does not support classes. Classes are syntactic sugar. They produce functions containing component factories instead.</p>
<p>Factories act as blueprints for host views. They build views to interface with Angular on behalf of their components. Host views attach to DOM elements. Technically any element is OK but the most common target is <code>&lt;ng-component&gt;&lt;/ng-component&gt;</code>.</p>
<p>A view container (view) for holding views must first exist. <code>&lt;ng-container&gt;&lt;/ng-container&gt;</code> is a great place to attach a view container. View containers are the same type of views that also apply to template class elements.</p>
<p>A few helpers and references from <code>@angular/core</code> provide the other needed utilities. The following example puts it all together.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// another.component.ts</span>

<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>({
  template: <span class="hljs-string">`
  &lt;h1&gt;Another Component Content&lt;/h1&gt;
  &lt;h3&gt;Dynamically Generated!&lt;/h3&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AnotherComponent { }
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// example.component.ts</span>

<span class="hljs-keyword">import</span> { AfterViewInit, Component, ViewChild,
ViewContainerRef, ComponentFactoryResolver } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { AnotherComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./another.component'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-example'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;Application Content&lt;/h1&gt;
  &lt;ng-container #container&gt;&lt;/ng-container&gt;
  &lt;h3&gt;End of Application&lt;/h3&gt;
  `</span>,
  entryComponents: [ AnotherComponent ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ExampleComponent <span class="hljs-keyword">implements</span> AfterViewInit {
  <span class="hljs-meta">@ViewChild</span>(<span class="hljs-string">"container"</span>, { read: ViewContainerRef }) ctr: ViewContainerRef;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> resolve: ComponentFactoryResolver</span>) { }

  ngAfterViewInit() {
    <span class="hljs-keyword">const</span> factory = <span class="hljs-built_in">this</span>.resolve.resolveComponentFactory(AnotherComponent);
    <span class="hljs-built_in">this</span>.ctr.createComponent(factory);
  }
}
</code></pre>
<p>Assume AnotherComponent and ExampleComponent are both declared under the same module. AnotherComponent is a simple class component dynamically added into ExampleComponent’s view. ExampleComponent’s <code>entryComponents</code> metadata must contain AnotherComponent for <a target="_blank" href="https://angular.io/guide/bootstrapping">bootstrapping</a>.</p>
<p>While ExampleComponent is a part of the template, AnotherComponent remains detached. It dynamically renders into the template from ExampleComponent.</p>
<p>There are two view containers present: <code>&lt;app-example&gt;&lt;/app-example&gt;</code> and <code>&lt;ng-container&gt;&lt;/ng-container&gt;</code>. The host view for this example will insert into <code>ng-container</code>.</p>
<p>The <code>AfterViewInit</code> lifecycle hook fires after the <code>@ViewChild</code> queries complete. Using the <em>template reference variable</em> <code>#container</code>, the <code>@ViewChild</code> references <code>ng-container</code> as <code>ctr</code>.</p>
<p><code>ViewContainerRef</code> is the type of reference for view containers (views). <code>ViewContainerRef</code> references a view that supports the insertion of other views. <code>ViewContainerRef</code> contains more methods for managing its contained views.</p>
<p>Through dependency injection, the constructor instantiates an instance of Angular’s <code>ComponentFactoryResolver</code> service. This service extracts the the factory function (host view blueprint) of AnotherComponent.</p>
<p>The single argument of <code>createComponent</code> requires a factory. The <code>createComponent</code> function derives from <code>ViewContainerRef</code>. It instantiates AnotherComponent under a host view derived from the component’s factory.</p>
<p>The host view then inserts into the view container. <code>&lt;ng-component&gt;&lt;/ng-component&gt;</code> wraps the component inside of the view container. It has attached to it the aforementioned host view. <code>ng-component</code> is the host view’s connection with the DOM.</p>
<p>There are other ways create a host view dynamically from a component. Other ways often <a target="_blank" href="https://blog.angularindepth.com/working-with-dom-in-angular-unexpected-consequences-and-optimization-techniques-682ac09f6866">focus on optimization</a>.</p>
<p>The <code>ViewContainerRef</code> holds a powerful API. It can manage any number of views either host or embedded within its view. The API includes view operations such as insert, move, and delete. This lets you manipulate the DOM through Angular’s view model. This is best practice so that Angular and the DOM match each other.</p>
<h3 id="heading-embedded-views">Embedded Views</h3>
<p>Note: embedded views attach to other views no added input. Host views attach to a DOM element with input data from its host view describing it as a component.</p>
<p>Structural directives create an <a target="_blank" href="https://angular.io/guide/structural-directives#the-asterisk--prefix"><code>ng-template</code> surrounding a chunk of HTML content</a>. The directive’s host element has a view container attached. This make it so that the content can conditionally render into its intended layout.</p>
<p>The <code>ng-template</code> holds embedded view nodes representing each element within its innerHTML. <code>ng-template</code> is by no means a DOM element. It comments itself out. The tags define the extend of its embedded view.</p>
<h3 id="heading-embedded-views-continued">Embedded Views Continued</h3>
<p>Instantiating an embedded view requires no external resources beyond its own reference. The <code>@ViewChild</code> query can fetch that.</p>
<p>With the template reference, calling <code>createEmbeddedView</code> from it does the trick. The innerHTML of the reference becomes its own embedded view instance.</p>
<p>In the next example, <code>&lt;ng-container&gt;&lt;/ng-container&gt;</code> is a view container. <code>ng-container</code> gets commented out during compilation just like <code>ng-template</code>. Thus it provides an outlet for inserting the embedded view while keeping the DOM lean.</p>
<p>The embedded view template inserts at the layout location of <code>ng-container</code>. This newly inserted view has no additional view encapsulation besides the view container. Remember how that differs from host views (host views attach to their <code>ng-component</code> element wrapper).</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, AfterViewInit, ViewChild,
ViewContainerRef, TemplateRef } <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;Application Content&lt;/h1&gt;
  &lt;ng-container #container&gt;&lt;/ng-container&gt; &lt;!-- embed view here --&gt;
  &lt;h3&gt;End of Application&lt;/h3&gt;

  &lt;ng-template #template&gt;
    &lt;h1&gt;Template Content&lt;/h1&gt;
    &lt;h3&gt;Dynamically Generated!&lt;/h3&gt;
  &lt;/ng-template&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ExampleComponent <span class="hljs-keyword">implements</span> AfterViewInit {
  <span class="hljs-meta">@ViewChild</span>(<span class="hljs-string">"template"</span>, { read: TemplateRef }) tpl: TemplateRef&lt;<span class="hljs-built_in">any</span>&gt;;
  <span class="hljs-meta">@ViewChild</span>(<span class="hljs-string">"container"</span>, { read: ViewContainerRef }) ctr: ViewContainerRef;

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

  ngAfterViewInit() {
    <span class="hljs-keyword">const</span> view =  <span class="hljs-built_in">this</span>.tpl.createEmbeddedView(<span class="hljs-literal">null</span>);
    <span class="hljs-built_in">this</span>.ctr.insert(view);
  }
}
</code></pre>
<p><code>@ViewChild</code> queries for the <em>template reference variable</em> <code>#template</code>. This provides a template reference of type <code>TemplateRef</code>. <code>TemplateRef</code> holds the <code>createEmbeddedView</code> function. It instantiates the template as an embedded view.</p>
<p>The single argument of <code>createEmbeddedView</code> is for context. If you wanted to pass in additional metadata, you could do it here as an object. The fields should match up with the <code>ng-template</code> attributes (<code>let-[context-field-key-name]=“value”</code>). Passing <code>null</code> indicates no extra metadata is necessary.</p>
<p>A second <code>@ViewChild</code> query provides a reference to <code>ng-container</code> as a <code>ViewContainerRef</code>. Embedded views only attach to other views, never the DOM. The <code>ViewContainerRef</code> references the view that takes in the embedded view.</p>
<p>An embedded view may also insert into the component view of <code>&lt;app-example&gt;&lt;/app-example&gt;</code>. This approach positions the view at the very end of ExampleComponent’s view. In this example however, we want the content to show up in the very middle where <code>ng-container</code> sits.</p>
<p>The <code>ViewContainerRef</code> <code>insert</code> function <em>inserts</em> the embedded view into the <code>ng-container</code>. The view content shows ups in the intended location right in the middle of ExampleComponent’s view.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Manipulating the DOM with platform specific methods is not recommended. Creating and managing a tight set of views keeps Angular and the DOM on the same page. Updating the views informs Angular of the current state of the DOM. Updates to the views also carry over into what the DOM displays.</p>
<p>Angular provides a flexible API for view interaction. Developing platform independent applications is possible thanks to this level of abstraction. Of course, the temptation to fallback on platform dependent strategies persists. Unless you have a very good reason not to, try to stick with the views API Angular provides. This will yield predictable results across all platforms.</p>
<h1 id="heading-routing-in-angular"><strong>Routing in Angular</strong></h1>
<p>Routing is essential. Many modern web applications host too much information for one page. Users should not have to scroll through an entire application’s worth of content either. An application needs to split itself into distinguishable sections.</p>
<p>Users prioritize necessary information. Routing helps them find the application section with such information. Any other information useful to other users may exist on an entirely separate route. With routing, both users can find what they need quickly. Irrelevant details stay obscured behind irrelevant routes.</p>
<p>Routing excels at sorting and restricting access to application data. Sensitive data should never display to unauthorized users. Between every route the application may intervene. It can examine a user’s session for authentication purposes. This examination determines what the route renders if it should render at all. Routing gives developers the perfect chance to verify a user before proceeding.</p>
<p>Creating a list of routes promotes organization as well. In terms of development, it keeps the developer thinking in distinguishable sections. Users benefit from this too, but more-so developers when navigating the application code. A list of programmatic routers paints an accurate model of the application’s front end.</p>
<p>As for Angular, routing takes up its own entire library within the framework. All modern front-end frameworks support routing, and Angular is no different. Routing happens from the client-side using either hash or location routing. Both styles allow the client to manage its own routes. No additional assistance from the server is necessary past the initial request.</p>
<p>The web browser rarely refreshes using client-side routing. Web browser utilities such as bookmarks, history, and the address bar still work despite no refreshing. This makes for a slick routing experience that does not mess up the browser. No more jumpy page reloads while routing to a different page.</p>
<p>Angular adds on a layer of abstraction over the core technologies used for routing. This article intends to explain this abstraction. There exists two routing strategies in Angular: path location and hash. This article focuses on the path location strategy since its the default option.</p>
<p>Plus, path location may deprecate hash routing following the full release of <a target="_blank" href="https://universal.angular.io/">Angular Universal</a>. Regardless, the two strategies are very similar in implementation. Learning one learns the other. Time to get started!</p>
<h2 id="heading-routermodule-setup">RouterModule Setup</h2>
<p>Routing utilities export with <code>RouterModule</code> available from <code>@angular/router</code>. It is not part of the core library since not all applications require routing. The most conventional way to introduce routing is as its own <a target="_blank" href="https://angular.io/guide/feature-modules">feature module</a>.</p>
<p>As route complexity grows, having it as its own module will promote the root module’s simplicity. Keeping it stupid simple without compromising functionality constitutes good design for 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> { RouterModule, Routes } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">import</span> { AComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/a/a.component'</span>;
<span class="hljs-keyword">import</span> { BComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/b/b.component'</span>;

<span class="hljs-comment">// an array of soon-to-be routes!</span>
<span class="hljs-keyword">const</span> routes: Routes = [];

<span class="hljs-meta">@NgModule</span>({
  imports: [ RouterModule.forRoot(routes) ],
  <span class="hljs-built_in">exports</span>: [ RouterModule ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppRoutingModule { }
</code></pre>
<p><code>.forRoot(...)</code> is a class function available from the RouterModule class. The function accepts an array of <code>Route</code> objects as <code>Routes</code>. <code>.forRoot(...)</code> configures routes for eager-loading while its alternative <code>.forChild(...)</code> configures for lazy-loading.</p>
<p>Eager-loading meaning the routes load their content into the application from the get-go. Lazy-loading happens on-demand. The focus of this article is eager-loading. It is the default approach for loading in an application. The RouterModule class definition looks something like the next block of code.</p>
<pre><code class="lang-typescript"><span class="hljs-meta">@NgModule</span>({
  <span class="hljs-comment">// … lots of metadata ...</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> RouterModule {
  forRoot(routes: Routes) {
    <span class="hljs-comment">// … configuration for eagerly loaded routes …</span>
  }

  forChild(routes: Routes) {
    <span class="hljs-comment">// … configuration for lazily loaded routes …</span>
  }
}
</code></pre>
<p>Do not worry about the configuration details the example omits with comments. Having a general understanding will do for now.</p>
<p>Notice how AppRoutingModule imports the RouterModule while also exporting it. This makes sense given AppRoutingModule is a feature module. It imports into the root module as a feature module. It exposes RouterModule directives, interfaces, and services to the root component tree.</p>
<p>This explains why AppRoutingModule must export RouterModule. It does so for the sake of the root module’s underlying component tree. It needs access to those routing utilities!</p>
<pre><code class="lang-typescript"><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> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-keyword">import</span> { AppComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.component'</span>;
<span class="hljs-keyword">import</span> { AComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/a/a.component'</span>;
<span class="hljs-keyword">import</span> { BComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/b/b.component'</span>;
<span class="hljs-keyword">import</span> { AppRoutingModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./modules/app-routing/app-routing.module'</span>;

<span class="hljs-meta">@NgModule</span>({
  declarations: [
    AppComponent,
    AComponent,
    BComponent
  ],
  imports: [
    AppRoutingModule, <span class="hljs-comment">// routing feature module</span>
    BrowserModule
  ],
  providers: [],
  bootstrap: [ AppComponent ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule { }
</code></pre>
<p>The AppRoutingModule token imports from the very top. Its token inserts into the root module’s imports array. The root component tree may now utilize the RouterModule library. That includes its directives, interfaces, and services as already mentioned. Big thanks goes to AppRoutingModule for exporting RouterModule!</p>
<p>The RouterModule utilities will come in handy for the root’s components. The basic HTML for AppComponent makes use of one directive: <code>router-outlet</code>.</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- app.component.html --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- routerLink(s) here --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">router-outlet</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-outlet</span>&gt;</span>
<span class="hljs-comment">&lt;!-- routed content appends here (AFTER THE ELEMENT, NOT IN IT!) --&gt;</span>
</code></pre>
<p><code>routerLink</code> is an attribute directive of RouterModule. It will attach to each element of <code>&lt;ul&gt;&lt;/ul&gt;</code> once the routes are setup. <code>router-outlet</code> is a component directive with interesting behavior. It acts more as a marker for displaying routed content. Routed content results from navigation to a specific route. Usually that means a single component as configured in AppRoutingModule</p>
<p>The routed content renders right after <code>&lt;router-outlet&gt;&lt;/router-outlet&gt;</code>. Nothing renders inside of it. This does not make too much of a considerable difference. That said, do not expect <code>router-outlet</code> to behave like a container for routed content. It is merely a marker for appending routed content to the Document Object Model (DOM).</p>
<h2 id="heading-basic-routing">Basic Routing</h2>
<p>The previous section establishes the basic setup for routing. Before actual routing can happen, a few more things must be addressed</p>
<p>The first question to address is what routes will this application consume? Well, there are two components: AComponent and BComponent. Each one should have its own route. They can render from AppComponent’s <code>router-outlet</code> depending on the current route location.</p>
<p>The route location (or path) defines what appends to a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin">website’s origin</a> (e.g. <a target="_blank" href="http://localhost:4200/">http://localhost:4200</a>) through a series of slashes (<code>/</code>).</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// … same imports from before …</span>

<span class="hljs-keyword">const</span> routes: Routes = [
  {
    path: <span class="hljs-string">'A'</span>,
    component: AComponent
  },
  {
    path: <span class="hljs-string">'B'</span>,
    component: BComponent
  }
];

<span class="hljs-meta">@NgModule</span>({
  imports: [ RouterModule.forRoot(routes) ],
  <span class="hljs-built_in">exports</span>: [ RouterModule ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppRoutingModule { }
</code></pre>
<p><code>http://localhost:4200/A</code> renders AComponent from AppComponent’s <code>router-outlet</code>. <code>http://localhost:4200/B</code> renders BComponent. You need a way to route to these locations without using the address bar though. An application should not rely upon a web browser’s address bar for navigation.</p>
<p><em>The global CSS (Cascading Style-sheets) supplements the HTML below it. An application’s router link ought to have a pleasant appearance. This CSS applies to all other examples too.</em></p>
<pre><code class="lang-css"><span class="hljs-comment">/* global styles.css */</span>

<span class="hljs-selector-tag">ul</span> <span class="hljs-selector-tag">li</span> {
  <span class="hljs-attribute">cursor</span>: pointer;
  <span class="hljs-attribute">display</span>: inline-block;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">background-color</span>: whitesmoke;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid black;
}

<span class="hljs-selector-tag">ul</span> <span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:hover</span> {
  <span class="hljs-attribute">background-color</span>: lightgrey;
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- app.component.html --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">routerLink</span>=<span class="hljs-string">"/A"</span>&gt;</span>Go to A!<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">routerLink</span>=<span class="hljs-string">"/B"</span>&gt;</span>Go to B!<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">router-outlet</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-outlet</span>&gt;</span>
</code></pre>
<p>This is basic routing! Clicking either of the routerLink elments routes the web address. It reassigns it without refreshing the web browser. Angular’s <code>Router</code> maps the routed address to the <code>Routes</code> configured in AppRoutingModule. It matches the address to the <code>path</code> property of a single <code>Route</code> object within the array. First match always wins, so match-all routes should lie at the very end of the <code>Routes</code> array.</p>
<p>Match-all routes prevent the application from crashing if it cannot match the current route. This can happen from the address bar where the user may type in any route. For this, Angular provides a wildcard path value <code>**</code> that accepts all routes. This route usually renders a PageNotFoundComponent component displaying “Error 404: Page not found”.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// … PageNotFoundComponent imported along with everything else …</span>

<span class="hljs-keyword">const</span> routes: Routes = [
  {
    path: <span class="hljs-string">'A'</span>,
    component: AComponent
  },
  {
    path: <span class="hljs-string">'B'</span>,
    component: BComponent
  },
  {
    path: <span class="hljs-string">''</span>,
    redirectTo: <span class="hljs-string">'A'</span>,
    pathMatch: <span class="hljs-string">'full'</span>
  },
  {
    path: <span class="hljs-string">'**'</span>,
    component: PageNotFoundComponent
  }
];
</code></pre>
<p>The <code>Route</code> object containing <code>redirectTo</code> keeps the PageNotFoundComponent from rendering as a result of <code>http://localhost:4200</code>. This is the applications home route. To fix this, <code>redirectTo</code> reroutes the home route to <code>http://localhost:4200/A</code>. <code>http://localhost:4200/A</code> indirectly becomes the application’s new home route.</p>
<p>The <code>pathMatch: 'full'</code> tells the <code>Route</code> object to match against the home route (<code>http://localhost:4200</code>). It matches the empty path.</p>
<p>These two new <code>Route</code> objects go at the end of the array since first match wins. The last array element (<code>path: '**'</code>) always matches, so it goes last.</p>
<p>There is one last thing worth addressing before moving on. How does the user know where he or she is in the application relative to the current route? Sure there may be content specific to the route, but how is user supposed to make that connection? There should be some form of highlighting applied to the routerLinks. That way, the user will know which route is active for the given web page.</p>
<p>This is an easy fix. When you click a <code>routerLink</code> element, Angular’s <code>Router</code> assigns <em>focus</em> to it. This focus can trigger certain styles which provide useful feedback to the user. The <code>routerLinkActive</code> directive can track this focus for the developer.</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- app.component.html --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">routerLink</span>=<span class="hljs-string">"/A"</span> <span class="hljs-attr">routerLinkActive</span>=<span class="hljs-string">"active"</span>&gt;</span>Go to A!<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">routerLink</span>=<span class="hljs-string">"/B"</span> <span class="hljs-attr">routerLinkActive</span>=<span class="hljs-string">"active"</span>&gt;</span>Go to B!<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">router-outlet</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-outlet</span>&gt;</span>
</code></pre>
<p>The right assignment of <code>routerLinkActive</code> represents a string of classes. This example portrays only one class (<code>.active</code>), but any number of space-delimited classes may apply. When the <code>Router</code> assigns <em>focus</em> to a routerLink, the space-delimited classes apply to the host element. When the focus shifts away, the classes get removed automatically.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* global styles.css */</span>

<span class="hljs-selector-class">.active</span> {
  <span class="hljs-attribute">background-color</span>: lightgrey <span class="hljs-meta">!important</span>;
}
</code></pre>
<p>Users can now easily recognize how the current route and the page content coincide. <code>lightgrey</code> highlighting applies to the routerLink matching the current route. <code>!important</code> ensures the highlighting overrides inline stylings.</p>
<h2 id="heading-parameterized-routes">Parameterized Routes</h2>
<p>Routes do not have to be completely hard-coded. They can contain dynamic variables referenceable from the component corresponding the <code>Route</code> object. These variables are declared as parameters when writing the route’s path.</p>
<p>Route parameters are either optional or mandatory for matching a particular <code>Route</code>. It depends on how a route writes its parameters. Two strategies exist: matrix and traditional parameterization.</p>
<p>Traditional parameterization begins from the <code>Routes</code> array configured in AppRoutingModule.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> routes: Routes = [
  <span class="hljs-comment">// … other routes …</span>
  {
    path: <span class="hljs-string">'B'</span>,
    component: BComponent
  },
  {
    path: <span class="hljs-string">'B/:parameter'</span>,
    component: BComponent
  },
  <span class="hljs-comment">// … other routes …</span>
];
</code></pre>
<p>Focus on the two BComponent routes. Parameterization will eventually occur in both routes.</p>
<p>Traditional parameterization occurs in the second BComponent <code>Route</code>. <code>B/:parameter</code> contains the <code>parameter</code> parameter as indicated with the <code>:</code>. Whatever follows the colon marks the parameter’s name. The <code>parameter</code> parameter is necessary for the second BComponent <code>Route</code> to match.</p>
<p><code>parameter</code> reads in the value of whatever gets passed into the route. Routing to <code>http://localhost:4200/B/randomValue</code> will assign <code>parameter</code> the value of <code>randomValue</code>. This value can include anything besides another <code>/</code>. For example, <code>http://localhost:4200/B/randomValue/blahBlah</code> will not trigger the second BComponent <code>Route</code>. The PageNotFoundComponent renders instead.</p>
<p>BComponent can reference route parameters from its component class. Both approaches to parameterization (matrix and traditional) yield the same results in BComponent. Before seeing BComponent, examine the matrix form of parameterization below.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// app.component.ts</span>

<span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</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">@Component</span>({
  selector: <span class="hljs-string">'app-root'</span>,
  templateUrl: <span class="hljs-string">'./app.component.html'</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppComponent {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> router: Router</span>) { }

  routeMatrixParam(value: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">if</span> (value)
      <span class="hljs-built_in">this</span>.router.navigate([<span class="hljs-string">'B'</span>, { parameter: value }]); <span class="hljs-comment">// matrix parameter</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-built_in">this</span>.router.navigate([<span class="hljs-string">'B'</span>]);
  }

  routeAddressParam(value: <span class="hljs-built_in">string</span>) {
    <span class="hljs-built_in">this</span>.router.navigate([<span class="hljs-string">'B'</span>, value]);
  }
}
</code></pre>
<p>Angular’s dependency injection system provides an instantiation of the <code>Router</code>. This lets the component programmatically route. The <code>.navigate(...)</code> function accepts an array of values that resolves to a <em>routable</em> path. Something like <code>.navigate(['path', 'to', 'something'])</code> resolves to <code>http://localhost:4200/path/to/something</code>. <code>.navigate(...)</code> adds path-delimiting <code>/</code> marks when normalizing the array into a <em>routable</em> path.</p>
<p>The second form of parameterization occurs in <code>routeMatrixParam(...)</code>. See this line of code: <code>this.router.navigate(['B', { parameter: value }])</code>. This form of <code>parameter</code> is a matrix parameter. Its value is optional for the first BComponent <code>Route</code> to match (<code>/B</code>). The <code>Route</code> matches regardless of the parameter’s presence in the path.</p>
<p>The <code>routeAddressParam(...)</code> resolves a route that matches the <code>http://localhost:4200/B/randomValue</code> parameterization approach. This traditional strategy needs a parameter to match the second BComponent route (<code>B/:parameter</code>).</p>
<p>The matrix strategy concerns <code>routeMatrixParam(...)</code>. With or without a matrix parameter in its path, the first BComponent route still matches. The <code>parameter</code> parameter passes to BComponent just like with the traditional approach.</p>
<p>To make full sense of the above code, here is the corresponding template HTML.</p>
<pre><code class="lang-html">// app.component.html

<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">routerLink</span>=<span class="hljs-string">"/A"</span>&gt;</span>Go to A!<span class="hljs-tag">&lt;/<span class="hljs-name">li</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">input</span> #<span class="hljs-attr">matrixInput</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"routeMatrixParam(matrixInput.value)"</span>&gt;</span>Matrix!<span class="hljs-tag">&lt;/<span class="hljs-name">button</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">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> #<span class="hljs-attr">paramInput</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"routeAddressParam(paramInput.value)"</span>&gt;</span>Param!<span class="hljs-tag">&lt;/<span class="hljs-name">button</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">router-outlet</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-outlet</span>&gt;</span>
</code></pre>
<p>In the template, values are accepted as text input. The input injects it into the route path as a parameter. Two separate sets of boxes exist for each parameterization strategy (traditional and matrix). With all the pieces coming together, it is time to examine the BComponent component class.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// b.component.ts</span>

<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> { ActivatedRoute, ParamMap } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-b'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;Route param: {{ currParam }}&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> BComponent <span class="hljs-keyword">implements</span> OnInit {
  currParam: <span class="hljs-built_in">string</span> = <span class="hljs-string">""</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> route: ActivatedRoute</span>) { }

  ngOnInit() {
    <span class="hljs-built_in">this</span>.route.params.subscribe(<span class="hljs-function">(<span class="hljs-params">param: ParamMap</span>) =&gt;</span> {
      <span class="hljs-built_in">this</span>.currParam = param[<span class="hljs-string">'parameter'</span>];
    });
  }
}
</code></pre>
<p>BComponent results from either of two BComponent routes in AppRoutingModule. <code>ActivatedRoute</code> instantiates into a set of useful information pertaining to the current route. That is, the route that caused BComponent to render. <code>ActivatedRoute</code> instantiates via dependency injection targeting the class constructor.</p>
<p>The <code>.params</code> field of <code>ActivatedRoute.params</code> returns an <code>Observable</code> which emits the route parameters. Notice how the two different parameterization approaches result in the <code>parameter</code> parameter. The returned <code>Observable</code> emits it as a key-value pair inside of a <code>ParamMap</code> object.</p>
<p>Between the two parameterization approaches, the <code>parameter</code> parameter resolved identically. The value emits from <code>ActivatedRoute.params</code> despite the approach to parameterization.</p>
<p>The address bar distinguishes the final results of each approach. Matrix parameterization (optional for <code>Route</code> match) yields the address: <code>http://localhost:4200/B;parameter=randomValue</code>. Traditional parameterization (required for <code>Route</code> match) yields: <code>http://localhost:4200/B/randomValue</code>.</p>
<p>Either way, the same BComponent results. The actual difference: a different BComponent <code>Route</code> matches. This entirely depends upon the parameterization strategy. The matrix approach ensures parameters are optional for <code>Route</code> matching. The traditional approach requires them.</p>
<h2 id="heading-nested-routes">Nested Routes</h2>
<p><code>Routes</code> may form a hierarchy. In the DOM, this involves one parent <code>router-outlet</code> rendering at least one child <code>router-outlet</code>. In the address bar, it looks like this: <code>http://localhost/parentRoutes/childRoutes</code>. In the <code>Routes</code> configuration, the <code>children: []</code> property denotes a <code>Route</code> object as having nested (child) routes.</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, Routes } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">import</span> { NestComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/nest/nest.component'</span>;
<span class="hljs-keyword">import</span> { AComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/nest/a/a.component'</span>;
<span class="hljs-keyword">import</span> { BComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/nest/b/b.component'</span>;

<span class="hljs-keyword">const</span> routes: Routes = [
  {
    path: <span class="hljs-string">'nest'</span>,
    component: NestComponent,
    children: [
      { path: <span class="hljs-string">'A'</span>, component: AComponent },
      { path: <span class="hljs-string">'B'</span>, component: BComponent }
    ]
  }
];

<span class="hljs-meta">@NgModule</span>({
  imports: [ RouterModule.forRoot(routes) ],
  <span class="hljs-built_in">exports</span>: [ RouterModule ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppRoutingModule { }
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// nest.component.ts</span>

<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-nest'</span>,
  template: <span class="hljs-string">`
  &lt;ul&gt;
    &lt;li routerLink="./A"&gt;Go to A!&lt;/li&gt;
    &lt;li routerLink="./B"&gt;Go to B!&lt;/li&gt;
  &lt;/ul&gt;
  &lt;router-outlet&gt;&lt;/router-outlet&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> NestComponent { }
</code></pre>
<p>NestComponent renders a <code>router-outlet</code> after rendering itself from another root-level <code>router-outlet</code> in AppComponent. The <code>router-outlet</code> of NestComponent’s template may render either AComponent (<code>/nest/A</code>) or BComponent (<code>/nest/B</code>).</p>
<p>The AppRoutingModule reflects this nesting in NestComponent’s <code>Route</code> object. The <code>children: []</code> field holds an array of <code>Route</code> objects. These <code>Route</code> object may also nest routes in their <code>children: []</code> fields. This can continue for however many layers of nested routes. The above example shows two layers of nesting.</p>
<p>Each <code>routerLink</code> contains a <code>./</code> as compared to <code>/</code>. The <code>.</code> ensures that the routerLink appends to the route path. The routerLink completely replaces the path otherwise. After routing to <code>/nest</code>, <code>.</code> expands into <code>/nest</code>.</p>
<p>This is useful for routing to either <code>/nest/A</code> or <code>/nest/B</code> from the <code>.nest</code> route. <code>A</code> and <code>B</code> constitute nested routes of <code>/nest</code>. Routing to <code>/A</code> or <code>/B</code> returns PageNotFound. <code>/nest</code> must prepend the two routes.</p>
<p>Take a look at the AppComponent containing the root-level <code>router-outlet</code> in its template. AppComponent is the first layer of nesting while NestComponent is the second.</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-root'</span>,
  template: <span class="hljs-string">`
  &lt;ul&gt;
    &lt;li routerLink="/nest"&gt;Go to nested routes!&lt;/li&gt;
    &lt;li routerLink="/"&gt;Back out of the nested routes!&lt;/li&gt;
  &lt;/ul&gt;
  &lt;router-outlet&gt;&lt;/router-outlet&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppComponent { }
</code></pre>
<p>Inside the nest <code>Route</code> object, the <code>children: []</code> contains two more nested routes. They result in AComponent and BComponent when routing from <code>/nest</code> as previously discussed. These components are very simple for the sake of demonstration. <code>&lt;li routerLink="/"&gt;...&lt;/li&gt;</code> lets you navigate out of the nest routes to reset the example by navigating to the home route.</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-a'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;a works!&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AComponent { }
</code></pre>
<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-b'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;b works!&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> BComponent { }
</code></pre>
<p>The <code>children: []</code> array accepts <code>Route</code> object as elements. <code>children: []</code> can apply to any of these elements as well. The children of these elements can continue nesting. This pattern may continue for however many layers of nesting. Insert a <code>router-outlet</code> into the template for every layer of nested routing.</p>
<p>Routing techniques apply regardless of a <code>Route</code> object’s level of nesting. The parameterization techniques differ in only one aspect. Child routes can only access their parent’s parameters via <code>ActivatedRoute.parent.params</code>. <code>ActivatedRoute.params</code> targets the same level of nested routes. This excludes parent-level routes and their parameters.</p>
<p><code>Route</code> guards are especially suited for nested routing. One <code>Route</code> object can restrict access to all its nested (child) routes.</p>
<h2 id="heading-guarded-routes">Guarded Routes</h2>
<p>Web applications often consist of public and private data. Both types of data tend to have their own pages with <em>guarded</em> routes. These routes allow/restrict access depending on the user’s privileges. Unauthorized users may interact with a guarded route. The route should block the user if he or she attempts to access its routed content.</p>
<p>Angular provides a bundle of authentication guards that can attach to any route. These methods trigger automatically depending on how the user interacts with the guarded route.</p>
<ul>
<li><code>canActivate(...)</code> - fires when the user attempts to access a route</li>
<li><code>canActivateChild(...)</code> - fires when the user attempts to access a route’s nested (child) routes</li>
<li><code>canDeactivate(...)</code> - fires when the user attempts to leave a route</li>
</ul>
<p>Angular’s guard methods are available from <code>@angular/router</code>. To help them authenticate, they may optionally receive a few parameters. Such parameters do not inject via dependency injection. Under the hood, each value gets passed in as an argument to the invoked guard method.</p>
<ul>
<li><code>ActivatedRouteSnapshot</code> - available to all three</li>
<li><code>RouterStateSnapshot</code> - available to all three</li>
<li><code>Component</code> - available to <code>canDeactivate(...)</code></li>
</ul>
<p><code>ActivatedRouteSnapshot</code> provides access to the route parameters of the guarded route. <code>RouterStateSnapshot</code> exposes the URL (uniform resource locator) web address matching the route. <code>Component</code> references the component rendered by the route.</p>
<p>To guard a route, a class implementing the guard methods needs to first exist as a service. The service can inject into AppRoutingModule to guard its <code>Routes</code>. The token value for the service may inject into any one <code>Route</code> object.</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, Routes } <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> { UserService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/user.service'</span>;

<span class="hljs-keyword">import</span> { PrivateNestComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/private-nest/private-nest.component'</span>;
<span class="hljs-keyword">import</span> { PrivateAComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/private-nest/private-a/private-a.component'</span>;
<span class="hljs-keyword">import</span> { PrivateBComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../components/private-nest/private-b/private-b.component'</span>;

<span class="hljs-keyword">const</span> routes: Routes = [
  {
    path: <span class="hljs-string">'private-nest'</span>,
    component: PrivateNestComponent,
    canActivate: [ AuthService ], <span class="hljs-comment">// !!!</span>
    canActivateChild: [ AuthService ], <span class="hljs-comment">// !!!</span>
    canDeactivate: [ AuthService ], <span class="hljs-comment">// !!!</span>
    children: [
      { path: <span class="hljs-string">'private-A'</span>, component: PrivateAComponent },
      { path: <span class="hljs-string">'private-B'</span>, component: PrivateBComponent }
    ]
  }
];

<span class="hljs-meta">@NgModule</span>({
  imports: [ RouterModule.forRoot(routes) ],
  <span class="hljs-built_in">exports</span>: [ RouterModule ],
  providers: [
    AuthService,
    UserService
  ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppRoutingModule { }
</code></pre>
<p><code>canActivate</code>, <code>canActivateChild</code>, and <code>canDeactivate</code> implement from AuthService. The service implementation will be shown shortly alongside the UserService implementation.</p>
<p>UserService provides the information needed to authenticate a user. The AuthService guard method implementations perform the authentication. AppRoutingModule must include the two services into its providers array. This is so the module’s injector knows how to instantiate them.</p>
<p>Nested routes exist off of the <code>/private-nest</code> path. The <code>Route</code> object for <code>/private-nest</code> contains a few more new fields. Their names should look familiar as they mirror their corresponding guard methods.</p>
<p>Each field fires its namesake’s method implementation inside of the service when triggered. Any number of services can populate this array too. The method implementation of each service gets tested. They must return a boolean value or an <code>Observable</code> that emits a boolean value.</p>
<p>See the AuthService and UserService implementations below.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// user.service.ts</span>

<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> { Router } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">class</span> TheUser {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> isLoggedIn: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">false</span></span>) { }

  toggleLogin() {
    <span class="hljs-built_in">this</span>.isLoggedIn = <span class="hljs-literal">true</span>;
  }

  toggleLogout() {
    <span class="hljs-built_in">this</span>.isLoggedIn = <span class="hljs-literal">false</span>;
  }
}

<span class="hljs-keyword">const</span> globalUser = <span class="hljs-keyword">new</span> TheUser();

<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> UserService {
  theUser: TheUser = globalUser;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> router: Router</span>) { }

  get isLoggedIn() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.theUser.isLoggedIn;
  }

  login() {
    <span class="hljs-built_in">this</span>.theUser.toggleLogin();
  }

  logout() {
    <span class="hljs-built_in">this</span>.theUser.toggleLogout();
    <span class="hljs-built_in">this</span>.router.navigate([<span class="hljs-string">'/'</span>]);
  }
}
</code></pre>
<p>The same instance of <code>TheUser</code> gets passed with each instantiation of UserService. <code>TheUser</code> provides access to <code>isLoggedIn</code> determining the user’s login status. Two other public methods let the UserService toggle the value of <code>isLoggedIn</code>. This is so the user can log in and out.</p>
<p>You can think of <code>TheUser</code> as a global instance. <code>UserService</code> is a instantiable interface that configures this global. Changes to <code>TheUser</code> from one <code>UserService</code> instantiation apply to every other <code>UserService</code> instance. <code>UserService</code> implements into AuthService to provide access to <code>isLoggedIn</code> of <code>TheUser</code> for authentication.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { CanActivate, CanActivateChild, CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">import</span> { UserService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./user.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> AuthService <span class="hljs-keyword">implements</span> CanActivate, CanActivateChild, CanDeactivate&lt;Component&gt; {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> user: UserService</span>) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.user.isLoggedIn)
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.canActivate(route, state);
  }

  canDeactivate(component: Component, route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.user.isLoggedIn || <span class="hljs-built_in">window</span>.confirm(<span class="hljs-string">'Leave the nest?'</span>))
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
}
</code></pre>
<p>AuthService implements every guard method imported from <code>@angular/router</code>. Each guard method maps to a corresponding field in the PrivateNestComponent’s <code>Route</code> object. An instance of UserService instantiates from the AuthService constructor. AuthService determines if a user may proceed using <code>isLoggedIn</code> exposed by UserService.</p>
<p>Returning <code>false</code> from a guard instructs the route to block the user from routing. A return value of <code>true</code> lets the user proceed to his route destination. If more than one service authenticates, they all must return true to permit access. <code>canActivateChild</code> guards the child routes of PrivateNestComponent. This guard method accounts for users bypassing PrivateNestComponent through the address bar.</p>
<p>Guard method parameters pass in automatically upon invocation. While the example does not make use of them, they do supply useful information from the route. The developer can use this information to help authenticate the user.</p>
<p>AppComponent also instantiates UserService for direct use in its template. The UserService instantiation of AppComponent and AuthService reference the same user class (<code>TheUser</code>).</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-keyword">import</span> { UserService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./services/user.service'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-root'</span>,
  template: <span class="hljs-string">`
  &lt;ul&gt;
    &lt;li routerLink="/private-nest"&gt;Enter the secret nest!&lt;/li&gt;
    &lt;li routerLink="/"&gt;Leave the secret nest!&lt;/li&gt;
    &lt;li *ngIf="user.isLoggedIn"&gt;&lt;button (click)="user.logout()"&gt;LOGOUT&lt;/button&gt;&lt;/li&gt;
    &lt;li *ngIf="!user.isLoggedIn"&gt;&lt;button (click)="user.login()"&gt;LOGIN&lt;/button&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;router-outlet&gt;&lt;/router-outlet&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppComponent {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> user: UserService</span>) { }
}
</code></pre>
<p>UserService handles all the logic for AppComponent. AppComponent mostly concerns its template. A UserService does instantiate as <code>user</code> from the class constructor. <code>user</code> data determines the template’s functionality.</p>
<h2 id="heading-conclusions">Conclusions</h2>
<p>Routing strikes a fine balance between organizing and restricting sections of the application. A smaller application such as a blog or tribute page may not require any routing. Even then, including a little bit of hash routing could not hurt. A user may only want to reference part of the page after all.</p>
<p>Angular applies its own routing library built on top of the HTML5 <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/History_API">history API</a>. This API omits hash routing to instead use the <code>pushState(...)</code> and <code>replaceState(...)</code> methods. They change the web address URL without refreshing the page. The default path location routing strategy in Angular works this way. Setting <code>RouterModule.forRoot(routes, { useHash: true })</code> enables hash routing if preferred.</p>
<p>This article focused on the default path location strategy. Regardless of the strategy, many routing utilities are available to route an application. The <code>RouterModule</code> exposes these utilities through its exports. Basic, parameterized, nested, and guarded routes are all possible utilizing RouterModule.</p>
<h1 id="heading-ngmodules"><strong>NgModules</strong></h1>
<p>Angular applications begin from the root NgModule. Angular manages an application’s dependencies through its module system comprised of NgModules. Alongside plain JavaScript modules, NgModules ensure code modularity and encapsulation.</p>
<p>Modules also provide a top-most level of organizing code. Each NgModule sections off its own chunk of code as the root. This module provides top-to-bottom encapsulation for its code. The entire block of code can then export to any other module. In this sense, NgModules act like gatekeepers to their own code blocks.</p>
<p>Angular’s documented utilities come from NgModules authored by Angular. No utility is available unless the NgModule that declares it gets included into the root. These utilities must also export from their host module so that importers can use them. This form of encapsulation empowers the developer to produce his or her own NgModules within the same file-system.</p>
<p>Plus, it makes sense to know why the Angular CLI (command-line interface) imports <code>BrowserModule</code> from <code>@angular/core</code>. This happens whenever a new app generates using the CLI command: <code>ng new [name-of-app]</code>.</p>
<p>Understanding the point of the implementation may suffice in most cases. However, understanding how the implementation wires itself to the root is even better. It all happens automatically by importing <code>BrowserModule</code> into the root.</p>
<h3 id="heading-ngmodule-decorator">NgModule Decorator</h3>
<p>Angular defines its modules by decorating a generic class. The <code>@NgModule</code> decorator indicates the class’ modular purpose to Angular. An NgModule class consolidates root dependencies accessible/instantiable from the module’s scope. ‘Scope’ meaning anything originating from the module’s metadata.</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-meta">@NgModule</span>({
  <span class="hljs-comment">// … metadata …</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule { }
</code></pre>
<h3 id="heading-ngmodule-metadata">NgModule Metadata</h3>
<p>The CLI generated root NgModule includes the following metadata fields. These fields provide configuration to the code block upon which the NgModule presides.</p>
<ul>
<li><code>declarations: []</code></li>
<li><code>imports: []</code></li>
<li><code>providers: []</code></li>
<li><code>bootstrap: []</code></li>
</ul>
<h3 id="heading-declarations">Declarations</h3>
<p>The declarations array includes all components, directives, or pipes hosted by an NgModule. They are private to the module unless explicitly exported inside its metadata. Given this use-case, components, directives, and pipes are nicknamed ‘declarables’. An NgModule must declare a declarable uniquely. The declarable cannot declare twice in separate NgModules. An error gets thrown otherwise. See the below example.</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> { TwoComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/two.component.ts'</span>;

<span class="hljs-meta">@NgModule</span>({
  declarations: [ TwoComponent ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> TwoModule { }

<span class="hljs-meta">@NgModule</span>({
  imports: [ TwoModule ],
  declarations: [ TwoComponent ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> OneModule { }
</code></pre>
<p>Angular throws an error for the sake of NgModule encapsulation. Declarables are private to the NgModule that declares them by default. If multiple NgModules need a certain declarable, they should import the declaring NgModule. This NgModule must then export the desired declarable so that the other NgModules can use it.</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> { TwoComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/two.component.ts'</span>;

<span class="hljs-meta">@NgModule</span>({
  declarations: [ TwoComponent ],
  <span class="hljs-built_in">exports</span>: [ TwoComponent ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> TwoModule { }

<span class="hljs-meta">@NgModule</span>({
  imports: [ TwoModule ] <span class="hljs-comment">// this module can now use TwoComponent</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> OneModule { }
</code></pre>
<p>The above example will not throw an error. TwoComponent has been uniquely declared between the two NgModules. OneModule also has access to TwoComponent since it imports TwoModule. TwoModule in turn exports the TwoComponent for external use.</p>
<h3 id="heading-imports">Imports</h3>
<p>The imports array only accepts NgModules. This array does not accept declarables, services, or anything else besides other NgModules. Importing a module provides access to what declarable the module publicizes.</p>
<p>This explains why importing <code>BrowserModule</code> provides access to its various utilities. Each declarable utility declared in <code>BrowserModule</code> exports from its metadata. Upon importing <code>BrowserModule</code>, those exported declarables become available to the importing NgModule. Services do not export at all since they lack the same encapsulation.</p>
<h3 id="heading-providers">Providers</h3>
<p>The lack of service encapsulation might seem odd given the encapsulation of declarables. Remember that services go into the providers array separate from declarations or exports.</p>
<p>When Angular compiles, it flattens the root NgModule and its imports into one module. Services group together in a single providers array hosted by the merged NgModule. Declarables maintain their encapsulation through a set of compile-time flags.</p>
<p>If NgModule providers contain matching token values, the importing root module takes precedence. Past that, the last NgModule imported takes precedence. See the next example. Pay special attention to the NgModule importing the other two. Recognize how that affects the precedence of the provided service.</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-meta">@NgModule</span>({
  providers: [ AwesomeService ], <span class="hljs-comment">// 1st precedence + importing module</span>
  imports: [
    BModule,
    CModule
  ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AModule { }

<span class="hljs-meta">@NgModule</span>({
  providers: [ AwesomeService ]  <span class="hljs-comment">// 3rd precedence + first import</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> BModule { }

<span class="hljs-meta">@NgModule</span>({
  providers: [ AwesomeService ]  <span class="hljs-comment">// 2nd precedence + last import</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CModule { }
</code></pre>
<p>Instantiating AwesomeService from within AModule’s scope results in an AwesomeService instance as provided in AModule’s metadata. If AModule’s providers omitted this service, the AwesomeService of CModule would take precedence. So and so forth for BModule if CModule’s providers omitted AwesomeService.</p>
<h2 id="heading-bootstrap">Bootstrap</h2>
<p>The bootstrap array accepts components. For each component of the Array, Angular inserts the component as its own root of the <code>index.html</code> file. The CLI-generated root NgModule of an application will always have this field.</p>
<pre><code class="lang-typescript"><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> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</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>AppComponent’s element will inject into the base-level HTML of the app (<code>index.html</code>). The rest of the component tree unfolds from there. The scope of the overarching NgModule covers this entire tree plus any others injected from the bootstrap array. The array usually contains only one element. This one component represents the module as a single element and its underlying tree.</p>
<h2 id="heading-ngmodules-vs-javascript-modules">NgModules vs JavaScript Modules</h2>
<p>You have seen Angular and JavaScript modules working together in the previous examples. The top-most <code>import..from</code> statements constitute the JavaScript module system. The file locations of each statement’s target must export a class, variable, or function matching the request. <code>import { TARGET } from './path/to/exported/target'</code>.</p>
<p>In JavaScript, modules are file-separated. Files import using the <code>import..from</code> keywords as just mentioned. NgModules, on the other hand, are class-separated and decorated with <code>@NgModule</code>. And so, many Angular modules can exist in a single file. This cannot happen with JavaScript since a file defines a module.</p>
<p>Granted, conventions say that each <code>@NgModule</code> decorated class should have its own file. Even so, know that files do not constitute their own modules in Angular. Classes decorated with <code>@NgModule</code> create that distinction.</p>
<p>JavaScript modules provide token references to <code>@NgModule</code> metadata. This happens at the top of a file hosting a NgModule class. NgModule uses these tokens inside of its metadata fields (declarables, imports, providers, etc). The only reason <code>@NgModule</code> can decorate a class in the first place is because JavaScript imports it from the top of the file.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// JavaScript module system provides tokens</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> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { AppComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.component'</span>;
<span class="hljs-keyword">import</span> { AppService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.service'</span>;
<span class="hljs-comment">// Javascript module system is strict about where it imports. It can only import at the top of files.</span>

<span class="hljs-comment">// Angular NgModule uses those tokens in its metadata settings</span>
<span class="hljs-meta">@NgModule</span>({ <span class="hljs-comment">// import { NgModule } from '@angular/core';</span>
  declarations: [
    AppComponent <span class="hljs-comment">// import { AppComponent } from './app.component';</span>
  ],
  imports: [
    BrowserModule <span class="hljs-comment">// import { BrowserModule } from '@angular/platform-browser';</span>
  ],
  providers: [
    AppService <span class="hljs-comment">// import { AppService } from './app.service';</span>
  ],
  bootstrap: [
    AppComponent <span class="hljs-comment">// import { AppComponent } from './app.component';</span>
  ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule { }
<span class="hljs-comment">// JavaScript module system exports the class. Other modules can now import AppModule.</span>
</code></pre>
<p>The above example does not introduce anything new. The focus here is on the comments explaining how the two modular systems work together. JavaScript provides token references while NgModule uses those token to encapsulate and configure its underlying block of code.</p>
<h3 id="heading-feature-modules">Feature Modules</h3>
<p>Applications grow overtime. Scaling them properly requires application organization. A solid system for this will make further development much easier.</p>
<p>In Angular, schematics ensure purpose-driven sections of code remain distinguishable. Beyond the sub-NgModule schematics, there are the NgModules themselves. They are a type of schematic too. They stand above the rest in the list of schematics excluding the application itself.</p>
<p>The root module should not stand alone once an application starts to scale. Feature modules include any NgModule used alongside the root NgModule. You can think of the root module as having the <code>bootstrap: []</code> metadata field. Feature application ensure the root module does not oversaturate its metadata.</p>
<p>Feature modules isolate a section of code on behalf of any importing module. They can handle whole application sections independently. This means it could be used in any application whose root module imports the feature module. This tactic saves developers time and effort over the course of multiple applications! It keeps the application’s root NgModule lean as well.</p>
<p>In the root NgModule of an app, adding a feature module’s token into the root’s <code>imports</code> array does the trick. Whatever the feature module exports or provides becomes available to the root.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// ./awesome.module.ts</span>

<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> { AwesomePipe } <span class="hljs-keyword">from</span> <span class="hljs-string">'./awesome/pipes/awesome.pipe'</span>;
<span class="hljs-keyword">import</span> { AwesomeComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./awesome/components/awesome.component'</span>;
<span class="hljs-keyword">import</span> { AwesomeDirective } <span class="hljs-keyword">from</span> <span class="hljs-string">'./awesome/directives/awesome.directive'</span>;

<span class="hljs-meta">@NgModule</span>({
  <span class="hljs-built_in">exports</span>: [
    AwesomePipe,
    AwesomeComponent,
    AwesomeDirective
  ]
  declarations: [
    AwesomePipe,
    AwesomeComponent,
    AwesomeDirective
  ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AwesomeModule { }
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// ./app.module.ts</span>

<span class="hljs-keyword">import</span> { AwesomeModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./awesome.module'</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> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</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: [
    AwesomeModule,
    BrowserModule
  ],
  providers: [],
  bootstrap: [
    AppComponent
  ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule { }
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// ./app.component.ts</span>

<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-root'</span>,
  template: <span class="hljs-string">`
  &lt;!-- AwesomeDirective --&gt;
  &lt;h1 appAwesome&gt;This element mutates as per the directive logic of appAwesome.&lt;/h1&gt;

  &lt;!-- AwesomePipe --&gt;
  &lt;p&gt;Generic output: {{ componentData | awesome }}&lt;/p&gt;

  &lt;section&gt;
    &lt;!-- AwesomeComponent --&gt;
    &lt;app-awesome&gt;&lt;/app-awesome&gt;
  &lt;/section&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppComponent {
  componentData: <span class="hljs-built_in">string</span> = <span class="hljs-string">"Lots of transformable data!"</span>;
}
</code></pre>
<p><code>&lt;app-awesome&gt;&lt;/app-awesome&gt;</code> (component), <code>awesome</code> (pipe), and <code>appAwesome</code> (directive) are exclusive to AwesomeModule. Had it not exported these declarables or AppModule neglected to add AwesomeModule to its imports, then AwesomeModule’s declarables would not have been usable by AppComponent’s template. AwesomeModule is a feature module to the root NgModule AppModule.</p>
<p>Angular provides some its own modules that supplement the root upon their importation. This is due to these feature modules exporting what they create.</p>
<h3 id="heading-static-module-methods">Static module methods</h3>
<p>Sometimes modules provide the option to be configured with a custom config object. This is achieved by leveraging static methods inside the module class.</p>
<p>An example of this approach is the <code>RoutingModule</code> which provides a <code>.forRoot(...)</code> method directly on the module.</p>
<p>To define your own static module method you add it to the module class using the <code>static</code> keyword. The return type has to be <code>ModuleWithProviders</code>.</p>
<pre><code class="lang-ts"><span class="hljs-comment">// configureable.module.ts</span>

<span class="hljs-keyword">import</span> { AwesomeModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./awesome.module'</span>;
<span class="hljs-keyword">import</span> { ConfigureableService, CUSTOM_CONFIG_TOKEN, Config } <span class="hljs-keyword">from</span> <span class="hljs-string">'./configurable.service'</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> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;


<span class="hljs-meta">@NgModule</span>({
  imports: [
    AwesomeModule,
    BrowserModule
  ],
  providers: [
    ConfigureableService
  ]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ConfigureableModule { 
  <span class="hljs-keyword">static</span> forRoot(config: Config): ModuleWithProviders {
    <span class="hljs-keyword">return</span> {
        ngModule: ConfigureableModule,
        providers: [
            ConfigureableService,
            {
                provide: CUSTOM_CONFIG_TOKEN,
                useValue: config
            }
        ]
    };
  }
}
</code></pre>
<pre><code class="lang-ts"><span class="hljs-comment">// configureable.service.ts</span>

<span class="hljs-keyword">import</span> { Inject, Injectable, InjectionToken } <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> CUSTOM_CONFIG_TOKEN: InjectionToken&lt;<span class="hljs-built_in">string</span>&gt; = <span class="hljs-keyword">new</span> InjectionToken(<span class="hljs-string">'customConfig'</span>);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Config {
  url: <span class="hljs-built_in">string</span>
}

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ConfigureableService {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">
    <span class="hljs-meta">@Inject</span>(CUSTOM_CONFIG_TOKEN) <span class="hljs-keyword">private</span> config: Config
  </span>)
}
</code></pre>
<p>Notice that the object the <code>forRoot(...)</code> method returns is almost identical to the <code>NgModule</code> config.</p>
<p>The <code>forRoot(...)</code> method accepts a custom config object that the user can provide when importing the module.</p>
<pre><code class="lang-ts">imports: [
  ...
  ConfigureableModule.forRoot({ url: <span class="hljs-string">'http://localhost'</span> }),
  ...
]
</code></pre>
<p>The config is then provided using a custom <code>InjectionToken</code> called <code>CUSTOM_CONFIG_TOKEN</code> and injected in the <code>ConfigureableService</code>. The <code>ConfigureableModule</code> should be imported only once using the <code>forRoot(...)</code> method. This provides the <code>CUSTOM_CONFIG_TOKEN</code> with the custom config. All other modules should import the <code>ConfigureableModule</code> without the <code>forRoot(...)</code> method.</p>
<h2 id="heading-ngmodule-examples-from-angular">NgModule Examples from Angular</h2>
<p>Angular provides a variety of modules importable from <code>@angular</code>. Two of the most commonly imported modules are <code>CommonModule</code> and <code>HttpClientModule</code>.</p>
<p><code>CommonModule</code> is actually a subset of <code>BrowserModule</code>. Both provide access to the <code>*ngIf</code> and <code>*ngFor</code> structural directives. <code>BrowserModule</code> includes a platform-specific installation for the web browser. <code>CommonModule</code> omits this installation. The <code>BrowserModule</code> should import into the root NgModule of a web application. <code>CommonModule</code> provides <code>*ngIf</code> and <code>*ngFor</code> to feature modules not requiring a platform installation.</p>
<p><code>HttpClientModule</code> provides the <code>HttpClient</code> service. Remember that services go in the providers array of the <code>@NgModule</code> metadata. They are not declarable. During compilation, every NgModule gets consolidated into one single module. Services are not encapsulated unlike declarables. They are all instantiable through the root injector located alongside the merged NgModule.</p>
<p>Back to the point. Like any other service, <code>HttpClient</code> instantiates into a class through its constructor via dependency injection (DI). Using DI, the root injector injects an instance of <code>HttpClient</code> into the constructor. This service lets developers make HTTP requests with the service’s implementation.</p>
<p>The <code>HttpClient</code> implementation includes into the <code>HttpClientModule</code> providers array. As long as the root NgModule imports <code>HttpClientModule</code>, <code>HttpClient</code> will instantiate from inside the root’s scope as expected.</p>
<h2 id="heading-conclusion-1">Conclusion</h2>
<p>Chances are you may have already taken advantage of Angular’s NgModules. Angular makes it very easy to throw a module into the root NgModule’s imports array. Utilities are often exported from the imported module’s metadata. Hence why its utilities suddenly become available upon importation within the root NgModule.</p>
<p>NgModules work closely with plain JavaScript modules. One provides token while one uses them for configuration. Their teamwork results in a robust, modular system unique to the Angular framework. It provides a new layer of organization above all other schematics excluding the application.</p>
<p>Hopefully this article furthers your understanding of NgModules. Angular can leverage this system even further for some of the more exotic use-cases. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Best Angular and AngularJS Tutorials ]]>
                </title>
                <description>
                    <![CDATA[ AngularJS (versions 1.x) is a JavaScript-based open source Framework. It is cross platform and used to develop Single Page Web Applications (SPWAs). AngularJS implements the MVC pattern to separate the logic, presentation, and data components. It als... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/best-angular-tutorial-angularjs/</link>
                <guid isPermaLink="false">66c3457942d4db64acf4cbe6</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 23 Nov 2019 00:49:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9f1a740569d1a4ca40d5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>AngularJS (versions 1.x) is a JavaScript-based open source Framework. It is cross platform and used to develop Single Page Web Applications (SPWAs). AngularJS implements the MVC pattern to separate the logic, presentation, and data components. It also uses dependency injection to make use of server-side services in client side applications.</p>
<p>Angular (versions 2.x and up) is a Typescript-based open source framework to develop front-end Web applications. Angular has features like generics, static-typing and also some ES6 features.</p>
<p>We recommend learning Angular and using it for new projects. AngularJS is mainly used for legacy projects.</p>
<p>The best way to learn Angular is with <a target="_blank" href="https://www.youtube.com/watch?v=2OHbjep_WjQ">freeCodeCamp's 6-hour Angular Tutorial</a> on YouTube.</p>
<p><img src="https://img.youtube.com/vi/2OHbjep_WjQ/maxresdefault.jpg" alt="Image" width="1280" height="720" loading="lazy"></p>
<h1 id="heading-other-tutorials-on-angular">Other tutorials on Angular</h1>
<h2 id="heading-angular-1x"><strong>Angular 1.x</strong></h2>
<h3 id="heading-general-pages"><strong>General Pages</strong></h3>
<ul>
<li><a target="_blank" href="https://angularjs.org/">Angular JS</a> - The Angular JS Homepage</li>
<li><a target="_blank" href="https://github.com/johnpapa/angular-styleguide/tree/master/a1">AngularJS Style Guide</a> - Detailed best practices for Angular Development</li>
</ul>
<h3 id="heading-videos"><strong>Videos</strong></h3>
<ul>
<li><a target="_blank" href="https://www.youtube.com/watch?v=5uhZCc0j9RY">Routing in Angular JS</a> - Client Side Routing in 15 minutes</li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=WuiHuZq_cg4">Angular ToDo App</a> - An Angular ToDo app in 12 minutes</li>
</ul>
<h3 id="heading-courses"><strong>Courses</strong></h3>
<ul>
<li><a target="_blank" href="https://egghead.io/browse/frameworks/angularjs">Egghead.io AngularJS Courses ($)</a></li>
</ul>
<h2 id="heading-angular-2x"><strong>Angular 2.x+</strong></h2>
<h3 id="heading-general-pages-1"><strong>General Pages</strong></h3>
<ul>
<li><a target="_blank" href="https://angular.io/">Angular</a> - The Angular Homepage</li>
<li><a target="_blank" href="https://angular.io/guide/styleguide">Angular Style Guide</a> - Detailed best practices for Angular Development</li>
</ul>
<h3 id="heading-specific-topic-pages"><strong>Specific-topic Pages</strong></h3>
<ul>
<li><a target="_blank" href="http://www.sitepoint.com/practical-guide-angularjs-directives/">Directives</a> - Excellent guide going into detail on Angular Directives (Part 1)</li>
</ul>
<h3 id="heading-courses-1"><strong>Courses</strong></h3>
<ul>
<li><a target="_blank" href="https://egghead.io/browse/frameworks/angular">Egghead.io Angular Courses ($)</a></li>
<li><a target="_blank" href="https://frontendmasters.com/courses/building-apps-angular">FrontendMasters - Building Awesomer Apps with Angular</a></li>
<li><a target="_blank" href="https://ultimateangular.com/">Ultimate Angular - Todd Motto</a></li>
<li><a target="_blank" href="https://www.udemy.com/the-complete-guide-to-angular-2/">Angular 6 (formerly Angular 2) - The Complete Guide($) Maximilian Schwarzmüller</a></li>
</ul>
<h2 id="heading-blogs"><strong>Blogs</strong></h2>
<ul>
<li><a target="_blank" href="https://alligator.io/angular/">Alligator.io</a></li>
<li><a target="_blank" href="https://blog.angularindepth.com/tagged/angular">Angular In Depth</a></li>
</ul>
<h2 id="heading-version-history"><strong>Version History</strong></h2>
<p>Google released the initial version of AngularJS on October 20, 2010. The first stable release of AngularJS was on December 18, 2017 of version 1.6.8. Angular 2.0 release took place on September 22, 2014 at the ng-Europe conference. One of the features of Angular 2.0 is dynamic loading.</p>
<p>After some modifications, Angular 4.0 was released in December, 2016. Angular 4 is backward compatible with Angular 2.0. HttpClient library is one of the features of Angular 4.0. Angular 5 was released on November 1, 2017. Support for progressive web apps was one of the improvements in Angular 4.0. Angular 6 was released in May 2018. The latest stable version is <a target="_blank" href="https://blog.angular.io/angular-v6-1-now-available-typescript-2-9-scroll-positioning-and-more-9f1c03007bb6">6.1.9</a></p>
<p><strong>Install</strong>:</p>
<p>We can add Angular either by referencing the sources available or downloading the framework.</p>
<p><strong>Link To Source</strong>:</p>
<p>AngularJS: We can add AngularJS (Angular 1.x versions) by referencing the Content Delivery Network from Google.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Download/install: We can download the framework with npm, Bower or composer.</p>
<p><strong>Angular 1.x</strong>:</p>
<p>npm</p>
<pre><code class="lang-shell">npm install angular
</code></pre>
<p>Then add a <code>&lt;script&gt;</code> to your <code>index.html</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/node_modules/angular/angular.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>bower</p>
<pre><code class="lang-shell">bower install angular
</code></pre>
<p>Then add a <code>&lt;script&gt;</code> to your <code>index.html</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/bower_components/angular/angular.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>For more information regarding the documentation, refer to the official site of <a target="_blank" href="https://docs.angularjs.org/api">AngularJS</a>.</p>
<p>You can install <strong>Angular 2.x</strong> and other versions by following the steps from the official documentation of <a target="_blank" href="https://angular.io/guide/quickstart">Angular</a>.</p>
<h1 id="heading-components"><strong>Components</strong></h1>
<h4 id="heading-motivation"><strong>Motivation</strong></h4>
<p>Angular contains many <em>schematics</em> for building applications. Components are one such schematic. They encompass a single unit of logic concerned with a single part of the application. Components often partner with other schematics to operate more effectively.</p>
<p>Among all schematics, components tend to consume more than they provide. While other schematics like directives, pipes, and services offer utility, components utilize. They are responsible for the application interface so it makes sense why they consume utility.</p>
<p>Components simplify the application. Funneling logic into a single section of the visible interface is their primary goal. To build applications step-by-step, you must build component-by-component. Components act as Angular’s building blocks, after all.</p>
<h4 id="heading-components-introduction"><strong>Components Introduction</strong></h4>
<p>As mentioned, components consume utility (services/resources). They stand between business logic and presentation to produce a cohesive unit. Angular attaches various mechanisms to each component. These attachments identify a class as a component and define its standard capabilities.</p>
<p>Angular must recognize components when it comes across them. To do this, <code>@Component</code> must decorate every class intended to be a component. Decorators indicate to Angular what the class is.</p>
<p>In the case of a component, it must know how to interact with its injector, connect with a template, pull from a list of styles, encapsulate its styles, and so on. Angular takes care of most of the low-level requirements. Developers still need to configure a component’s behavior, import its dependencies, and extend its logic.</p>
<p>For all such things, we have the component’s class. The class keeps everything relatively uniform. It encapsulates the component’s business logic.</p>
<h4 id="heading-component-class-and-metadata"><strong>Component Class and Metadata</strong></h4>
<p>Go ahead and install the <a target="_blank" href="https://cli.angular.io/">Angular command-line interface (CLI)</a>. You can learn more about it from <a target="_blank" href="https://guide.freecodecamp.org/angular/command-line-interface">this article</a>. The CLI command <code>ng generate component [name-of-component]</code> yields the following.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, OnInit } <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>,
  templateUrl: <span class="hljs-string">'./example.component.html'</span>,
  styleUrls: [<span class="hljs-string">'./example.component.css'</span>]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ExampleComponent <span class="hljs-keyword">implements</span> OnInit {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) { }

  ngOnInit() { }
}
</code></pre>
<p>This is the basic skeleton from which all great components originate. The <code>@Component</code> decorator is the most important part. Without it, the above example becomes a generic class. Angular relies on decorators to discern a class’s schematic type.</p>
<p><code>@Component</code> receives metadata as a single object. Decorators are just JavaScript functions under the hood. They take in arguments as with the metadata object. The metadata object configures a component’s basic dependencies. Each fields plays a role.</p>
<ul>
<li><code>selector:</code> tells Angular to associate the component with a certain element in the application’s template HTML.</li>
<li><code>templateUrl:</code> accepts the file location of the component’s template HTML (this is where data gets displayed to).</li>
<li><code>styleUrls:</code> accepts an array of style-sheet file locations (strings). These style-sheets target the component’s assigned template.</li>
</ul>
<p>Think of metadata as a big blob of configuration. The decorator takes it so that it can generate the data specific to the component. The decorator <em>decorates</em> the underlying class with data necessary for its class’s behavior. A <em>component</em> class that is.</p>
<p>The class’s signature exports by default so that the component can be imported. <code>ngOnInit</code> also gets implemented. <code>implements</code> tells the class to define certain methods per the interface’s definition. <code>ngOnInit</code> is a lifecycle hook.</p>
<h4 id="heading-component-lifecycle-and-change-detection"><strong>Component Lifecycle and Change Detection</strong></h4>
<p>Components use all sorts of tools, services, and features. One key feature available to components is lifecycle hooks. An explanation for each hook exists <a target="_blank" href="https://guide.freecodecamp.org/angular/lifecycle-hooks">in this article</a>.</p>
<p>There are eight in total and they all serve as timing functions. They execute conditionally as the component transitions from state-to-state via <a target="_blank" href="https://blog.angularindepth.com/everything-you-need-to-know-about-change-detection-in-angular-8006c51d206f">change detection</a>. This process happens constantly across the component tree. It searches for changes in data which merit a re-rendering of the template.</p>
<p>Time to move on. Please refer to the aforementioned articles for more information on the component lifecycle. It deserves much more explanation.</p>
<h4 id="heading-component-data"><strong>Component Data</strong></h4>
<p>Data drives everything. Components are no exception. Components encapsulate all their data. To receive data externally, a component must explicitly declare it. This form of privacy keeps information from clashing across the component tree.</p>
<p>Data determines what gets displayed from the component class to its template. Any updates to the class’s data will (or at least should) update the template display.</p>
<p>Components will often initialize a set of members (or variables) that store data. They are used throughout the component class logic for convenience. This information fuels the logic resulting in the template and its behavior. See the following example.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// ./components/example/example.component.ts</span>

<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> { Post, DATA } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../data/posts.data'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-example'</span>,
  templateUrl: <span class="hljs-string">'./example.component.html'</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ExampleComponent <span class="hljs-keyword">implements</span> OnInit {
  username: <span class="hljs-built_in">string</span>;
  totalPosts: <span class="hljs-built_in">number</span>;
  allPosts: Post[];

  deletePost(index: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.allPosts.splice(index, <span class="hljs-number">1</span>);
    <span class="hljs-built_in">this</span>.totalPosts = <span class="hljs-built_in">this</span>.allPosts.length;
  }

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.username = DATA.author;
    <span class="hljs-built_in">this</span>.totalPosts = DATA.thePosts.length;
    <span class="hljs-built_in">this</span>.allPosts = DATA.thePosts;
  }
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- ./components/example/example.component.html --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{{ username }}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Change Name: <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">input</span> [(<span class="hljs-attr">ngModel</span>)]=<span class="hljs-string">"username"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Posts: {{ totalPosts }}<span class="hljs-tag">&lt;/<span class="hljs-name">h3</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">hr</span>/&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> *<span class="hljs-attr">ngFor</span>=<span class="hljs-string">"let post of allPosts; let i=index"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"deletePost(i)"</span>&gt;</span>DELETE<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h6</span>&gt;</span>{{ post.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">h6</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{{ post.body }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">hr</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">ul</span>&gt;</span>
</code></pre>
<p>Note the ways the component interacts with its data. It first fetches it from <code>../../data/posts.data</code> before it begins to forward it to the template for display.</p>
<p>The data shows up throughout the template. Inside the double curly braces, a variable’s value is mapped from the component class into the braces. The <code>*ngFor</code> loops across the <code>allPosts</code> class array. Clicking on the button removes a specific element from <code>allPosts</code> by its index. You can even change the topmost <code>username</code> by typing into the input box.</p>
<p>The above interactions alter the component class’s data which in turn updates the component’s template HTML. Components provide the backbone logic that facilitates the flow of data. The template HTML makes that data readable to the user.</p>
<h4 id="heading-component-template"><strong>Component Template</strong></h4>
<p>The previous example’s template HTML featured an interesting syntax. The syntax was not actual HTML. It was Angular’s template HTML. Some often refer to it as HTML <em>Plus,</em> recognizable only by Angular’s compiler. The compiler supports a syntax resulting in the dynamic manipulation of HTML. This article will often refer to it as ‘template HTML’ or ‘template’.</p>
<p>The syntax lets components inject data directly into the template HTML. The injection is dynamic. This means that data can iterate and display itself as HTML without needing external assistance. The Angular compiler compiles it into real HTML by the time it reaches the web browser.</p>
<p>To learn more about some of the ways data binds to the template, read about <a target="_blank" href="https://guide.freecodecamp.org/angular/data-binding">data binding in Angular</a>. A few examples of data binding occurred in the previous example (<code>{{ ... }}</code>). For this article, it is enough to recognize data interactions were happening between the component class and its template.</p>
<h4 id="heading-querying-the-template"><strong>Querying the Template</strong></h4>
<p>Data managing the state of the template imperatively works OK. Yet, pure data does not always fulfill an application’s intended design. Interacting more directly with the Document Object Model (DOM) may be required.</p>
<p>To do that, the component must have reference to the template elements. When the data changes, the component can manipulate the DOM explicitly. This is a more declarative approach.</p>
<p>Components can grab references using a web browser’s DOM application programming interface (API). Bad idea though. Angular prefers cross-platform compatibility. For a component to function outside of the web browser, it needs to use Angular’s API instead of the DOM’s.</p>
<p>Components can query their templates using the <code>@ViewChild</code> and <code>ContentChild</code> decorators. They grab references to template elements on behalf of the component class.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, ViewChild, ContentChild, ElementRef, Renderer2, AfterContentChecked, AfterViewChecked } <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-child'</span>,
  template: <span class="hljs-string">`
  &lt;button (click)="toggleEnlarge()"&gt;Toggle Enlarge&lt;/button&gt;
  &lt;ng-content&gt;&lt;/ng-content&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChildComponent <span class="hljs-keyword">implements</span> AfterContentChecked {
  <span class="hljs-meta">@ContentChild</span>(<span class="hljs-string">"pReference"</span>, { read: ElementRef }) pElement: ElementRef;
  textEnlarge: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">false</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> renderer: Renderer2</span>) { }

  toggleEnlarge() {
    <span class="hljs-built_in">this</span>.textEnlarge = !<span class="hljs-built_in">this</span>.textEnlarge;
  }

  ngAfterContentChecked() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.textEnlarge)
      <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.pElement.nativeElement, <span class="hljs-string">'font-size'</span>, <span class="hljs-string">'25px'</span>);
      <span class="hljs-keyword">else</span>
      <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.pElement.nativeElement, <span class="hljs-string">'font-size'</span>, <span class="hljs-string">'initial'</span>);
    }
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-parent'</span>,
  template: <span class="hljs-string">`
  &lt;button (click)="toggleHighlight()"&gt;Toggle Highlight&lt;/button&gt;
  &lt;h1 #hOneRefereance&gt;View Child&lt;/h1&gt;
  &lt;app-child&gt;
    &lt;p #pReference&gt;Content Child&lt;/p&gt;
  &lt;/app-child&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ParentComponent <span class="hljs-keyword">implements</span> AfterViewChecked {
  <span class="hljs-meta">@ViewChild</span>(<span class="hljs-string">"hOneRefereance"</span>, { read: ElementRef }) hOneElement: ElementRef;
  textHighlight: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">false</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> renderer: Renderer2</span>) { }

  toggleHighlight() {
    <span class="hljs-built_in">this</span>.textHighlight = !<span class="hljs-built_in">this</span>.textHighlight;
  }

  ngAfterViewChecked() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.textHighlight)
      <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.hOneElement.nativeElement, <span class="hljs-string">'background-color'</span>, <span class="hljs-string">'yellow'</span>);
    <span class="hljs-keyword">else</span>
      <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.hOneElement.nativeElement, <span class="hljs-string">'background-color'</span>, <span class="hljs-string">'initial'</span>);
  }
}
</code></pre>
<p>The above example contains two buttons that toggle a certain style for each element. Clicking the buttons toggles the true/false values unique to each component. These booleans determine if the custom styles apply. Instead of these values causing changes imperatively, the lifecycle hooks (<code>ngAfterViewChecked</code> and <code>ngAfterContentChecked</code>) declaratively alter the DOM.</p>
<p>The declarative approach explicitly changes the style through the element’s reference. In imperative programming, changes to the DOM based off data are implicit. Check out this article on <a target="_blank" href="https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2">imperative and declarative programming</a> to learn more.</p>
<p>The main thing to notice is how these references get pulled from the template. In the example, there are two sections of the template queried using two decorators: <code>@ViewChild</code> and <code>@ContentChild</code>.</p>
<p>They differ in where they look for an element’s reference whether it be in the content DOM or view DOM. These two DOMs exist in ParentComponent’s template. Differentiating between them is important because they finish rendering at separate times.</p>
<p>This is why <code>@ViewChild</code> and <code>@ContentChild</code> both exist. They work together with their companion lifecycle hooks <code>ngAfterViewChecked</code> and <code>ngAfterContentChecked</code>. These lifecycle hooks wait for their respective queries to resolve before executing.</p>
<p>Once resolved, <code>@ViewChild</code> and <code>@ContentChild</code> provide references to two elements. Both exist in separate parts of the DOM. The boolean data still determines the outcome. How that outcome translates to the DOM is the key difference from before. The DOM updates via<code>Renderer2</code>’s direct manipulation of it.</p>
<h4 id="heading-content-projection"><strong>Content Projection</strong></h4>
<p>The content DOM exists in the innerHTML of ChildComponent’s <code>&lt;app-child&gt;&lt;/app-child&gt;</code> element. It is all positioned within ParentComponent’s template. The innerHTML of <code>app-child</code> <em>projects</em> onto ChildComponent’s template through <code>&lt;ng-content&gt;&lt;/ng-content&gt;</code>.</p>
<p>This exemplifies content projection. Displaying content from <code>one</code> component to another using the innerHTML of <code>another</code>’s tags in <code>one</code>’s template so that <code>another</code> component can pull that innerHTML into its own template via <code>&lt;ng-content&gt;&lt;/ng-content&gt;</code>. <em>Thank you for reading that sentence.</em></p>
<p>Hence why ChildComponent references its <code>&lt;p&gt;&lt;/p&gt;</code> element using <code>@ContentChild</code>. Content contained within <code>&lt;app-child&gt;&lt;/app-child&gt;</code> in ParentComponent’s template makes up the content DOM. ChildComponent references the element with an <code>@ContentChild</code> query.</p>
<p>ParentComponent’s view DOM consists of everything accessible from within the component’s view. This does not necessarily include the entire template given the innerHTML of <code>&lt;app-child&gt;&lt;/app-child&gt;</code>. Again, this part of the DOM is queried from ChildComponent using <code>@ContentChild</code>. Everything else gets queried using <code>@ViewChild</code> from the ParentComponent class.</p>
<p>This is a great way for components to exchange content and query their own content regardless of their DOM type. Components can communicate with themselves and others using data binding as well. Read more about it from <a target="_blank" href="https://guide.freecodecamp.org/angular/data-binding">this article</a>.</p>
<h4 id="heading-component-styles"><strong>Component Styles</strong></h4>
<p>Styles are critical to a component’s readability and interactivity. Each component encapsulates its style-sheet dependencies. That way they only apply to the component’s template HTML. A special technique introduced by HTML’s shadow DOM makes this possible.</p>
<p>A shadow DOM branch may exist on any element. This part of the DOM cannot be seen from the HTML’s source code. Standard HTML elements leverage the shadow DOM to provide their trademark appearances. A shadow DOM branch must anchor itself to a visible component so that it can style and customize it.</p>
<p>The unique aspect about a shadow DOM branch is its encapsulation. Everything used to style a shadow DOM branch’s root element is private to it. No other element can access it.</p>
<p>Angular embraces this form of encapsulation with components. The style-sheet and template of a component encapsulate together. No other components have access to them. Style-sheet clashes cannot occur.</p>
<p>Angular does not use the shadow DOM by default. It uses an emulation system that mimics the behavior of the shadow DOM. This is a temporary measure since some web browsers do not yet support the shadow DOM API.</p>
<p>The <code>@Component</code> metadata contains the <code>encapsulation</code> field. This lets developers toggle in-between emulated shadow DOM, real shadow DOM, or neither. Here are the options in their respective order:</p>
<ul>
<li><code>ViewEncapsulation.Emulated</code> - fake shadow DOM (default)</li>
<li><code>ViewEncapsulation.Native</code> - real shadow DOM (now deprecated since Angular 6.0.8)</li>
<li><code>ViewEncapsulation.None</code> - neither</li>
</ul>
<p><code>ViewEncapsulation.None</code> means the component’s style-sheets elevate to the global scope. Not recommended considering components should form their own private unit (encapsulation). Angular still provides it as an escape hatch for extreme situations.</p>
<h4 id="heading-conclusion"><strong>Conclusion</strong></h4>
<p>Components build applications. They are privately scoped and separately uniform of each other unless configured otherwise. Applications tend to begin from the root module. Past that, components form an elongated tree defining the rest of the application.</p>
<p>A component covers a designated unit of the application interface. This includes its styles, logic, and layout. Other schematics such as pipes, services, and directives see frequent use in component code. You can learn more about these interactions in some of the other Angular guide articles.</p>
<p>Do not forget that components must <a target="_blank" href="https://angular.io/guide/bootstrapping">bootstrap</a>. This can happen in the root module or the component’s metadata. This is so Angular recognizes the component wherever it appears in the application.</p>
<p>You can always learn more, as components carry far more depth than that what this article could convey.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Top JavaScript Frameworks For Front-End Development in 2020 ]]>
                </title>
                <description>
                    <![CDATA[ By Shifa Martin Front-end developers might know this game already: you type “top JavaScript frameworks” into Google and you get so many JavaScript frameworks from which to choose. There are always more choices for JavaScript frameworks. And it's alwa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/complete-guide-for-front-end-developers-javascript-frameworks-2019/</link>
                <guid isPermaLink="false">66d460f03bc3ab877dae2230</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[  Single Page Applications  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vue ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Vue.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Vuex ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Applications ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 08 Nov 2019 12:45:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/1181834_8257_2.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shifa Martin</p>
<p>Front-end developers might know this game already: you type “top JavaScript frameworks” into Google and you get so many JavaScript frameworks from which to choose.</p>
<p>There are always more choices for JavaScript frameworks. And it's always tough to choose a JavaScript framework for front-end development.</p>
<p>So, what are front-end developers looking for in their tech stacks? As a full-time developer, I know it comes down to rapid development and easy-to-make UIs.</p>
<p>Rather than try to be decisive, we, 450+ developers at <a target="_blank" href="https://www.valuecoders.com/">ValueCoders software development company</a>, voted and shortlisted a few of the best JavaScript frameworks.</p>
<h3 id="heading-our-vote-goes-to-react">Our Vote Goes to React</h3>
<p>I was not surprised to see this. Most of our developers voted for React as one of the best JavaScript frameworks. There have been plenty of projects along the way that our front-end developers are handling that highlighted the strengths of the JS framework. React provides a combination of the following:</p>
<ul>
<li>Reusable components</li>
<li>Synchronization of state and view</li>
<li>Routing and template system</li>
</ul>
<p>Our developers implement front-end logic by relying heavily on React. At the same time, I was surprised by how simple it was to create  applications with React.</p>
<h3 id="heading-here-is-an-overview-of-our-app">Here is an Overview of Our App</h3>
<p>The application is simple. It’s a <a target="_blank" href="https://www.valuecoders.com/case-studies/online-music-school">studio management app</a> for music teachers that helps them focus more on their teaching and less on the management of their music studio.</p>
<p>The key challenge was creating one ‘Activity Dashboard’ for teachers where they could manage all their students' activities and track their progress over time. We overcame this challenge by using <a target="_blank" href="https://redux.js.org/introduction/ecosystem">Redux libraries</a> to build the platform. We built a teacher’s studio from where they could manage their students' progress, showcase new music lessons, chat with them, compare students music playing with live music, and provide them feedback.</p>
<p><img src="https://lh3.googleusercontent.com/MlqY_vfvZEVG1w6UKUhasIekmnODKhSBr5MM3WVLVSzS6_rXyi-wq0npVhBqILg1Totwwccloq9XWQwFF-VWpOCtF8vqj7yOmV4tDKJ9vyNM8jg_YJYvt4x6njz51w1-eI9ojzQ6" alt="Image" width="315" height="564" loading="lazy"></p>
<p>So, this is my experience with React JS. But many would argue that Vue is one of the best front-end JavaScript frameworks with many useful tools. </p>
<p>Front-end developers are the ones deciding which JavaScript framework will do the job. In doing so, they face a lot of challenges because they need to decide what they’ve always needed. Often, we have to choose a JavaScript framework now, not after a week of research. In that case, most developers go with what they know. But maybe the stacks you’re familiar with are no longer cutting it in terms of performance.</p>
<p>Even just choosing among Angular, React, an Vue, it is difficult for new developers. Rather than making it more exhaustive for you, here is the list of the top JavaScript frameworks for front-end developers.</p>
<h2 id="heading-the-big-5-javascript-frameworks">The Big 5 JavaScript Frameworks</h2>
<p>The five JavaScript frameworks that currently dominate the market in terms of popularity and usage are:</p>
<ul>
<li>React </li>
<li>Vue </li>
<li>Angular </li>
<li>Ember</li>
<li>Backbone.js. </li>
</ul>
<p>They each have large communities. If you are a front-end developer or are going to start your new project on front-end technologies, these five are your best bets. Here’s a look at the npm trends over the last six months.</p>
<p><img src="https://lh3.googleusercontent.com/XxQMWDLC6oyQMOna5NKP_lDYYgmXgHnLclulqOZ-0C-l5n-hFw-q5BLnbM7hRGEB8kl9w7GSUAzf6K1gexsZrcp9O7T7ju_ns94qNUR_2-12cR2_Rn30F3f9ul4iO2rGqdRv1SYl" alt="Image" width="1080" height="450" loading="lazy"></p>
<p><img src="https://lh3.googleusercontent.com/cSAcJvog37qO1rB1OCFvKPouN6R5OcbHam-Qmzc6Ei-nnOLxr-FoeeHD6sKQKEd-b3vmushcuEFjN02EPKbzYkEuOQlHtJizRRS2zVD77TUKRM-leOcGJpa1ZZqzQUAaD3EdUvRM" alt="Image" width="1098" height="332" loading="lazy"></p>
<h2 id="heading-1-react">1. React</h2>
<p>React is the definite leader in the JS world. This JavaScript framework uses a <a target="_blank" href="https://en.wikipedia.org/wiki/Reactive_programming">reactive approach</a> and also introduces many of its own concepts for front-end web development. </p>
<p>To use React , you’ll have to learn to use a plethora of additional tools to reach high flexibility in front-end development. For example, here's a less exhaustive list of libraries you can use with React: Redux, MobX, Fluxy, Fluxible, or RefluxJS. React can also be used with jQuery AJAX, fetch API, Superagent, and Axios.</p>
<h3 id="heading-concurrent-mode">Concurrent Mode</h3>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/reactjs/status/1187411505001746432"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>React is constantly working towards improving concurrent mode. To take this forward, React Conf 2019 wrapped up last month where the React team talked about improving <a target="_blank" href="https://reactjs.org/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html">Concurrent Mode and the Suspense model</a>. Both the features make React apps more responsive by rendering trees without blocking threads. This allows React to focus on high priority tasks like responding to user input.</p>
<h3 id="heading-suspense">Suspense</h3>
<p>React also introduced Suspense to improve the developer’s experience when handling asynchronous data fetching in React apps. In short, the new update to Suspense lets the component wait until a condition is met. </p>
<p>Hooks are another important update to React 16.8. <a target="_blank" href="https://reactjs.org/docs/hooks-overview.html">React hooks</a> lets you use every important feature of React – server-side rendering, accessibility, concurrent mode, and suspense – all without writing a class.</p>
<p>React applications are divided into multiple components that contain both business logic and HTML markup functions. To improve the communication between components, developers can use either Flux or a similar JavaScript library. </p>
<p>React also introduced objects, like state and props. With the state and props objects, you can simply pass data from a component to the layout or from a parent component to a child component.</p>
<p><strong>Introduction to the React ecosystem:</strong></p>
<ul>
<li>The React library plus React router for implementing routes.</li>
<li><a target="_blank" href="https://reactjs.org/docs/react-dom.html">React-DOM</a> for DOM manipulation.</li>
<li>React developer tools for Firefox and Chrome browsers.</li>
<li><a target="_blank" href="https://reactjs.org/docs/introducing-jsx.html">React JSX</a>, a markup language that mixes HTML into JavaScript.</li>
<li>React Create App command line interface to set up a React project.</li>
<li>Redux and Axios libraries to organize communication with the backend team.</li>
</ul>
<p>No doubt, React is one of the most popular JavaScript frameworks. And, I think that React can be your first choice for creating advanced-grade apps. </p>
<h2 id="heading-2-angular-2-to-angular-9">2. Angular 2 to Angular 9</h2>
<p>Angular 9 will mark a turning point revealed by the Angular team at the recent AngularConnect 2019. According to the update, the team is planning to make the <a target="_blank" href="https://angular.io/guide/ivy">Angular Ivy compiler</a> available for all apps. The main benefit of Angular Ivy is that it is able to reduce the size of applications. </p>
<p>Angular today has become very advanced and modular to use for front-end development. Previously you could insert a link to the AngularJS library in the main HTML file, but now you can do the same by installing separate modules. </p>
<p>Angular's flexibility is commendable. That’s why Angular's 1.x versions are still in demand. However, many developers currently rely on Angular 2+ because of its MVC architecture which has changed substantially to a component based architecture.  </p>
<p>Angular has a couple of additional challenges. You're almost obliged to use TypeScript to ensure type safety in Angular apps. TypeScript makes the Angular 2+ framework not so pleasant to work with. </p>
<p><strong>Angular’s ecosystem is comprised of:</strong></p>
<ul>
<li>For quick project setup, Angular's command line interface is helpful.</li>
<li>Developers will get a set of modules for Angular projects: @angular/common, @angular/compiler, @angular/core, @angular/forms, @angular/http, @angular/platform-browser, @angular/platform-browser-dynamic, @angular/router, and @angular/upgrade. </li>
<li>Angular uses Zone.js a JavaScript library to implement zones in Angular apps.</li>
<li>TypeScript and CoffeeScript both can be used with Angular.</li>
<li>For communication with server-side apps, Angular uses RxJS and the Observable pattern.</li>
<li>Angular Augury for <em>debugging</em> Angular apps.</li>
<li>Angular Universal for creating server-side apps with Angular.</li>
</ul>
<p>Angular2 is a complete JavaScript framework with all the tools a modern front-end developer needs. You can choose Angular if you don’t like to work with additional libraries as with React.</p>
<h2 id="heading-3-vue">3. Vue</h2>
<p>The Snyk JavaScript framework report for 2019 is out. The report mainly focused on security risks in both React and Angular.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/snyksec/status/1189527376197246977"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>The concept of Vue has been taken from Angular and React, but Vue is better in many ways. I’ll talk about its features, but first check out what the <a target="_blank" href="https://snyk.io/blog/javascript-frameworks-security-report-2019/">Synk report</a> says about Vue's front-end security. Vue has been downloaded 40 million times this year and records only <a target="_blank" href="https://snyk.io/vuln/npm:vue">four direct vulnerabilities</a>. All of them have been fixed. </p>
<p>For any front-end developer unfamiliar with Vue, let’s clarify several points. </p>
<p>With Vue you store component logic and layouts along with stylesheets in one file. This is the same way React works, without stylesheets. To let components talk to each other, Vue uses the props and state objects. This approach also existed in React before Vue adopted it.</p>
<p>Similar to Angular, Vue wants you to mix HTML layouts with JavaScript. You have to use Vue directives such as v-bind or v-if to interpolate values from the component logic to templates.</p>
<p>One of the reasons why Vue is worth considering instead of React is because of the Redux library that’s often used in large-scale React applications. As explained in the React section, when a React+Redux app grows bigger, you’ll spend a lot of time applying small changes to multiple files instead of actually working on features. The Vuex library – a Flux-like state management tool designed for Vue – seems less unwieldy than Redux.</p>
<p>If you're choosing between Vue and Angular, the reasons to opt for Vue over Angular can be reduced to the following: Angular is an over-complicated, full-fledged framework with a restrictive nature; Vue is much simpler and less restrictive than Angular.</p>
<p>Another advantage of Vue over Angular and React is that you don’t have to learn JavaScript once more. </p>
<p><strong>An introduction to the VueJS ecosystem:</strong></p>
<ul>
<li>Vuex comes with a dedicated library for application management.</li>
<li>Vuex is similar to the concept of Flux.</li>
<li>You will get Vue-loader for components and vue.js devtools for Chrome and Firefox browsers.</li>
<li>Vue-resource and Axios tools for communication between Vue and the backend source.</li>
<li>Vue.js support Nuxt.js for creating server-side applications with Vue; Nuxt.js is basically a competitor to Angular Universal.</li>
<li>You will get a Weex JavaScript library with Vue syntax that is used for mobile app development.</li>
</ul>
<p>Vue is excellent in terms of its workflow to other frameworks. I might opt for Vue because it’s less complicated than React and Angular JS and a great choice for developing enterprise-level apps.</p>
<h2 id="heading-4-ember">4. Ember</h2>
<p>Ember 3.13 released this year with some new updates and features. Ember is just like Backbone and AngularJS, and is also one of the oldest JavaScript frameworks. But with the new update, <a target="_blank" href="https://blog.emberjs.com/2019/09/25/ember-3-13-released.html">Ember 3.13</a> is compatible with new bug fixes, performance improvements, and deprecation. Tracked property updates have also been introduced that allow simpler ways of tracking state change in the ergonomic system of Ember apps.</p>
<p>Ember has a relatively intricate architecture, which will allow you to quickly build huge client-side applications. It realizes a typical MVC JavaScript framework, and Ember’s architecture comprises the following parts: adapters, components, controllers, helpers, models, routes, services, templates, utils, and addons.</p>
<p>One of Ember’s best features is its command line interface tool. The Ember CLI helps front-end developers be highly productive and lets them complete projects on time. You can not only create new projects with ready setups, but you can also create controllers, components, and project files using automatic generation. </p>
<p><strong>The EmberJS ecosystem is comprised of:</strong></p>
<ul>
<li>Ember CLI tool for quick prototyping and managing dependencies.</li>
<li>Ember server built into the framework for the development of apps.</li>
<li>You'll get Ember.js library and Ember Data for data management.</li>
<li>Handlebars template engine for Ember applications.</li>
<li>QUnit testing framework for Ember.</li>
<li>Ember Inspector development tool for Chrome and Firefox browsers.</li>
<li>Ember Observer for public storage and Ember addons to implement generic functionalities.</li>
</ul>
<p>Although Ember is underrated, it's perfect for creating complex client-side apps. </p>
<h2 id="heading-5-backbonejs">5. Backbone.js</h2>
<p>Backbone is a JavaScript framework based on the MVC architecture. In Backbone.js, the View of MVC helps implement component logic similarly to a Controller. Backbone view can use engines like Mustache and Underscore.js.</p>
<p>Backbone is an easy to use JavaScript framework that allows for quick development of single page applications. To use Backbone.js to the fullest extent, you’ll have to choose tools: Chaplin, Marionette, Thorax, Handlebars or Mustache, and so on. </p>
<p>If you need to design an app that has different types of users, Backbone collections (arrays) can be used here to separate the models. Backbone.Events can be used with Backbone models, collections, routes, and views. </p>
<p><strong>Introducing the BackboneJS ecosystem:</strong></p>
<ul>
<li>The Backbone library consists of events, models, collections, views, and router.</li>
<li>Underscore.js, a JavaScript library with helper functions that you can use to write cross-browser JavaScript.</li>
<li>You can use template engines such as Mustache and jQuery-tmpl.</li>
<li><a target="_blank" href="http://backplug.io/">BackPlug</a> online repository with a lot of ready solutions for Backbone-based apps.</li>
<li>Backbone generator CLI for building Backbone apps.</li>
<li>Marionette, Thorax, and Chaplin JavaScript libraries to develop an advanced architecture for Backbone apps.</li>
</ul>
<p>Backbone.js is a perfect choice for front-end and back-end development as it supports REST APIs that are used to synchronize the front-end and back-end. </p>
<h2 id="heading-need-more-help">Need More Help?</h2>
<p>All front-end developers out there, if you need help with JavaScript frameworks, feel free to <a target="_blank" href="https://www.valuecoders.com/contact">get in touch</a>. Or, you can also contact us to <a target="_blank" href="https://www.valuecoders.com/hire-developers/hire-reactjs-developers">hire ReactJS developers</a>, Vue developers, or Angular developers. </p>
<blockquote>
<p>_Or, leave me a note or <a target="_blank" href="https://twitter.com/ValueCoders?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor">Tweet</a> out to me._</p>
</blockquote>
<p>Remember this article gives you a general roadmap on JavaScript frameworks. Tell me if I have missed something, and we can discuss that. I hope it will also help achieve your front-end development goals.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How I Built an HR Portal on Angular 4 and Magento ]]>
                </title>
                <description>
                    <![CDATA[ By Shifa Martin Sometimes trying a new technology mashup works wonders. Both Magento 2 + Angular 4 are very commonly talked about, and many consider them to be the future of the development industry.  For example, I recently used Magento + Angular 4 ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-i-built-an-online-hrm-management-portal-on-angular-4-magento/</link>
                <guid isPermaLink="false">66d460f47df3a1f32ee7f899</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Magento ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 23 Oct 2019 09:59:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/10/background-close-up-computer-2740956-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shifa Martin</p>
<p>Sometimes trying a new technology mashup works wonders. Both Magento 2 + Angular 4 are very commonly talked about, and many consider them to be the future of the development industry. </p>
<p>For example, I recently used Magento + Angular 4 to build a super-efficient <a target="_blank" href="https://www.valuecoders.com/case-studies/hr-management-portal">HR management portal</a>.</p>
<h2 id="heading-learning-with-the-best-examples">Learning With the Best Examples</h2>
<p>One of the most sought after features of an hr portal is “managing diverse requirements promptly". This means that the human resources department need a software to manages the whole employee performance life cycle and other HR activities at a click of a button. For example, handling onboarding of employees, performance appraisals, training and development, leave management, grievance management, disciplinary processes, etc etc. then they review the final outcome.</p>
<blockquote>
<p>The HR portal I built is an intuitive online management software that reported as high as 90 percent better output than other tools. However, it suffered from many challenges such as the speed of software, output quality, and promptness. </p>
</blockquote>
<h3 id="heading-challenges">Challenges</h3>
<p>A user typically enters numerous details in combinations and has a hop between step 1 and step 2. Every time the user hops between different tabs, the entire details of the employee get reloaded. This is annoying and the chance of user abandonment is high.</p>
<p>The prototype of such an independent HR portal worked great. However, developing it was a complex task. Our developers had to make AngularJS and Magento (PHP) work together as a last resort. </p>
<p>My firm <a target="_blank" href="https://www.valuecoders.com/">ValueCoders software development company</a> which is a world leader in IT and software solutions has its own development team that worked at their wits’ end on this HR portal. </p>
<h2 id="heading-why-magento-with-angular-4-for-hr-portal">Why Magento With Angular 4 for HR Portal?</h2>
<p>Before coming to us, our client had already received offers from different development agencies. And, as a friendly favor, my team was asked to review all those ideas for their hr portal. But, I was amazed to see that one of them had sent only one thing that they were going to build the hr portal with the typescript-based framework Angular. </p>
<p>And that wasn’t all. They had even tried to hide the fact that this technology wasn’t enough to build the hr portal. Instead, they promoted their brand and also proposed a price that didn't justify making an online HR portal with high-quality propositions. </p>
<p><strong>The crux of the matter is why we have used Magento with AngularJS for HR portal.</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/giphy--1--1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>No doubt, Magento is one of the most popular open-source CMS systems written in PHP that justifies that each e-portal has to be unique. With its out-of-the-box features, open-source architecture, and REST API, Magento gives an unrivaled ability to customize and third-party integrations to your app that you could only dream of. </p>
<p>However, the rise of internet connectivity, smartphones, and tablets have directly affected the e-commerce CMS market. Today customers don’t just expect an e-portal or hr portal to be unique but also want it to work fast and seamlessly. In an attempt to bring a native feel to the website is the biggest advantage of MVC JavaScript framework like AngularJS. Some praise it as the future of the e-commerce development industry and others call it a trendy gimmick.</p>
<p>Having an MVC framework meant that customers can traverse through the hr portal from page to page or view by view and not like a book. This means instead of refreshing the entire web page the user navigates to an internal page and only the relevant section will be updated. The result is the blazing fast loading hr portal because the inner pages of the website never load. </p>
<p>Explaining the entirety of AngularJS and Magento is beyond the scope of this article, but we will look at the quick code snippets for a comprehensive guide on the HRM tutorial.</p>
<p>Before we move towards the more technical details, a brief introduction of what type of hr portal we’ve dealt with here seems to be in place.</p>
<h2 id="heading-features-of-hr-portal">Features of HR Portal</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/5d55e5d304e085e83b57aeda747ee0eb.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The client is Australia’s leading HRIS platform that manages the whole employee lifecycle at the click of a button. They help centralize HR activities and improve the efficiency of your business with lots of awesome features.</p>
<p>After some discussions with the client, a few specs crystallized:</p>
<ul>
<li>To develop a hr portal for managing and facilitating all functions of the Human resource department in the enterprises which deals with payroll, performance, employees management, recruitment, training etc.</li>
<li>Client-side should be strong and able to manage diverse requirements promptly.</li>
<li>Developing a hr portal that provides smart way to manage HRM and save both money and time.</li>
<li>No loss to quality of the website.</li>
</ul>
<p>These are pretty good set of features for an hr portal. This is exactly what our client want from us with a new mashup of technology. So if you want to know the end result, here's is an overview of the coding on Angular 4 for the hr portal.</p>
<p>So that's I tried to do. And hit the jackpot. Now that I have covered all the contextual things, I can finally you take to more technical stuff.  </p>
<p>Showing one of the features of the hr portal that is organizational structuring or treemapping, wherein a user can check the complete details of an employee by entering employee id, name, department or operations type.  This tool give you a method for displaying hierarchical data using nested figures and in just one click of enter tab.</p>
<h3 id="heading-lets-code-with-angular-4">Let's Code With Angular 4:</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/coding-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Coding on Angular 4 For Organizational Chart/Employee Details</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/coding-on-angular.png" alt="Image" width="600" height="400" loading="lazy">
<em>Coding on Angular 4 For Organizational Chart/Employee Details</em></p>
<blockquote>
<p>After getting the hr portal foundation ready using Angular 4, one of the first challenges was to add features on a different development environment.</p>
</blockquote>
<h3 id="heading-heres-another-illustration-with-the-php-codes">Here's another illustration with the PHP codes:</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/happyHr1-php-1-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/Happyhr2-php-2-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/php-new-01-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/php-new-02-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/php-new-03-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/php-new-04-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/php-new-05.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Considering the above examples, hopefully this will save someone out there fair amount of time and efforts spend in the coding to get this type of HR portal ready for your business. </p>
<h2 id="heading-to-sum-up-my-experience">To Sum Up My Experience</h2>
<p>This hr portal project taught me continuous integration, deployment, and monitoring of the software solution before submitting to a new release to the app stores. However, a few simple things I still considered a necessary:</p>
<ul>
<li>The client company always want to automate everything that can be automated. It is possible only with the team of developers. So I was determined to hire Angular developers that have desirable experience in the industry and can make the development process as easy as possible.</li>
<li>If there is one thing you can count on the way of developing your hr portal, it's that you'll take the help of dedicated developers before you start the actual app/web development process.     </li>
</ul>
<p>Admittedly, the technology is ever changing and far from perfect. But I and many other developers would not hesitate to use them again and again. As always, if you are looking for any help on HR portal development feel free to <a target="_blank" href="https://www.valuecoders.com/contact">get in touch</a>. </p>
<p>And, if you're looking for experienced <a target="_blank" href="https://www.valuecoders.com/hire-developers/hire-angularjs-developers">Angular developers</a>, <a target="_blank" href="https://www.valuecoders.com/hire-developers/hire-magento-developers">Magento developers</a> and interested to hire them for your next hr portal project, ValueCoders software development team is there to help you!      </p>
<blockquote>
<p>Connect with me on Twitter for more updates on future posts/tutorials: <a target="_blank" href="https://twitter.com/ValueCoders">https://twitter.com/ValueCoders</a></p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Angular vs React: Which One to Choose for Your App ]]>
                </title>
                <description>
                    <![CDATA[ A precise side-by-side comparison of general and technical aspects of Angular and React There are so many articles titled “Angular vs React”, “React vs Angular”, “Angular or React” – it is a miracle you opened this one! What these articles are missin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/angular-vs-react-what-to-choose-for-your-app-2/</link>
                <guid isPermaLink="false">66be14af9f6cdc38e7dec50b</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ angular 5 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ angular2 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ angular6 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ angular8 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oleh Romanyuk ]]>
                </dc:creator>
                <pubDate>Tue, 08 Oct 2019 13:49:33 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/10/react-vs-angular.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <h3 id="heading-a-precise-side-by-side-comparison-of-general-and-technical-aspects-of-angular-and-react">A precise side-by-side comparison of general and technical aspects of Angular and React</h3>
<p>There are so many articles titled “Angular vs React”, “React vs Angular”, “Angular or React” – it is a miracle you opened this one! What these articles are missing, however, is a precise <strong>side-by-side comparison</strong> of Angular vs React. </p>
<blockquote>
<p>So this is what I am going to do in this blog post: to place <a target="_blank" href="https://keenethics.com/tech-front-end-react">React</a> and <a target="_blank" href="https://keenethics.com/tech-front-end-angular">Angular</a> in direct juxtaposition. We're going to review and contrast the two JavaScript frameworks and look at each possible characteristic to make sure we don't miss even a single piece of data. </p>
</blockquote>
<p>In the end, I am not going to tell you which technology to choose. But I will give you enough food for thought for you to choose the technology that suits you and your project best.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/Angular_React_comparison-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/2PpsrJKGRiYFYhCXh9NcfM/c43b9b24509d459ec94d7f7bb6ce207a/search__1_.png?h=300" alt="search (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-1-brief-overview">1. Brief Overview</h2>
<h3 id="heading-react">React</h3>
<p>React is a JavaScript library for UI development. It is managed by Facebook and an open-source community of developers.</p>
<p>The framework was introduced in May 2013.</p>
<p>The latest updates were released on August 8th, 2019 – just over a month ago.</p>
<h3 id="heading-angular">Angular</h3>
<p>Angular is an open-sourced JavaScript framework for web and mobile development. It is TypeScript-based and managed by Google’s Angular Team and the Angular developer community. </p>
<p>Launched in September 2016, Angular (also known as Angular 2.0) is a complete rewrite of AngularJS (Angular 1.0), which was introduced in 2010. </p>
<p>There have been six versions of Angular already, and the latest release took place on August 28th, 2019 – almost three weeks ago.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/26X0F8SysU9aRODLpiTS8T/6d17ff52d723a3d8b34b54a4f53f6e34/internet__1_.png?h=300" alt="internet (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-2-universality">2. Universality</h2>
<h3 id="heading-react-1">React</h3>
<p>React is a framework used in both web and mobile development. However, for mobile development, it needs to be incorporated with Cordova. Moreover, for mobile development, there is an additional framework – React Native.</p>
<p>React can be used to build both single-page and multiple-page web applications.</p>
<h3 id="heading-angular-1">Angular</h3>
<p>Angular is suitable for both web and mobile development. In mobile development, however, a great share of work is done by Ionic. Furthermore, similarly to React, Angular has an additional mobile development framework. The counterpart of React Native is NativeScript. </p>
<p>Angular can also be used for both single- and multiple-page web apps.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/7EP4F57YmLWZvF7OO0iDTX/b7ba3aacd67d576f1fcc49ba78478916/success__1_.png?h=300" alt="success (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-3-self-sufficiency">3. Self-Sufficiency</h2>
<h3 id="heading-react-2">React</h3>
<p>React is a framework for UI development, so apps written with React need additional libraries to be used. For instance, Redux, React Router, or Helmet optimize the processes of state management, routing, and interaction with the API. Such functions as data binding, component-based routing, project generation, form validation, or dependency injection require additional modules or libraries to be installed.</p>
<h3 id="heading-angular-2">Angular</h3>
<p>Angular is a full-fledged framework for software development, which usually does not require additional libraries. All the above-mentioned functions – data binding, component-based routing, project generation, form validation, and dependency injection – can be implemented with the means of Angular package.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/pFVFckO96mf60jYoDLsXA/df1d17d0c516c24b906feacc66a36b2d/open-book.png?h=300" alt="open-book" width="256" height="256" loading="lazy"></p>
<h2 id="heading-4-learning-curve">4. Learning Curve</h2>
<h3 id="heading-react-3">React</h3>
<p>React is minimalistic: no dependency injection, no classic templates, no overly complicated features. The framework will be quite simple to understand if you already know JavaScript well. </p>
<p>However, it takes quite some time to learn how to set up a project because there is no predefined project structure. You also need to learn the Redux library, which is used in more than half of React applications for state management. Constant framework updates also require additional effort from the developer. Furthermore, there are quite a lot of best practices in React, which you will need to learn to do things right.</p>
<h3 id="heading-angular-3">Angular</h3>
<p>Angular itself is a huge library, and learning all the concepts associated with it will take much more time than in the case of React. Angular is more complex to understand, there is a lot of unnecessary syntax, and component management is intricate. Some complicated features are embedded into the framework core, which means that the developer cannot avoid learning and using them. Moreover, there are a lot of ways of solving a single issue. </p>
<p>Although TypeScript closely resembles JavaScript, it also takes some time to learn. Since the framework is constantly updated, the developer needs to put some extra learning effort.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/3UoGpyTMCV8CGu1Z4kjpse/d32f947e97c9ca59b8d06ffa3cbcab5e/users__1_.png?h=300" alt="users (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-5-community">5. Community</h2>
<h3 id="heading-react-4">React</h3>
<p>React framework is one of the most popular JS frameworks worldwide, and the community supporting and developing it is huge.</p>
<p>Working with React, you have to be a continuous learner since the framework is often updated. While the community tries to go forward with the latest documentation as swiftly as possible, keeping up with all the changes is not that easy. Sometimes, there may be a lack of documentation, but the issue is often solved by the community support on thematic forums. </p>
<p>React is actively used by such companies as Facebook, Twitter, Netflix, Airbnb, PayPal, The New York Times, Yahoo, Walmart, Uber, and Microsoft.</p>
<h3 id="heading-angular-4">Angular</h3>
<p>Angular is less admired than React and faces a lot of skepticism, partially because of the unpopularity of Angular 1.0. Developers used to dismiss the framework as an overly complicated one as it required a lot of time to be spent learning. However, this framework has been developed by Google, which works in favor of Angular’s credibility. </p>
<p>Google provides the long-term support of the framework and constantly improves it. However, the updates are so fast that the documentation often falls behind. </p>
<p>Angular is used by such companies as McDonald’s, AT&amp;T, HBO, Apple, Forbes, Adobe, Nike, and Microsoft as well.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/42G1ot0FKIiLsLEss57U7C/afa7f06c694c2481af01923ade2c1f90/settings__1_.png?h=300" alt="settings (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-6-performance">6. Performance</h2>
<h3 id="heading-react-5">React</h3>
<p>React’s performance is greatly improved with the introduction of the virtual DOM. Since all virtual DOM trees are lightweight and built on server, the load on browser is reduced. Furthermore, since the data-binding process is unidirectional, bindings are not assigned watchers as in the case of Angular. Respectively, no additional workload is created.</p>
<h3 id="heading-angular-5">Angular</h3>
<p>Angular performs worse, especially in the case of complex and dynamic web apps. </p>
<p>The performance of Angular apps is negatively affected by bidirectional data-binding. Each binding is assigned a watcher to track changes, and each loop continues until all the watchers and associated values are checked. Because of this, the more bindings you have, the more watchers are created, and the more cumbersome the process becomes. </p>
<p>However, the most recent update of Angular has greatly improved its performance, and it does not lose to React anymore. Moreover, the size of an Angular application is slightly smaller than the size of a React app.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/LCPTXwhsTKQ4YasbWaJBg/3ecbcedd4687993fcca72086a16abc0f/menu__1_.png?h=300" alt="menu (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-7-language">7. Language</h2>
<h3 id="heading-react-6">React</h3>
<p>React is based on JavaScript ES6+ combined with JSX script. JSX is an extension for syntax, which makes a JavaScript code resemble that written in HTML. This makes the code easier to understand, and typos are easier to spot. For the JSX code to be compiled in a browser, React is augmented with Babel – a code translation tool.</p>
<h3 id="heading-angular-6">Angular</h3>
<p>Angular can use JavaScript or TypeScript, which is a superset of JS developed specifically for larger projects. TypeScript is more compact than JavaScript, the code is easier to navigate, and typos are easily spotted. Code refactoring process also becomes simpler and faster.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/34RQEkHFyn2MwWWbUxVwyx/d621c2de5692fb4b686b3702472676ab/layers__2_.png?h=300" alt="layers (2)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-8-app-structure">8. App Structure</h2>
<h3 id="heading-react-7">React</h3>
<p>The structure of React provides developers with the freedom to choose. There is no “the only right structure” for a React app. However, the necessity to design the app structure at the beginning of each project makes it more difficult and longer to start.</p>
<p>Besides, React offers only View layer, while Model and Controller are added with the usage of other libraries.</p>
<p>The architecture of a React app is component-based. The code is made of React components, which are rendered with React DOM library and directed in two ways: functional (with a function that returns JSX)...</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Hello</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">div</span>&gt;</span>Hello {props.name}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<p>...and class-based (with ES6 classes).</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Hello</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>Hello, {this.props.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
}
</code></pre>
<h3 id="heading-angular-7">Angular</h3>
<p>The structure of Angular is fixed and complex, suitable for experienced developers.</p>
<p>Angular is based on three layers – Model, Controller, and View. An object responsible for the Model is initialized by the Controller and displayed with the View.</p>
<p>The application code consists of different Angular components, each being written in four separate files: a TypeScript to implement the component, an HTML file to define the view, a CSS file to define the stylistic features, and a special file for testing purposes. Links to these files are written in the app directive, which displays the structural logic of the app. Respectively, Angular components are also reusable.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
@Component({
<span class="hljs-attr">selector</span>: <span class="hljs-string">'my-app'</span>,
<span class="hljs-attr">templateUrl</span>: <span class="hljs-string">'./app.component.html'</span>,
<span class="hljs-attr">styleUrls</span>: [<span class="hljs-string">'./app.component.css'</span>]
})
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppComponent</span> </span>{ }
</code></pre>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/1jnhjOLhvVfIJpf1JjAFlO/e14f81b5efdca246c0d2beab0e49c2f0/app__1_.png?h=300" alt="app (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-9-ui-components">9. UI Components</h2>
<h3 id="heading-react-8">React</h3>
<p>UI tools for React are developed by the community. There are a lot of free and paid UI components on the React portal. To use material design components in React, you would have to install an additional library – Material-UI Library &amp; Dependencies.</p>
<h3 id="heading-angular-8">Angular</h3>
<p>Angular has a built-in Material toolset, and it offers a variety of pre-built material design components. There are various buttons, layouts, indicators, pop-ups, and form controls. Because of this, UI configuration becomes simpler and faster.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/27zKcdqY3mOnzT5p8vrQbC/e987f42102e8875d0f7714d8db3288f8/file__1_.png?h=300" alt="file (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-10-directives">10. Directives</h2>
<h3 id="heading-react-9">React</h3>
<p>In React, templates and logic are explained in one place – at the end of the component. It allows the reader to quickly grasp the meaning of the code even if they do not know the syntax.</p>
<h3 id="heading-angular-9">Angular</h3>
<p>In Angular, each template is returned with an attribute – a directive of how the object has to be set. The syntax of Angular directives is complex and sophisticated, which makes it incomprehensible for a reader without any experience in working with this technology.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/4I2aqTboict17ysz5yGD4n/5a7fc19e15889f42b7561d34b18edae9/controls__1_.png?h=300" alt="controls (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-11-state-management">11. State Management</h2>
<h3 id="heading-react-10">React</h3>
<p>In React, each component has its own state. A React developer can create special components for holding the state of the entire application or a particular part of it. The major disadvantage here consists in the fact that the global state needs to be stored in multiple different parts of the app with data being manually passed around different component tree levels.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Clock</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">date</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</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>Hello world!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Now is {this.state.date.toLocaleTimeString()}.<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
}
</code></pre>
<p>To solve this problem, there is a special state management library – Redux. The idea of it is that the global state is represented as a single stateful object, which is altered in different parts of the app with the help of reducers – special Redux functions.</p>
<p>Another solution is offered by the state management library MobX. Unlike Redux with the global state stored in a single immutable stateful object, MobX offers storing only the minimal required state, while the rest of it can be derived.</p>
<h3 id="heading-angular-10">Angular</h3>
<p>In Angular, component data is stored in component properties. Parent components pass data through to children ones. State changes in some parts can be identified and recalculated, but in a large app, it can cause a multi-directional tree series of updates, which will be difficult to track. The features can be improved with the help of state management libraries, such as NgRx or RxJS , which would make sure that the data flow is unidirectional.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HeroListComponent</span> <span class="hljs-title">implements</span> <span class="hljs-title">OnInit</span> </span>{
  <span class="hljs-attr">heroes</span>: Hero[];
  selectedHero: Hero;
  <span class="hljs-keyword">constructor</span>(private service: HeroService) { }
  ngOnInit() {
    <span class="hljs-built_in">this</span>.heroes = <span class="hljs-built_in">this</span>.service.getHeroes();
  }
  selectHero(hero: Hero) { <span class="hljs-built_in">this</span>.selectedHero = hero; }
}
</code></pre>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/1FrBshReFNJB1yDkeNVBPr/091aac131dccf0267061a450f76fb897/network__1_.png?h=300" alt="network (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-12-dependency-injection">12. Dependency Injection</h2>
<h3 id="heading-react-11">React</h3>
<p>React does not fully support dependency injection as it does not fully comply with the idea of functional programming and data immutability. Instead, it has a global state for all components.</p>
<h3 id="heading-angular-11">Angular</h3>
<p>The greatest advantage of Angular rests in the fact that, unlike React, it supports dependency injection. Therefore, Angular allows having different lifecycles for different stores.</p>
<pre><code class="lang-js"><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> { HEROES } <span class="hljs-keyword">from</span> <span class="hljs-string">'./mock-heroes'</span>;
@Injectable({
  <span class="hljs-comment">// we declare that this service should be created</span>
  <span class="hljs-comment">// by the root application injector.</span>
  <span class="hljs-attr">providedIn</span>: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HeroService</span> </span>{
  getHeroes() { <span class="hljs-keyword">return</span> HEROES; }
}
</code></pre>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/4FJFtvDwvmQdgsCUx5MYOO/b87ee7b57de5908ef20405e95b707959/unlink__1_.png?h=300" alt="unlink (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-13-data-binding">13. Data Binding</h2>
<h3 id="heading-react-12">React</h3>
<p>Data binding stands for the data synchronization process between Model and View. React should be augmented with Redux, which allows you to work with immutable data and makes data flow unidirectional. Unidirectional binding is predictable, which facilitates the debugging process.</p>
<h3 id="heading-angular-12">Angular</h3>
<p>Angular works with bidirectional data-binding and mutable data. While the advantages of mutable and immutable data are a matter of a heated discussion, it is definitely easier to work with bidirectional data-binding rather than with the unidirectional approach. At the same time, bidirectional data-binding negatively affects the performance since Angular automatically develops a watcher for each binding.</p>
<p>The ways of data-binding in Angular:</p>
<pre><code class="lang-js">{{expression}}   Interpolation
[target]=<span class="hljs-string">"expression"</span>    Property
bind-target=<span class="hljs-string">"expression"</span>    Attribute
</code></pre>
<pre><code class="lang-js">(target)=<span class="hljs-string">"statement"</span> Event
on-target=<span class="hljs-string">"statement"</span> Event
</code></pre>
<pre><code class="lang-js">[(target)]=<span class="hljs-string">"expression"</span> Two-way
bindon-target=<span class="hljs-string">"expression"</span> Two-way
</code></pre>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/2mOdA6gBK5MqwjRRdgm5Mm/d679f1314811e0ba93ae2b106ddbf5f1/shuffle__1_.png?h=300" alt="shuffle (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-14-change-rendering">14. Change Rendering</h2>
<h3 id="heading-react-13">React</h3>
<p>React uses a virtual Document Object Model (DOM), which enables easily implementing minor data changes in one element without updating the structure of the entire tree. The framework creates an in-memory cache of data structure, computes the changes, and efficiently updates the DOM displayed in the browser. This way, the entire page seems to be rendered on each change, whereas actually, the libraries render changed subcomponents only. </p>
<p>The React team is constantly improving Fiber – a mechanism aimed at boosting the productivity of change rendering.</p>
<h3 id="heading-angular-13">Angular</h3>
<p>Angular uses a real DOM, which updates the entire tree structure even when the changes have taken place in a single element. The real DOM is considered to be slower and less effective than the virtual DOM. </p>
<p>To compensate for this disadvantage, Angular uses change detection to identify components that need to be altered. Therefore, the real DOM on Angular performs as effectively as the virtual DOM on React.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/77lE2Lv97WHOpaxBVDPjfX/2b4e6f55becbd8aae05b983cb072f3c7/edit__1_.png?h=300" alt="edit (1)" width="256" height="256" loading="lazy"></p>
<h2 id="heading-15-tools">15. Tools</h2>
<h3 id="heading-react-14">React</h3>
<p>React is supported by multiple code editors. For instance, the code in React can be edited with <a target="_blank" href="https://www.sublimetext.com/">Sublime Text</a>, <a target="_blank" href="https://visualstudio.microsoft.com/">Visual Studio</a>, and <a target="_blank" href="https://atom.io/">Atom</a>. To bootstrap a project, you can use the Create React App (CLI) tool. In turn, server-side rendering is completed with the use of Next.js framework.</p>
<p>To test the entire app written in React, you would need multiple tools. For instance, <a target="_blank" href="https://github.com/airbnb/enzyme">Enzyme</a> for component testing, <a target="_blank" href="https://jestjs.io/">Jest</a> for testing JS code, React-unit for unit testing and so on. To debug the app in the development mode, you can use a browser extension React Dev Tools.</p>
<p>Another interesting tool is <a target="_blank" href="https://github.com/facebook/react-360">React 360</a>, which is a library used for creating AR and VR applications.</p>
<h3 id="heading-angular-14">Angular</h3>
<p>Similarly to React, Angular is supported by a variety of code editing tools. For example, you may work with such code editors as <a target="_blank" href="http://www.aptana.com/">Aptana</a>, <a target="_blank" href="https://www.sublimetext.com/">Sublime Text</a>, and <a target="_blank" href="https://visualstudio.microsoft.com/">Visual Studio</a>. A project can be promptly set up with <a target="_blank" href="https://cli.angular.io/">Angular CLI</a>. Server-side rendering is completed with the help of <a target="_blank" href="https://github.com/angular/universal">Angular Universal</a>.</p>
<p>Unlike React, Angular can be fully tested with a single tool. For the end-to-end testing in Angular, the platforms are <a target="_blank" href="https://jasmine.github.io/2.0/introduction.html">Jasmine</a>, <a target="_blank" href="http://www.protractortest.org/#/">Protractor</a>, and <a target="_blank" href="https://karma-runner.github.io/latest/index.html">Karma</a>. Another tool that debugs the app in the development mode is a browser extension <a target="_blank" href="https://augury.rangle.io/">Augury</a>.</p>
<h2 id="heading-to-wrap-up">To Wrap Up</h2>
<p><strong>Angular</strong> is a full-fledged mobile and web development framework. <strong>React</strong> is a framework only for UI development, which can be turned into a full-fledged solution with the help of additional libraries. </p>
<p>React seems simpler at first sight, and it takes less time to start working on a React project. However, that simplicity as the main advantage of React is neutralized because you have to learn to work with additional JavaScript frameworks and tools. </p>
<p>Angular itself is more complex and takes quite some time to master. Yet, it is a powerful tool that offers a holistic web development experience, and once you learn how to work with it, you reap the fruits. </p>
<p><strong>There is no better framework. Both are updated continuously to keep up with the competitor</strong>. For instance, while React was believed to win because of its virtual DOM, Angular equaled the score by implementing change detection. While Angular was considered to be winning because of being developed by such an authoritative company as Google, the immense devoted React community fully compensated for Google's reputation and made React similar to Angular. </p>
<p><strong>In the end, React vs Angular is all a matter of personal preference, a matter of skills and habits</strong>. As a beginner in programming, you would probably benefit more from starting with React. As an experienced developer, you just keep working with what you know better. </p>
<p>Do not forget to challenge yourself and start learning a new framework, React or Angular. As a Project Manager or a business owner outsourcing developers, you should talk to your web development team and together choose the framework that suits all of you best, whether it be Angular or React.</p>
<h2 id="heading-do-you-have-an-idea-for-either-an-angular-or-react-project">Do you have an idea for either an Angular or React project?</h2>
<p>My company KeenEthics is experienced in <a target="_blank" href="https://keenethics.com/tech-front-end-react">react development</a>, and we, also, provide outstanding <a target="_blank" href="https://keenethics.com/tech-front-end-angular">agularjs developers</a> for your projects. In case you need the following services, feel free to <a target="_blank" href="https://keenethics.com/contacts">get in touch</a><em>.</em></p>
<p>If you have enjoyed the article, you should definitely read another wonderful comparison of 2 JS frameworks: <a target="_blank" href="https://keenethics.com/blog/react-vs-svelte-how-to-build-messaging-components">React vs Svelte: How to Build Messaging Components</a>.</p>
<h2 id="heading-ps">P.S.</h2>
<p>I would like to say thank you to everyone who contributed to this article including Sergey Gornostaev and Volodya Andrushchak, full-stack software developers @ KeenEthics.</p>
<p>The original article posted on KeenEthics blog can be found here: <a target="_blank" href="https://keenethics.com/blog/angular-vs-react-what-to-choose-for-your-app">Angular vs React: Which One to Choose for Your App</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What’s new in Angular 7.0 and how you can upgrade ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction Angular has released its latest version, Angular 7.0. In this article, we will explore the following points: What is new in Angular 7.0 Creating your first Angular 7.0 application using Angular CLI How to update your exi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/whats-new-in-angular-7-0-and-how-to-upgrade-f2ed22a79e28/</link>
                <guid isPermaLink="false">66d45dd155db48792eed3f2d</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 02 Nov 2018 15:16:46 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*TzObK_L_fue2CAxYOG-CnA.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h3 id="heading-introduction">Introduction</h3>
<p>Angular has released its latest version, Angular 7.0. In this article, we will explore the following points:</p>
<ul>
<li>What is new in Angular 7.0</li>
<li>Creating your first Angular 7.0 application using Angular CLI</li>
<li>How to update your existing Angular application to Angular 7.0</li>
</ul>
<h3 id="heading-whats-new-in-angular-70">What’s new in Angular 7.0?</h3>
<ol>
<li>While creating a new Angular application, the Angular CLI will prompt the user to select if they want to add features like Angular routing or the format of the stylesheet they want to use in their application</li>
<li>Angular 7.0 applications will use the Bundle Budget feature of Angular CLI. This will warn developers if the application bundle size exceeds the predefined limit. The default value for the warning is set to 2MB, and for errors it is 5MB. This value is configurable and can be changed from the <code>angular.json</code> file. This feature enhances the application’s performance considerably.</li>
<li><p>The Component Dev Kit (CDK) of Angular Material also receives some new features as part of this update. The two newly added feature of the CDK are:</p>
</li>
<li><p><strong>Virtual Scrolling</strong> If you are trying to load a large list of elements, then it can affect the application’s performance. The <code>&lt;cdk-virtual-scroll-viewport&gt;</code> tag can be used to load only the visible part of the list on the screen. It will render only the items that can fit on the screen. When a user scrolls through the list then the DOM will load and unload the elements dynamically based on the display size. This feature is not to be confused with infinite scrolling which is altogether a different strategy to load elements. You can read more about Virtual Scrolling <a target="_blank" href="https://material.angular.io/cdk/scrolling/overview">here</a>.</p>
</li>
<li><p><strong>Drag and Drop</strong><br>We can easily add the drag and drop feature to an item. It supports features such as free dragging of an element, reordering items of a list, moving items between list, animation, adding a custom drag handle, and restricted dragging along X or Y axis. You can read more about Drag and Drop <a target="_blank" href="https://material.angular.io/cdk/drag-drop/overview">here</a>.</p>
</li>
<li><p>The <code>mat-form-field</code> will now support the use of the native select element. This will provide enhanced performance and usability to the application. Read more about this feature <a target="_blank" href="https://material.angular.io/components/select/overview">here</a>.</p>
</li>
<li><p>Angular 7.0 has updated its dependencies to support Typescript 3.1, RxJS 6.3 and Node 10.</p>
</li>
</ol>
<p>Now we will proceed to create our first Angular 7 application.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>Install the latest version of Node.js from <a target="_blank" href="https://nodejs.org/en/download/">here</a></li>
<li>Install Visual Studio Code from <a target="_blank" href="https://code.visualstudio.com/">here</a></li>
</ul>
<p>Installing Node.js will also install npm on your machine. After installing Node.js, open the command prompt. Run the following set of commands to check the version of node and npm installed on your machine.</p>
<ul>
<li>node -v</li>
<li>npm -v</li>
</ul>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aMRrmSzH02XbSjMH7iLL9dvL2Rwr5XfDmZt2" alt="Image" width="640" height="378" loading="lazy"></p>
<h3 id="heading-installing-angular-cli"><strong>Installing Angular CLI</strong></h3>
<p>Angular CLI is the Command Line interface for Angular. It helps us to initialize, develop and maintain Angular applications easily.</p>
<p>To install Angular CLI, run the following command in the command window:</p>
<pre><code class="lang-bash">npm i -g @angular/cli
</code></pre>
<p>This will install Angular CLI 7.0 globally in your machine. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/8NjtUfzQgZ5lz5xVnOzj3lrK3NGmVmGgmnYx" alt="Image" width="650" height="234" loading="lazy"></p>
<p>To check the version of angular CLI installed in your machine, run the following command:</p>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0XwEnfOjRufctv0XNKSSLF2eDeClji0XyNnS" alt="Image" width="578" height="500" loading="lazy"></p>
<h3 id="heading-create-the-angular-7-app"><strong>Create the Angular 7 app</strong></h3>
<p>Open Visual Studio Code and navigate to <code>View &gt;&gt; Te</code>rminal. This will open the VS code terminal window. Alternatively, you can also use the keyboard sho<code>rtcut</code> ctrl+` to open the terminal window.</p>
<p>Type the following sequence of commands in the terminal window. These commands will create a directory named “ng7Demo”. Then create an Angular application with the name “ng7App” inside that directory.</p>
<ul>
<li>mkdir ng7Demo</li>
<li>cd ng7Demo</li>
<li>ng new ng7App</li>
</ul>
<p>As you run the ng new command, the Angular CLI will ask you to make selections in the following two options:</p>
<ol>
<li>Would you like to add Angular routing? (y/N)</li>
<li>Which stylesheet format would you like to use?</li>
</ol>
<p>Once you select the options and hit enter, the Angular 7.0 application will be created.</p>
<p>Refer to the below Gif for better understanding.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/SSJPhveMoVdyPvtAq5QrSiiHSdXqH7mH8djN" alt="Image" width="650" height="393" loading="lazy"></p>
<p>Once the application is created successfully, run the following command to open the project:</p>
<ul>
<li>code .</li>
</ul>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ir01hAZ0pkSePN0SX3A51Ce7QR11SPt7lGcs" alt="Image" width="488" height="153" loading="lazy"></p>
<p>This will open the code file of our application in a new VS Code window. You can see the following file structure in Solution Explorer.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2FThBN1bRwDkeqIXvqgAG6A86Kbs5eZjMuXD" alt="Image" width="310" height="611" loading="lazy"></p>
<p>Open the package.json file and you can observe that we have the latest Angular 7.0.0 packages installed in our project.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"ng7-app"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"0.0.0"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"ng"</span>: <span class="hljs-string">"ng"</span>,
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"ng serve"</span>,
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"ng build"</span>,
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"ng test"</span>,
    <span class="hljs-attr">"lint"</span>: <span class="hljs-string">"ng lint"</span>,
    <span class="hljs-attr">"e2e"</span>: <span class="hljs-string">"ng e2e"</span>
  },
  <span class="hljs-attr">"private"</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"@angular/animations"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/common"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/compiler"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/core"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/forms"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/http"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/platform-browser"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/platform-browser-dynamic"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/router"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"core-js"</span>: <span class="hljs-string">"^2.5.4"</span>,
    <span class="hljs-attr">"rxjs"</span>: <span class="hljs-string">"~6.3.3"</span>,
    <span class="hljs-attr">"zone.js"</span>: <span class="hljs-string">"~0.8.26"</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"@angular-devkit/build-angular"</span>: <span class="hljs-string">"~0.10.0"</span>,
    <span class="hljs-attr">"@angular/cli"</span>: <span class="hljs-string">"~7.0.1"</span>,
    <span class="hljs-attr">"@angular/compiler-cli"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@angular/language-service"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"@types/node"</span>: <span class="hljs-string">"~8.9.4"</span>,
    <span class="hljs-attr">"@types/jasmine"</span>: <span class="hljs-string">"~2.8.8"</span>,
    <span class="hljs-attr">"@types/jasminewd2"</span>: <span class="hljs-string">"~2.0.3"</span>,
    <span class="hljs-attr">"codelyzer"</span>: <span class="hljs-string">"~4.5.0"</span>,
    <span class="hljs-attr">"jasmine-core"</span>: <span class="hljs-string">"~2.99.1"</span>,
    <span class="hljs-attr">"jasmine-spec-reporter"</span>: <span class="hljs-string">"~4.2.1"</span>,
    <span class="hljs-attr">"karma"</span>: <span class="hljs-string">"~3.0.0"</span>,
    <span class="hljs-attr">"karma-chrome-launcher"</span>: <span class="hljs-string">"~2.2.0"</span>,
    <span class="hljs-attr">"karma-coverage-istanbul-reporter"</span>: <span class="hljs-string">"~2.0.1"</span>,
    <span class="hljs-attr">"karma-jasmine"</span>: <span class="hljs-string">"~1.1.2"</span>,
    <span class="hljs-attr">"karma-jasmine-html-reporter"</span>: <span class="hljs-string">"^0.2.2"</span>,
    <span class="hljs-attr">"protractor"</span>: <span class="hljs-string">"~5.4.0"</span>,
    <span class="hljs-attr">"ts-node"</span>: <span class="hljs-string">"~7.0.0"</span>,
    <span class="hljs-attr">"tslint"</span>: <span class="hljs-string">"~5.11.0"</span>,
    <span class="hljs-attr">"typescript"</span>: <span class="hljs-string">"~3.1.1"</span>
  }
}
</code></pre>
<h3 id="heading-execution-demo">Execution Demo</h3>
<p>The name of our Angular application is <em>ng7App</em> which is inside the <em>ng7Demo</em> directory.</p>
<p>So, we will first navigate to our application using the below commands.</p>
<ul>
<li>cd ng7Demo</li>
<li>cd ng7App</li>
</ul>
<p>Now, we use the following command to start the web server.</p>
<ul>
<li>ng serve</li>
</ul>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/I9P20l7DxHfFzooUz8JWUhU7bFc4sJUxJE3C" alt="Image" width="650" height="240" loading="lazy"></p>
<p>After running this command, you can see that it is asking to open <code>_http://localhost:4200_</code> in your browser. So, open any browser on your machine and navigate to this URL. Now, you can see the following page.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/lN5VU04tLKYoxfQskGaAnPXuSAVkdm94l0TS" alt="Image" width="650" height="455" loading="lazy"></p>
<h3 id="heading-how-to-upgrade-to-angular-7">How to upgrade to Angular 7</h3>
<p>The angular team has provided an Angular Update Guide to ensure the smooth upgrade of angular versions. Navigate to <a target="_blank" href="https://update.angular.io/">https://update.angular.io/</a> to access it. It is a self-explanatory and easy to use application. It will show you the steps that you need to follow before updating, during the update and after the update. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/DQoXJZqvZgwkWCf0zbqH8S-0V7M9oqWmIDdP" alt="Image" width="650" height="486" loading="lazy"></p>
<p>If you want to update your application from Angular 6 to Angular 7 then run the following command in the project folder:</p>
<pre><code class="lang-bash">ng update @angular/cli @angular/core
</code></pre>
<h3 id="heading-conclusion">Conclusion</h3>
<p>We have learned about the new features of Angular 7.0. We also installed Angular CLI 7.0. To create and execute an Angular 7.0 app we have used Angular CLI and VS Code. We also explored the method to upgrade an existing application to Angular 7.0.</p>
<h3 id="heading-see-also">See Also</h3>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/getting-started-with-angular-6-0/">Getting Started With Angular 6.0</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/understanding-angular-6-animations/">Understanding Angular 6 Animations</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/getting-started-with-angular-5-using-visual-studio-code/">Getting Started With Angular 5 Using Visual Studio Code</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/crud-operations-asp-net-core-using-angular-5-ado-net/">CRUD Operations With ASP.NET Core Using Angular 5 And ADO.NET</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/asp-net-core-crud-using-angular-5-and-entity-framework-core/">ASP.NET Core — CRUD Using Angular 5 And Entity Framework Core</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/asp-net-core-using-highcharts-with-angular-5/">ASP.NET Core — Using Highcharts With Angular 5</a></li>
</ul>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Angular in this free 33-part course by Angular-expert Dan Wahlin ]]>
                </title>
                <description>
                    <![CDATA[ By Per Harald Borgen According to the Stack Overflow developer survey 2018, Angular is one of the most popular frameworks/libraries among professional developers. So learning it increases your chances of getting a job as a web developer significantly... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/want-to-learn-angular-heres-our-free-33-part-course-by-dan-wahlin-fc2ff27ab451/</link>
                <guid isPermaLink="false">66d85264c1231da2ef2b5aa7</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 16 Oct 2018 05:34:57 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*SaVwtG8cWgCh1WFYsIa2Fw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Per Harald Borgen</p>
<p>According to the <a target="_blank" href="https://insights.stackoverflow.com/survey/2018/#most-popular-technologies">Stack Overflow developer survey 2018</a><strong>,</strong> Angular is one of the most popular frameworks/libraries among professional developers. So learning it increases your chances of getting a job as a web developer significantly.</p>
<p>That’s why we’ve teamed up with one of the most renowned experts on the framework, and created a <a target="_blank" href="https://scrimba.com/g/gyourfirstangularapp?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=gyourfirstangularapp_launch_article">free Angular course</a> at Scrimba.</p>
<p>Instructor <a target="_blank" href="https://twitter.com/DanWahlin">Dan Wahlin</a> is a Google Developer Expert who’s provided training, architecture, and development services for some of the biggest corporations in the industry and created some of the most popular training courses on Udemy and Pluralsight. He’s also a regular speaker at developer conferences around the world.</p>
<p><a target="_blank" href="https://scrimba.com/g/gyourfirstangularapp?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=gyourfirstangularapp_launch_article">In this course</a>, Dan guides you through creating your very first Angular app using TypeScript. By completing the course you’ll add valuable skills to your toolbelt.</p>
<p>Now let’s have a look at how the course is structured!</p>
<h3 id="heading-part-1-course-overview">Part #1: Course overview</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*mHUNNtNB1aF6s1juYuJ7Jw.png" alt="Image" width="800" height="374" loading="lazy"></p>
<p>In the introductory video, Dan gives an overview of the course, key aspects of Angular, and how the course is laid out. He also tells you a little bit about his background, so that you are familiar with him before jumping into the code of your new app.</p>
<h3 id="heading-part-2-application-overview">Part #2: Application Overview</h3>
<p>In this part, Dan gives us a glimpse into the app we’re going to build. It is designed to allow us to focus on the key building blocks of Angular. By creating an app to display customer data and their orders, we will hone in on the key aspects of Angular, such as Components, Modules, Services and Routing. Also, during the course, we will learn about great features every app has, like sorting and filtering.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*_bYYJCud9vhxaSSvKmqH6Q.png" alt="Image" width="800" height="524" loading="lazy"></p>
<h3 id="heading-part-3-angular-cli">Part #3: Angular CLI</h3>
<p>In this part we learn the basics of using the Angular CLI (command-line interface) tool and walk through the basic commands:</p>
<pre><code class="lang-sh">ng --version  
ng --<span class="hljs-built_in">help</span>  
ng new my-app-name  
ng generate [component | directive | pipe | service | class | interface | enum | guard]  
ng build   
ng serve  
ng lint   
ng tests
</code></pre>
<p>For example, <code>ng --new my-app-name</code> will create a new blank Angular app for us and we can use <code>ng -generate</code> to create parts of our app.</p>
<p><code>ng build</code> will build everything for us, and <code>ng serve -o</code> will even start a development server as well as open a browser window for us to view our app in.</p>
<h3 id="heading-part-4-project-files-overview">Part #4: Project Files Overview</h3>
<p>In this video of the course, Dan gives a basic overview of the CLI command for generating a blank Angular app and gives a quick overview of the configuration files like <code>tslint</code>, <code>tsconfig</code> and <code>protractor</code> in our app folder.</p>
<h3 id="heading-part-5-the-big-picture">Part #5: The Big Picture</h3>
<p>Here we learn a useful abstraction that Components are similar to Lego blocks — we build up components and then use them to stick together to make an app. We also get a quick refresher on JavaScript language family and learn where TypeScripts fits in.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*s2TcwSmQM7_BAA25NC3lVQ.png" alt="Image" width="800" height="442" loading="lazy"></p>
<p>Dan gives us a good mental model to use for thinking about our code while working with Angular so we can imagine where it all fits in.</p>
<h3 id="heading-part-6-components-amp-modules-overview">Part #6: Components &amp; Modules — Overview</h3>
<p>Not abstracted away, the diagram for Angular code might look like this.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*OTT4yeJg6630S2I43WRGxg.png" alt="Image" width="800" height="449" loading="lazy"></p>
<p>Components are made up of code and HTML template and it can have a selector, so we can call it in our HTML.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">appcomponent</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">appcomponent</span>&gt;</span>
</code></pre>
<p>Every Component consists of:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*-12cVJ5V8OG1SBWI4hraSg.png" alt="Image" width="800" height="338" loading="lazy"></p>
<p>Dan then explains what each of the parts is and how they fit in the Angular way of developing components. One of the great things about Angular is that it’s very predictable. Once you learn how to create your first component you’re well on your way to creating additional components.</p>
<h3 id="heading-part-7-components-amp-modules-app-component">Part #7: Components &amp; Modules — App Component</h3>
<p>In this part of the course, we look at a <code>HelloWorld</code> component.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*UYiWpdm6Aqf4PmcbHdSXGg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*wproObAyLBo-EOBM-r3P8A.png" alt="Image" width="600" height="465" loading="lazy"></p>
<p>Dan breaks down every aspect of the component for us and explains how it’s used and how our component is processed by Angular, how it’s added to <code>app.module</code> and ultimately how it’s rendered on our screens.</p>
<p>We learn that <code>selector: 'app-root'</code> is what allows us to later call the component from our HTML using <code>&lt;app-root&gt;&lt;/app-root&gt;</code></p>
<p>We also have a sneak peek at data binding which we’ll learn more about in later chapters.</p>
<h3 id="heading-part-8-components-amp-modules-app-module">Part #8: Components &amp; Modules — App Module</h3>
<p>In this screencast, we spend more time learning about the inner workings of <code>app.module</code> which we touched on in the previous cast and learn about <code>NgModule</code> and <code>BrowserModule</code>.</p>
<h3 id="heading-part-9-components-amp-modules-adding-a-customers-component">Part #9: Components &amp; Modules — Adding a Customers Component</h3>
<p>In this cast, Dan gives us some tips on creating components using the CLI and then shows how to create components manually. We learn how to structure a component further expanding on our knowledge from Part #6.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*C2YJ7m1pbHjXSHC0Fv0baQ.png" alt="Image" width="800" height="524" loading="lazy"></p>
<p>Now we bring in some data to mimic our API and learn about how modules help us keep our code organized and easier to re-use.</p>
<h3 id="heading-part-10-components-amp-modules-adding-a-customers-list-component">Part #10: Components &amp; Modules — Adding a Customers List component</h3>
<p>In this part, we create a <code>customers-list.component</code> which is an HTML table to display our list of customers. We quickly register in <code>customers.module</code> and use the<code>&lt;app-customers-list&gt;&lt;/app-customers-list&gt;</code> selector to display our empty table.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*CeqVsl_JlKtnPXzgSVismQ.png" alt="Image" width="800" height="614" loading="lazy"></p>
<p>Next step would be to populate the table with some data.</p>
<h3 id="heading-part-11-components-amp-modules-adding-a-filter-textbox-component">Part #11: Components &amp; Modules — Adding a Filter Textbox Component</h3>
<p>Before we add some data to our table, Dan shows us how to add a <code>filter-textbox.component</code> to our table and we reinforce the Angular way of creating a component, registering it in a module and using it in our HTML with selectors.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*b9SgU3SuhQINc87r56DDwg.png" alt="Image" width="800" height="306" loading="lazy"></p>
<h3 id="heading-part-12-components-amp-modules-adding-a-shared-module-and-interfaces">Part #12: Components &amp; Modules — Adding a Shared Module and Interfaces</h3>
<p>In this section, Dan talks about using <code>shared.module</code> — a module where we put components or other features that we want to share throughout our app, not just in <code>customers</code>.</p>
<p>We also have a quick refresher on TypeScript interfaces and how they can be used in Angular applications to provide better code help and enhance productivity.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> ICustomer {  
    id: <span class="hljs-built_in">number</span>;  
    name: <span class="hljs-built_in">string</span>;  
    city: <span class="hljs-built_in">string</span>;  
    orderTotal?: <span class="hljs-built_in">number</span>;  
    customerSince: <span class="hljs-built_in">any</span>;  
}
</code></pre>
<h3 id="heading-part-13-data-binding-data-binding-overview">Part #13: Data Binding — Data Binding Overview</h3>
<p>In this chapter we learn about data binding, learn a few techniques and see how to add data binding to our application.</p>
<p>We usually bind data in our templates. Data binding comes into play when a component gets our data and hooks it into a template. We can get data into a template using <code>Property Binding</code>, and handle user events and get data out of a template using <code>Event Binding</code>. Angular provides a robust and clean way to add data binding in templates that’s quick and easy to remember.</p>
<p>Dan provides us with a handy slide to remember syntax required…</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Ft7Mj_TaGsUJ4GRdmJNGPQ.png" alt="Image" width="800" height="445" loading="lazy"></p>
<p>…and some on Angular directives, for example, <code>ngFor</code>, used to loop through items in a collection and get some properties from the items, and <code>ngIf</code> to add and remove an HTML element from the DOM.</p>
<h3 id="heading-part-14-data-binding-getting-started-with-data-binding">Part #14: Data Binding — Getting Started with Data Binding</h3>
<p>In this cast we play around with <code>Property Binding</code> and <code>Event Binding</code> to better understand how they work in Angular, using the knowledge from the previous chapter.</p>
<p>Dan shows how we can use the <code>[hidden]</code> property to display an <code>h1</code> element dynamically:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> [<span class="hljs-attr">hidden</span>]=<span class="hljs-string">"!isVisible"</span>&gt;</span>{{ title }}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
</code></pre>
<p>And to bind DOM events such as click:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"changeVisibility()"</span>&gt;</span>Show/Hide<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<h3 id="heading-part-15-data-binding-directives-and-interpolation">Part #15: Data Binding — Directives and Interpolation</h3>
<p>Here we have a look at Interpolation. The rationale is that we need to get data from each customer to generate a table row in a table from Part #10.</p>
<p>This is the part when things start coming together: we use directive <code>ngFor</code> to loop through each customer in <code>filteredCustomers</code> and interpolate data from a customer into a table row. We learn a few tricks about rendering data conditionally using <code>ngIf</code>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*xMU7cyyy5ooxLJPBct0PEw.png" alt="Image" width="800" height="439" loading="lazy"></p>
<p>In the end we get a pretty looking table!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*BO_isrPNvKI9u80bXLOnyA.png" alt="Image" width="800" height="436" loading="lazy"></p>
<h3 id="heading-part-16-data-binding-event-binding">Part #16: Data Binding — Event Binding</h3>
<p><code>Event Binding</code> is crucial when we need to handle an event, like a mouse move or a click. In this screencast, Dan guides us through adding functionality to sort the data in our table. We will start on it in this chapter and finish it when we get to the Services part of our course.</p>
<p>We create a placeholder event handler in our <code>customer-list.component</code>:</p>
<pre><code class="lang-ts">sort(prop: <span class="hljs-built_in">string</span>) {  
     <span class="hljs-comment">// A sorter service will handle the sorting  </span>
}
</code></pre>
<p>Add binding in <code>customers-list.component.html</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>  
    <span class="hljs-tag">&lt;<span class="hljs-name">th</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"sort('name')"</span>&gt;</span>Name<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>  
    <span class="hljs-tag">&lt;<span class="hljs-name">th</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"sort('city')"</span>&gt;</span>City<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>  
    <span class="hljs-tag">&lt;<span class="hljs-name">th</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"sort('orderTotal')"</span>&gt;</span>Order Total<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>  
<span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
</code></pre>
<h3 id="heading-part-17-data-binding-input-properties">Part #17: Data Binding — Input Properties</h3>
<p>We have some data in a <code>people</code> array in our <code>customers.component</code> and we need to pass it into our <code>filteredCustomers</code> array in <code>customers-list.component</code>, effectively passing data from a parent component to a child.</p>
<p>For that we will use Angular’s <code>Input</code> property which relies on a decorator named Input():</p>
<pre><code class="lang-ts"><span class="hljs-meta">@Input</span>() get customers(): ICustomer[] {  
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>._customers  
}

set customers(value: ICustomer[]) {  
     <span class="hljs-keyword">if</span> (value) {  
     <span class="hljs-built_in">this</span>.filteredCustomers = <span class="hljs-built_in">this</span>._customers = value;  
     <span class="hljs-built_in">this</span>.calculateOrders();  
     }  
}
</code></pre>
<p>And bind to it in our parent component template to pass data from parent to child (app-customers-list in this case):</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">app-customers-list</span> [<span class="hljs-attr">customers</span>]=<span class="hljs-string">"people"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-customers-list</span>&gt;</span>
</code></pre>
<h3 id="heading-part-18-data-binding-working-with-pipes">Part #18: Data Binding — Working with Pipes</h3>
<p>Wow! We’ve done quite well so far!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*v51xQi5Ard63tF0-0dd-2Q.png" alt="Image" width="800" height="606" loading="lazy"></p>
<p>There are a few things which might look a bit odd — “john” is lowercase and we have no “$” symbol to display currency in which we have our orders.</p>
<p>This is really the way we have our data, so we could just go and update it directly, or we can use a built-in Angular feature called Pipes to update it for us!</p>
<p>Some of the simplest pipes look like this:</p>
<pre><code class="lang-ts">{{ cust.name | uppercase }} <span class="hljs-comment">// renders JOHN  </span>
{{ cust.name | titlecase }} <span class="hljs-comment">// renders John</span>
</code></pre>
<p>But sometimes you might want to have your own custom pipe and Dan shows us how to build a custom <code>capitalize</code> pipe (note that Angular includes one called <code>titlecase</code> — but we’re learning here!) and how to wire it up to use in our application.</p>
<h3 id="heading-part-19-data-binding-adding-filtering">Part #19: Data Binding — Adding Filtering</h3>
<p>In this cast, Dan walks us through adding functionality to our <code>filter-textbox.component</code> from Part #11</p>
<p>We learn more about Angular <code>Output</code> and <code>EventEmitter</code> properties, create our filter event handler and bind it to our filter textbox:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">filter-textbox</span> (<span class="hljs-attr">changed</span>)=<span class="hljs-string">"filter($event)"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">filter-textbox</span>&gt;</span>
</code></pre>
<p>And there we go, we can now filter on our customers’ names!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*8oM5-CM9n7Ic46M4l4IS8w.png" alt="Image" width="800" height="567" loading="lazy"></p>
<h3 id="heading-part-20-services-and-http-services-overview">Part #20: Services and Http — Services Overview</h3>
<p>In this chapter, we look at Angular Services. One of Angular’s strong points is that it’s a complete framework that provides built-in support for managing state and objects through services. We saw services in the diagram earlier. Since we don’t want components to know how to do too much, we’ll rely on services to communicate with the server, perform client-side validation or calculations, etc.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*OTT4yeJg6630S2I43WRGxg.png" alt="Image" width="800" height="449" loading="lazy"></p>
<p>Components should focus on presenting data and handling user events. When additional functionality needs to be performed they should delegate to services to provide for a more maintainable application and better code reuse.</p>
<p>That’s exactly what Service does — some reusable functionality for the app which should not be of any component’s concern.</p>
<p>Luckily, Dan get us covered with a handy slide to keep in mind.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Dzy9aUGQUu_RXuQ3Wx6RDg.png" alt="Image" width="800" height="443" loading="lazy"></p>
<h3 id="heading-part-21-services-and-http-creating-and-providing-a-service">Part #21: Services and Http — Creating and Providing a Service</h3>
<p>From a chapter earlier we have seen an import of <code>Injectible</code> which is a decorator that allows for something called Dependency Injection or DI for short (another powerful feature built-into Angular).</p>
<p>We’ll use DI to access an <code>HttpClient</code> service which we will use to communicate with a RESTful service. We will be adding HttpClient to a constructor of our <code>data.service</code> and <code>@Injectible()</code> decorator will make DI possible.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*6sbs_J-0b6_SH1XqpB7k-g.png" alt="Image" width="800" height="510" loading="lazy"></p>
<h3 id="heading-part-22-services-and-http-calling-the-server-with-httpclient">Part #22: Services and Http — Calling the Server with HttpClient</h3>
<p>In this cast, Dan introduces Observables from <code>RxJS</code> — reactive extensions for JavaScript, which is not a part of Angular but is included in all Angular projects by default.</p>
<p>We will be using Observables to deal with asynchronous code. In a nutshell, it allows us to start an operation and then subscribe to data that is returned. Once the data comes back from the server, the subscription ends and we can unsubscribe.</p>
<p>Dan discusses the necessary code to call the server and then subscribe to the response using RxJS piping and operators.</p>
<p>Here’s an example of how we can get Orders:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*LZp4nkmFIm4MGJAhQFU4sA.png" alt="Image" width="800" height="220" loading="lazy"></p>
<h3 id="heading-part-23-services-and-http-injecting-a-service-into-a-component">Part #23: Services and Http — Injecting a Service into a Component</h3>
<p>Now that we have a way to get the data, we need to inject the service into one of our components. We can now change <code>this.people</code> in <code>customers.component</code> from being hardcoded to call a service and get data that way.</p>
<p>We need to bring our <code>data.service</code> to <code>app.module</code> and then in <code>customers.component</code> we can:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { DataService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../core/data.service'</span>;
</code></pre>
<p>Now we can inject our <code>DataService</code> straight into our component’s constructor:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> dataService: DataService</span>) {}
</code></pre>
<h3 id="heading-part-24-services-and-http-subscribing-to-an-observable">Part #24: Services and Http — Subscribing to an Observable</h3>
<p>Now we can use our injected <code>dataService</code>, call <code>getCustomers()</code> and subscribe to our <code>Observable&lt;ICustomer[]&gt;</code> to get the data.</p>
<p>Which is pretty straightforward:</p>
<pre><code class="lang-ts">ngOnInit() {  
    <span class="hljs-built_in">this</span>.title = <span class="hljs-string">'Customers'</span>;  
    <span class="hljs-built_in">this</span>.dataService.getCustomers()  
        .subscribe(<span class="hljs-function">(<span class="hljs-params">customers: ICustomer[]</span>) =&gt;</span>  
        <span class="hljs-built_in">this</span>.people = customers);
</code></pre>
<p>Now we have one last service to look at — <code>SorterService</code></p>
<h3 id="heading-part-25-services-and-http-using-a-sorterservice">Part #25: Services and Http — Using a SorterService</h3>
<p>Currently, if we click on our column headers nothing would happen.</p>
<p>Dan handily provided a prewritten service for us, which we can use, so in this chapter, we will practice bringing in service into our components, in this case, <code>customers-list.component</code>.</p>
<p>As with other services we need to import it:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SorterService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../core/sorter.service'</span>;
</code></pre>
<p>Then we inject <code>SorterService</code> into our constructor:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> sorterService: SorterService</span>) {}
</code></pre>
<p>Dependency injection makes it extremely easy to access reusable code such as the sorter or data services.</p>
<p>Lastly, we use it in our <code>sort()</code> function:</p>
<pre><code class="lang-ts">sort(prop: <span class="hljs-built_in">string</span>) {  
    <span class="hljs-built_in">this</span>.sorterService.sort(<span class="hljs-built_in">this</span>.filteredCustomers, prop);  
}
</code></pre>
<h3 id="heading-part-26-routing-routing-overview">Part #26: Routing — Routing Overview</h3>
<p>This chapter will introduce Routing, which is an essential part of modern applications. As you’re building an Angular app, you want to show different components as the user interacts with it. In our case, when a user clicks on a Customer, we might want to show them Orders. Routing is one way to very neatly achieve this.</p>
<p>Routes are used to hook a specific URL to a component and in the next few chapters, we will be focusing on the top part of our Angular diagram.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*og4k_DGep_esiA5I1ALgzg.png" alt="Image" width="800" height="395" loading="lazy"></p>
<p>A super great part of routing is that if a user bookmarks a specific URL, it will bring them back to a specific component and there is no need for complex show/hide logic.</p>
<h3 id="heading-part-27-routing-creating-a-routing-module-with-routes">Part #27: Routing — Creating a Routing Module with Routes</h3>
<p>We begin with a familiar module-container routine and create a <code>app-routing.module</code>.</p>
<p>A main focus of the <code>app-routing.module</code> is to define the routes in an array:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> routes: Routes = [  
    { path: <span class="hljs-string">''</span>, pathMatch: <span class="hljs-string">'full'</span>, redirectTo: <span class="hljs-string">'/customers'</span>},  
    { path: <span class="hljs-string">'**'</span>, redirectTo: <span class="hljs-string">'/customers'</span> }  
];
</code></pre>
<p>Three key properties of <code>routes</code> are:</p>
<ul>
<li><code>path</code> — where your user goes, so <code>path: ''</code> would be the root of your app. <code>path: '**'</code> is a wild card match. It is usually placed last and it’s there to cover cases for any route that is not specified in <code>routes</code></li>
<li><code>pathMatch</code> — how exactly should the route match for a specific component to be displayed</li>
<li><code>redirectTo</code> — when a path is matched, this is where we send the user. In our case, we send them to <code>/customers</code>.</li>
</ul>
<h3 id="heading-part-28-routing-using-router-outlet">Part #28: Routing — Using Router Outlet</h3>
<p>In order to use Routing in Angular in our <code>app.component</code> template we replace <code>&lt;app-customers&gt;&lt;/app-customers&gt;</code> with <code>&lt;router-outlet&gt;&lt;/router-outlet&gt;</code>. Ultimately, this is just a way to say: ‘Hey, this is where a component will go when we hit our route’.</p>
<p>When we hit a route, then a component associated with that route will magically appear in the place of <code>&lt;router-outlet&gt;&lt;/router-outlet&gt;</code>.</p>
<h3 id="heading-part-29-routing-adding-a-customers-routing-module-and-routes">Part #29: Routing — Adding a Customers Routing Module and Routes</h3>
<p>In this chapter, Dan brings all the things together and we connect a <code>/customer</code> route to <code>customers.component</code>.</p>
<p>First, we create a<code>customers-routing.module</code> and point our route from part #28 to <code>customers.component</code> like so:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> routes: Routes = [  
    { path: <span class="hljs-string">'customers'</span>, component: CustomersComponent }  
];
</code></pre>
<p>And now when we type “customers” <strong>in the Scrimba browser address bar</strong> we get our <code>customers.component</code>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*drUS_faas9AzJIvfW-EKxg.png" alt="Image" width="800" height="615" loading="lazy"></p>
<h3 id="heading-part-30-routing-adding-an-orders-component-with-routes">Part #30: Routing — Adding an Orders Component with Routes</h3>
<p>In this clip, we’re going to quickly review how we’ve done routing to display customers, and now it’s time for routing to display their orders.</p>
<p>There’s a little catch though. When we click on a customer we need to display order data related to that customer. So we need to pass some dynamic data into our routing.</p>
<p>We can achieve this by passing a <code>route parameter</code> in our <code>orders-routing.module</code> like so:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> routes: Routes = [  
    { path: <span class="hljs-string">'orders/:id'</span>, component: OrdersComponent}  
];
</code></pre>
<p>Note the <code>/:id</code> syntax. In routing the <code>:</code> symbol indicates that the value after it will be dynamically replaced and <code>id</code> is just a variable, so it can be anything like <code>:country</code> or <code>:book</code>.</p>
<h3 id="heading-part-31-routing-accessing-route-parameters">Part #31: Routing — Accessing Route Parameters</h3>
<p>In the previous screencast we saw how to create <code>orders/:id</code> route and now <code>orders.component</code> needs to somehow grab that <code>id</code> and display customer related orders. To do that we need to access the <code>id</code> route parameter.</p>
<p>One way of doing it would be:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">let</span> id = <span class="hljs-built_in">this</span>.route.paramMap.get(<span class="hljs-string">'id'</span>);
</code></pre>
<p>The benefit of this way is that we can subscribe to <code>paramMap</code> and get notified when any of the data in <code>id</code> changes. But we only need it once.</p>
<p>We can use <code>snapshot</code> for that:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">let</span> id = <span class="hljs-built_in">this</span>.route.snapshot.paramMap.get(<span class="hljs-string">'id'</span>)
</code></pre>
<p><code>snapshot</code> just takes a kind of an instant picture of your URL and gives it to you, which perfect as that’s what we need in this situation.</p>
<p>But now we have a problem. Our <code>id</code> is a string, but to get an order from our <code>DataService</code> it needs to be a number. We can convert it with <code>parseInt()</code>, but Dan teaches us a neat <code>+</code> trick:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">let</span> id = +<span class="hljs-built_in">this</span>.route.snapshot.paramMap.get(<span class="hljs-string">'id'</span>)
</code></pre>
<p>Now we can call <code>DataService</code> to get the order and render it to <code>orders.component</code>.</p>
<h3 id="heading-part-32-routing-linking-to-routes-with-the-routerlink-directive">Part #32: Routing — Linking to Routes with the routerLink Directive</h3>
<p>The last thing we want to do is to add a link on a customer’s name, so we can click it to see their orders.</p>
<p>In part #28 we’ve added <code>&lt;router-outlet&gt;&lt;/router-outlet</code> and now we just need to tell our app that we want to display <code>orders.component</code> when we navigate to <code>/orders/:id</code>.</p>
<p>We can do it by adding a link to our customer’s name in <code>customers-list.component.html</code> in a row where we’re mapping all the data to be displayed. We already have our customer object there, so we can just pass <code>id</code> to our route.</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">"['/orders', cust.id]"</span>&gt;</span>  
    {{ cust.name | capitalize }}  
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>Now we can see orders!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*M3o56Z9ikhkMt6tLbndzdQ.png" alt="Image" width="800" height="608" loading="lazy"></p>
<p>But hey, how do we get back? We could click ‘Back’ button on the browser, but it’s much nicer to have an app link for that, now that we know routing. Let’s add it to <code>customers-list.component.html</code> at the very bottom.</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">"/customers"</span>&gt;</span>View All Customers<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<h3 id="heading-part-33-course-summary">Part #33: Course Summary</h3>
<p>Very well done, we have our app now!</p>
<p>We can wrap up and have a quick recap of things done. Don’t forget to watch the actual screencast of the course, as Dan is a great teacher so you will have lots of fun following the process alongside him!</p>
<p>Thank you, Dan!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*TwvG-32iqImuHarf1HKUQg.png" alt="Image" width="800" height="502" loading="lazy"></p>
<p>If you’re interested in keeping up on front-end and back-end technologies make sure to <a target="_blank" href="https://twitter.com/danwahlin">follow Dan on Twitter</a>! </p>
<p>Happy coding!</p>
<hr>
<p>Thanks for reading! My name is Per Borgen, I'm the co-founder of <a target="_blank" href="https://scrimba.com">Scrimba</a> – the easiest way to learn to code. You should check out our <a target="_blank" href="https://scrimba.com/g/gresponsive?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=gyourfirstangularapp_launch_article">responsive web design bootcamp</a> if want to learn to build modern website on a professional level.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/bootcamp-banner.png" alt="Image" width="600" height="400" loading="lazy">
_<a target="_blank" href="https://scrimba.com/g/gresponsive?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=gyourfirstangularapp_launch_article">Click here to get to the advanced bootcamp.</a>_</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to use animation with Angular 6 ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction Animation is defined as the transition from an initial state to a final state. It is an integral part of any modern web application. Animation not only helps us create a great UI but it also makes the application interest... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-animation-with-angular-6-675b19bc3496/</link>
                <guid isPermaLink="false">66d45dc7680e33282da25e3f</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 04 Oct 2018 17:40:20 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*apXhEl5f3wwTKH4fQYMExA.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h3 id="heading-introduction">Introduction</h3>
<p>Animation is defined as the transition from an initial state to a final state. It is an integral part of any modern web application. Animation not only helps us create a great UI but it also makes the application interesting and fun to use. A well-structured animation keeps the user engaged with the application and enhances the user experience.</p>
<p>Angular allows us to create animations which provides us similar native performance as CSS animations. In this article, we will learn how we can create animation using Angular 6.</p>
<p>We will use Visual Studio Code for our demo.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>Install VS code and Angular CLI.</p>
<p>If you are new to Angular, then refer to my previous article <a target="_blank" href="http://ankitsharmablogs.com/getting-started-with-angular-6-0/">Getting Started With Angular 6.0</a> to set up the Angular 6 development environment on your machine.</p>
<h3 id="heading-source-code">Source Code</h3>
<p>Download the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/angular-6-animations">GitHub</a>.</p>
<h3 id="heading-understanding-angular-animation-states">Understanding Angular Animation States</h3>
<p>Animation involves transition from one state of an element to another state. Angular defines three different states for an element:</p>
<ol>
<li>Void state — represents the state of an element which is not part of the DOM. This state occurs when an element is created but not yet placed in the DOM or the element is removed from the DOM. This state is useful when we want to create animation while adding or removing an element from our DOM. To define this state in our code we use the keyword <code>void</code>.</li>
<li>The wildcard state — This is also known as the default state of the element. The styles defined for this state are applicable to the element regardless of its current animation state. To define this state in our code we use the <code>*</code> symbol.</li>
<li>Custom state — This is the custom state of the element and it needs to be defined explicitly in the code. To define this state in our code, we can use any custom name of our choice.</li>
</ol>
<h3 id="heading-animation-transition-timing">Animation Transition Timing</h3>
<p>To show the animation transition from one state to another, we define animation transition timing in our application.</p>
<p>Angular provides the following three timing properties:</p>
<h4 id="heading-duration">Duration</h4>
<p>This property represents the time our animation takes to complete from start (initial state) to finish (final state). We can define the duration of animation in the following three ways:</p>
<ul>
<li>Using an integer value to represent the time in milliseconds. E.g.- 500</li>
<li>Using a string value to represent the time in milliseconds. E.g. — ‘500ms’</li>
<li>Using a string value to represent the time in seconds. E.g. — ‘0.5s’</li>
</ul>
<h4 id="heading-delay">Delay</h4>
<p>This property represents the duration between the animation trigger and the beginning of the actual transition. This property also follows the same syntax as duration. To define the delay, we need to add the delay value after the duration value in a string format — ‘ Duration Delay’. Delay is an optional property.</p>
<p>For example:</p>
<ul>
<li>‘0.3s 500ms’. This means the transition will wait for 500ms and then run for 0.3s.</li>
</ul>
<h4 id="heading-easing">Easing</h4>
<p>This property represents how the animation accelerates or decelerates during its execution. We can define the easing by adding it as the third variable in the string after duration and delay. If the delay value is not present, then easing will be the second value. This is also an optional property.</p>
<p>For example:</p>
<ul>
<li>‘0.3s 500ms ease-in’ — This means the transition will wait for 500ms and then run for 0.3s (300ms) with ease-in effect.</li>
<li>‘300ms ease-out’. — This means the transition will run for 300ms (0.3s) with ease-out effect.</li>
</ul>
<h3 id="heading-creating-the-angular-6-application">Creating the Angular 6 application</h3>
<p>Open command prompt in your machine and execute the following set of commands:</p>
<ul>
<li>mkdir ngAnimationDemo</li>
<li>cd ngAnimationDemo</li>
<li>ng new ngAnimation</li>
</ul>
<p>These commands will create a directory with the name <code>ngAnimationDemo</code> and then create an Angular application with the name <code>ngAnimation</code> inside that directory.</p>
<p>Open the ngAnimation app using VS code. Now we will create our component.</p>
<p>Navigate to <code>View &gt;&gt; Integrated Te</code>rminal. This will open a terminal window in VS Code.</p>
<p>Execute the following command to create the component.</p>
<pre><code class="lang-bash">ng g c animationdemo
</code></pre>
<p>This will create our component <code>animationdemo</code> inside the <code>/src/app</code> folder.</p>
<p>To use Angular animation we need to import <code>BrowserAnimationsModule</code> which is an animation-specific module in our application. Open the app.module.ts file and include the import definition as shown below:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { BrowserAnimationsModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser/animations'</span>;
<span class="hljs-comment">// other import definitions</span>

<span class="hljs-meta">@NgModule</span>({ imports: [BrowserAnimationsModule <span class="hljs-comment">// other imports]})</span>
</code></pre>
<h4 id="heading-understanding-the-angular-animation-syntax"><strong>Understanding the Angular Animation Syntax</strong></h4>
<p>We will write our animation code inside the component’s metadata. The syntax for the animation is shown below:</p>
<pre><code class="lang-ts"><span class="hljs-meta">@Component</span>({
<span class="hljs-comment">// other component properties.</span>
  animations: [
    trigger(<span class="hljs-string">'triggerName'</span>), [
      state(<span class="hljs-string">'stateName'</span>, style())
      transition(<span class="hljs-string">'stateChangeExpression'</span>, [Animation Steps])
    ]
  ]
})
</code></pre>
<p>Here we will use a property called <code>animations</code>. This property will take an array as input. The array contains one or more “trigger”. Each trigger has a unique name and an implementation. The state and transitions for our animation need to be defined in the trigger implementation.</p>
<p>Each state function has a “stateName” defined to uniquely identify the state and a style function to show the style of the element in that state.</p>
<p>Each transition function has a <code>stateChangeExpression</code> defined to show the change of the state of an element and the corresponding array of animation steps to show how the transition will take place. We can include multiple trigger functions inside the animation property as comma separated values.</p>
<p>These functions trigger, and state and transition are defined in the <code>@angular/animations</code> module. Hence, we need to import this module in our component.</p>
<p>To apply animation on an element, we need to include the trigger name in the element definition. Include the trigger name followed by <code>@</code> symbol in the element tag. Refer to the sample code below:</p>
<pre><code class="lang-ts">&lt;div <span class="hljs-meta">@changeSize</span>&gt;&lt;/div&gt;
</code></pre>
<p>This will apply the trigger <code>changeSize</code> to the <code>&lt;d</code>iv&gt; element.</p>
<p>Let us create a few animations to get a better understanding of the Angular animation concepts.</p>
<h3 id="heading-change-size-animation">Change Size Animation</h3>
<p>We will create an animation to change the size of a <code>&lt;d</code>iv&gt; element on a button click.</p>
<p>Open the <code>animationdemo.component.ts</code> file and add the following import definition:</p>
<pre><code><span class="hljs-keyword">import</span> { trigger, state, style, animate, transition } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/animations'</span>;
</code></pre><p>Add the following animation property definition in the component metadata:</p>
<pre><code class="lang-ts">animations: [
  trigger(<span class="hljs-string">'changeDivSize'</span>, [
    state(<span class="hljs-string">'initial'</span>, style({
      backgroundColor: <span class="hljs-string">'green'</span>,
      width: <span class="hljs-string">'100px'</span>,
      height: <span class="hljs-string">'100px'</span>
    })),
    state(<span class="hljs-string">'final'</span>, style({
      backgroundColor: <span class="hljs-string">'red'</span>,
      width: <span class="hljs-string">'200px'</span>,
      height: <span class="hljs-string">'200px'</span>
    })),
    transition(<span class="hljs-string">'initial=&gt;final'</span>, animate(<span class="hljs-string">'1500ms'</span>)),
    transition(<span class="hljs-string">'final=&gt;initial'</span>, animate(<span class="hljs-string">'1000ms'</span>))
  ]),
]
</code></pre>
<p>Here we have defined a trigger <code>changeDivSize</code> and two state functions inside the trigger. The element will be green in the “initial” state and will be red with an increased width and height in the “final” state.</p>
<p>We have defined transitions for the state change. Transition from “initial” state to “final” will take 1500ms and from “final” state to “initial” will take 1000ms.</p>
<p>To change the state of our element we will define a function in the class definition of our component. Include the following code in the <code>AnimationdemoComponent</code> class:</p>
<pre><code class="lang-ts">currentState = <span class="hljs-string">'initial'</span>;

changeState() {
  <span class="hljs-built_in">this</span>.currentState = <span class="hljs-built_in">this</span>.currentState === <span class="hljs-string">'initial'</span> ? <span class="hljs-string">'final'</span> : <span class="hljs-string">'initial'</span>;
}
</code></pre>
<p>Here we have defined a <code>changeState</code> method which will switch the state of the element.</p>
<p>Open <code>animationdemo.component.html</code> file and add the following code:</p>
<pre><code class="lang-ts">&lt;h3&gt;Change the div size&lt;/h3&gt;
&lt;button (click)=<span class="hljs-string">"changeState()"</span>&gt;Change Size&lt;/button&gt;
&lt;br /&gt;
&lt;div [<span class="hljs-meta">@changeDivSize</span>]=currentState&gt;&lt;/div&gt;
&lt;br /&gt;
</code></pre>
<p>We have defined a button which will invoke the <code>changeState</code> function when clicked. We have defined a <code>&lt;d</code>iv&gt; element and applied the animation tr<code>igger changeD</code>ivSize to it. When we click on the button it will flip the state o<code>f the</code> </p><div> element and its size will change with a transition effect.<p></p>
<p>Before executing the application, we need to include the reference to our <code>Animationdemo</code> component inside the <code>app.component.html</code> file.</p>
<p>Open <code>app.component.html</code> file. You can see we have some default HTML code in this file. Delete all the code and put the selector of our component as shown below:</p>
<pre><code class="lang-ts">&lt;app-animationdemo&gt;&lt;/app-animationdemo&gt;
</code></pre>
<p>To execute the code run the <code>ng serve</code> command in the VS code terminal window. After running this command, it will ask to open <code>http://localhost:4200</code> in the browser. So, open any browser on your machine and navigate to this URL. You can see a webpage as shown below. Click on the button to see the animation.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aeLhzRqHdU1Gub7GL3WOvtgno7fMuRnwuy4H" alt="Image" width="639" height="594" loading="lazy">
<em>Change Div size using Angular animation</em></p>
<h3 id="heading-balloon-effect-animation">Balloon effect animation</h3>
<p>In the previous animation, the transition happened in two directions. In this section, we will learn how to change the size from all directions. It will be similar to inflating and deflating a balloon, hence the name balloon effect animation.</p>
<p>Add the following trigger definition in the animation property:</p>
<pre><code class="lang-ts">trigger(<span class="hljs-string">'balloonEffect'</span>, [
   state(<span class="hljs-string">'initial'</span>, style({
     backgroundColor: <span class="hljs-string">'green'</span>,
     transform: <span class="hljs-string">'scale(1)'</span>
   })),
   state(<span class="hljs-string">'final'</span>, style({
     backgroundColor: <span class="hljs-string">'red'</span>,
     transform: <span class="hljs-string">'scale(1.5)'</span>
   })),
   transition(<span class="hljs-string">'final=&gt;initial'</span>, animate(<span class="hljs-string">'1000ms'</span>)),
   transition(<span class="hljs-string">'initial=&gt;final'</span>, animate(<span class="hljs-string">'1500ms'</span>))
 ]),
</code></pre>
<p>Here, instead of defining the width and height property, we are using the transform property to change the size from all directions. The transition will occur when the state of the element is changed.</p>
<p>Add the following HTML code in the <code>app.component.html</code> file:</p>
<pre><code class="lang-ts">&lt;h3&gt;Balloon Effect&lt;/h3&gt;
&lt;div (click)=<span class="hljs-string">"changeState()"</span> 
  style=<span class="hljs-string">"width:100px;height:100px; border-radius: 100%; margin: 3rem; background-color: green"</span>
  [<span class="hljs-meta">@balloonEffect</span>]=currentState&gt;
&lt;/div&gt;
</code></pre>
<p>Here we have defined a div and applied the CSS style to make it a circle. Clicking on the div will invoke the <code>changeState</code> method to switch the element’s state.</p>
<p>Open the browser to see the animation in action as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/O8B90gJ8NVLnCmA1WStQAlqxeRUHnertm6G6" alt="Image" width="628" height="492" loading="lazy">
<em>Balloon effect animation using Angular 6</em></p>
<h3 id="heading-fade-in-and-fade-out-animation">Fade In and Fade Out animation</h3>
<p>Sometimes we want to show animation while adding or removing an element on the DOM. We will see how to animate the addition and removal of an item to a list with a fade-in and fade-out effect.</p>
<p>Add the following code inside the <code>AnimationdemoComponent</code> class definition for adding and removing the element in a list:</p>
<pre><code class="lang-ts">listItem = [];
list_order: <span class="hljs-built_in">number</span> = <span class="hljs-number">1</span>;

addItem() {
  <span class="hljs-keyword">var</span> listitem = <span class="hljs-string">"ListItem "</span> + <span class="hljs-built_in">this</span>.list_order;
  <span class="hljs-built_in">this</span>.list_order++;
  <span class="hljs-built_in">this</span>.listItem.push(listitem);
}
removeItem() {
  <span class="hljs-built_in">this</span>.listItem.length -= <span class="hljs-number">1</span>;
}
</code></pre>
<p>Add the following trigger definition in the animation property:</p>
<pre><code class="lang-ts">trigger(<span class="hljs-string">'fadeInOut'</span>, [
  state(<span class="hljs-string">'void'</span>, style({
    opacity: <span class="hljs-number">0</span>
  })),
  transition(<span class="hljs-string">'void &lt;=&gt; *'</span>, animate(<span class="hljs-number">1000</span>)),
]),
</code></pre>
<p>Here we have defined the trigger <code>fadeInOut</code>. When the element is added to the DOM it is a transition from void to wildcard (<em>) state. This is denoted using <code>void =&gt;</code>; </em>. When the element is removed from the DOM, it is a transition from wildcard (<em>) to void state. This is denoted usi`ng </em> =&gt;`; void.</p>
<p>When we use the same animation timing for both directions of the animation, we use the shorthand syntax <code>&lt;</code>;=&gt;. As defined in this trigger, the animation <code>from voi</code>d =&amp;g<code>t; * and</code> * =&gt; void will take 1000ms to complete.</p>
<p>Add the following HTML code in app.component.html file.</p>
<pre><code class="lang-ts">&lt;h3&gt;Fade-In and Fade-Out animation&lt;/h3&gt;

&lt;button (click)=<span class="hljs-string">"addItem()"</span>&gt;Add List&lt;/button&gt;
&lt;button (click)=<span class="hljs-string">"removeItem()"</span>&gt;Remove List&lt;/button&gt;

&lt;div style=<span class="hljs-string">"width:200px; margin-left: 20px"</span>&gt;
  &lt;ul&gt;
    &lt;li *ngFor=<span class="hljs-string">"let list of listItem"</span> [<span class="hljs-meta">@fadeInOut</span>]&gt;
      {{list}}
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
</code></pre>
<p>Here we are defining two buttons to add items to and remove them from the list. We are binding the fadeInOut trigger to the <code>&lt;</code>li&gt; element, which will show a fade-in and fade-out effect while being added and removed from the DOM.</p>
<p>Open the browser to see the animation in action as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/BbxpG-Sr4LlqQChVrxZtdRezMHifTwwM3-M3" alt="Image" width="628" height="492" loading="lazy">
<em>Fade-in and Fade-out animation using Angular 6</em></p>
<h3 id="heading-enter-and-leave-animation">Enter and Leave animation</h3>
<p>When adding to the DOM, the element will enter the screen from the left. When deleting, the element will leave the screen from the right.</p>
<p>The transition from <code>void =&gt; *</code> and <code>* =&gt; void</code> is very common. Therefore, Angular provides aliases for these animations:</p>
<ul>
<li>for void =&gt; * we can use ‘:enter’</li>
<li>for * =&gt; void we can use ‘:leave’</li>
</ul>
<p>The aliases make these transitions more readable and easier to understand.</p>
<p>Add the following trigger definition in the animation property:</p>
<pre><code class="lang-ts">trigger(<span class="hljs-string">'EnterLeave'</span>, [
  state(<span class="hljs-string">'flyIn'</span>, style({ transform: <span class="hljs-string">'translateX(0)'</span> })),
  transition(<span class="hljs-string">':enter'</span>, [
    style({ transform: <span class="hljs-string">'translateX(-100%)'</span> }),
    animate(<span class="hljs-string">'0.5s 300ms ease-in'</span>)
  ]),
  transition(<span class="hljs-string">':leave'</span>, [
    animate(<span class="hljs-string">'0.3s ease-out'</span>, style({ transform: <span class="hljs-string">'translateX(100%)'</span> }))
  ])
])
</code></pre>
<p>Here we have defined the trigger <code>EnterLeave</code>. The ‘:enter’ transition will wait for 300ms and then run for 0.5s with an ease-in effect. Whereas the ‘:leave transition will run for 0.3s with an ease-out effect.</p>
<p>Add the following HTML code in the <code>app.component.html</code> file:</p>
<pre><code class="lang-ts">&lt;h3&gt;Enter and Leave animation&lt;/h3&gt;

&lt;button (click)=<span class="hljs-string">"addItem()"</span>&gt;Add List&lt;/button&gt;
&lt;button (click)=<span class="hljs-string">"removeItem()"</span>&gt;Remove List&lt;/button&gt;

&lt;div style=<span class="hljs-string">"width:200px; margin-left: 20px"</span>&gt;
  &lt;ul&gt;
    &lt;li *ngFor=<span class="hljs-string">"let list of listItem"</span> [<span class="hljs-meta">@EnterLeave</span>]=<span class="hljs-string">"'flyIn'"</span>&gt;
      {{list}}
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
</code></pre>
<p>Here we are defining two buttons to add items to and remove them from the list. We are binding the <code>EnterLeave</code> trigger to the <code>&lt;</code>li&gt; element that will show the enter and leave effect while being added and removed from the DOM.</p>
<p>Open the browser to see the animation in action as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/iy70cW0uBOkKv9iGxVGf7xrxjvuVlywgzlsQ" alt="Image" width="628" height="492" loading="lazy">
<em>Enter and leave animation using Angular 6</em></p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In this article, we’ve learned about Angular 6 animations. We explored the concept of animation states and transitions. We also saw a few animations in action with the help of a sample application.</p>
<p>Please get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/angular-6-animations">GitHub</a> and play around to get a better understanding.</p>
<p>If you’re preparing for interviews, read my article on <a target="_blank" href="http://ankitsharmablogs.com/csharp-coding-questions-for-technical-interviews/">C# Coding Questions For Technical Interviews</a>.</p>
<h3 id="heading-see-also">See Also</h3>
<ul>
<li><a target="_blank" href="http://ankitsharmablogs.com/asp-net-core-using-highcharts-with-angular-5/">ASP.NET Core — Using Highcharts With Angular 5</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/asp-net-core-crud-using-angular-5-and-entity-framework-core/">ASP.NET Core — CRUD Using Angular 5 And Entity Framework Core</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/crud-operations-asp-net-core-using-angular-5-ado-net/">CRUD Operations With ASP.NET Core Using Angular 5 And ADO.NET</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/asp-net-core-getting-started-with-blazor/">ASP.NET Core — Getting Started With Blazor</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/crud-using-blazor-with-mongodb/">CRUD Using Blazor with MongoDB</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/creating-a-spa-using-razor-pages-with-blazor/">Creating An SPA Using Razor Pages With Blazor</a></li>
</ul>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
</div> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to make image upload easy with Angular ]]>
                </title>
                <description>
                    <![CDATA[ By Filip Jerga This is the second part of the tutorial on how to upload an image to Amazon S3. You can find the first part here. In this article, we will take a look at the Angular Part. You can also watch my step by step video tutorial of ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-image-upload-easy-with-angular-1ed14cb2773b/</link>
                <guid isPermaLink="false">66c3535fbf3e128ced96e93f</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ image ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 11 Sep 2018 15:07:36 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*dxawCwfllIh8ljUcRtwnXg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Filip Jerga</p>
<p>This is the second part of the tutorial on how to upload an image to Amazon S3. You can find the first part <a target="_blank" href="https://medium.freecodecamp.org/how-to-set-up-simple-image-upload-with-node-and-aws-s3-84e609248792">here</a>. In this article, we will take a look at the Angular Part.</p>
<p><strong>You can also watch my step by step video tutorial of an image upload. The link is provided at the bottom of this article.</strong></p>
<h3 id="heading-1-create-a-template-first">1. Create a template first</h3>
<p>First, we want to create a reusable component that will be easily pluggable into other components.</p>
<p>Let’s start with a simple HTML template for our input. Don’t forget to apply styles of your choice, or you can get them from my <a target="_blank" href="https://gist.github.com/Jerga99/7fe7b1942c6e5bbe4723f2369c760649">GitHub repo</a>.</p>
<pre><code class="lang-ts">&lt;label <span class="hljs-keyword">class</span>=<span class="hljs-string">"image-upload-container btn btn-bwm"</span>&gt;
  &lt;span&gt;Select Image&lt;/span&gt;
  &lt;input #imageInput
         <span class="hljs-keyword">type</span>=<span class="hljs-string">"file"</span>
         accept=<span class="hljs-string">"image/*"</span>
         (change)=<span class="hljs-string">"processFile(imageInput)"</span>&gt;
&lt;/label&gt;
</code></pre>
<p>Important here is a <strong>type</strong> of input, which is set to a <strong>file.</strong> The <strong>Accept</strong> attribute defines accepted files for input. <strong>Image/*</strong> specifies that we can choose images of any type by this input. <strong>#imageInput</strong> is a reference of input on which we can access uploaded files.</p>
<p>A <strong>Change</strong> event is fired when we select a file. So let’s take a look at the class code.</p>
<h3 id="heading-2-dont-forget-for-component-code">2. Don’t forget for Component Code</h3>
<pre><code class="lang-ts"><span class="hljs-keyword">class</span> ImageSnippet {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> src: <span class="hljs-built_in">string</span>, <span class="hljs-keyword">public</span> file: File</span>) {}
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'bwm-image-upload'</span>,
  templateUrl: <span class="hljs-string">'image-upload.component.html'</span>,
  styleUrls: [<span class="hljs-string">'image-upload.component.scss'</span>]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ImageUploadComponent {

  selectedFile: ImageSnippet;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> imageService: ImageService</span>){}

  processFile(imageInput: <span class="hljs-built_in">any</span>) {
    <span class="hljs-keyword">const</span> file: File = imageInput.files[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">const</span> reader = <span class="hljs-keyword">new</span> FileReader();

    reader.addEventListener(<span class="hljs-string">'load'</span>, <span class="hljs-function">(<span class="hljs-params">event: <span class="hljs-built_in">any</span></span>) =&gt;</span> {

      <span class="hljs-built_in">this</span>.selectedFile = <span class="hljs-keyword">new</span> ImageSnippet(event.target.result, file);

      <span class="hljs-built_in">this</span>.imageService.uploadImage(<span class="hljs-built_in">this</span>.selectedFile.file).subscribe(
        <span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> {

        },
        <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {

        })
    });

    reader.readAsDataURL(file);
  }
}
</code></pre>
<p>Let’s break down this code. You can see in the <strong>processFile</strong> that we are getting an image input we sent from the <strong>change</strong> event. By writing <strong>imageInput.files[0]</strong> we are accessing the first <strong>file</strong>. We need a <strong>reader</strong> in order to access additional properties of a file. By calling <strong>readAsDataURL,</strong> we can get a base64 representation of an image in the callback function of the <strong>addEventListener</strong> we subscribed to before.</p>
<p>In a callback function, we are creating an instance of the <strong>ImageSnippet. The first</strong> value is a base64 representation of an image we will display later on the screen. <strong>The second</strong> value is a file itself, which we will send to the server for upload to Amazon S3.</p>
<p>Now, we just need to provide this file and send a request through a service.</p>
<h3 id="heading-3-we-need-a-service-as-well">3. We need a service as well</h3>
<p>It wouldn’t be an Angular app without a service. The service will be the one responsible for sending a request to our Node server.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ImageService {

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> http: Http</span>) {}


  <span class="hljs-keyword">public</span> uploadImage(image: File): Observable&lt;Response&gt; {
    <span class="hljs-keyword">const</span> formData = <span class="hljs-keyword">new</span> FormData();

    formData.append(<span class="hljs-string">'image'</span>, image);

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.http.post(<span class="hljs-string">'/api/v1/image-upload'</span>, formData);
  }
}
</code></pre>
<p>As I told you in the previous lecture, we need to send an image as part of the <strong>form data</strong>. We will append the image under the key of an <strong>image</strong> to form data (same key we configured before in Node). Finally, we just need to send a request to the server with <strong>formData</strong> in a payload.</p>
<p><strong>Now we can celebrate. That’s it! Image sent to upload!</strong></p>
<p>In the next lines, I will provide some additional code for a better user experience.</p>
<h3 id="heading-4-additional-ux-updates">4. Additional UX Updates</h3>
<pre><code class="lang-ts"><span class="hljs-keyword">class</span> ImageSnippet {
  pending: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">false</span>;
  status: <span class="hljs-built_in">string</span> = <span class="hljs-string">'init'</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> src: <span class="hljs-built_in">string</span>, <span class="hljs-keyword">public</span> file: File</span>) {}
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'bwm-image-upload'</span>,
  templateUrl: <span class="hljs-string">'image-upload.component.html'</span>,
  styleUrls: [<span class="hljs-string">'image-upload.component.scss'</span>]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ImageUploadComponent {

  selectedFile: ImageSnippet;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> imageService: ImageService</span>){}

  <span class="hljs-keyword">private</span> onSuccess() {
    <span class="hljs-built_in">this</span>.selectedFile.pending = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">this</span>.selectedFile.status = <span class="hljs-string">'ok'</span>;
  }

  <span class="hljs-keyword">private</span> onError() {
    <span class="hljs-built_in">this</span>.selectedFile.pending = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">this</span>.selectedFile.status = <span class="hljs-string">'fail'</span>;
    <span class="hljs-built_in">this</span>.selectedFile.src = <span class="hljs-string">''</span>;
  }

  processFile(imageInput: <span class="hljs-built_in">any</span>) {
    <span class="hljs-keyword">const</span> file: File = imageInput.files[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">const</span> reader = <span class="hljs-keyword">new</span> FileReader();

    reader.addEventListener(<span class="hljs-string">'load'</span>, <span class="hljs-function">(<span class="hljs-params">event: <span class="hljs-built_in">any</span></span>) =&gt;</span> {

      <span class="hljs-built_in">this</span>.selectedFile = <span class="hljs-keyword">new</span> ImageSnippet(event.target.result, file);

      <span class="hljs-built_in">this</span>.selectedFile.pending = <span class="hljs-literal">true</span>;
      <span class="hljs-built_in">this</span>.imageService.uploadImage(<span class="hljs-built_in">this</span>.selectedFile.file).subscribe(
        <span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> {
          <span class="hljs-built_in">this</span>.onSuccess();
        },
        <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
          <span class="hljs-built_in">this</span>.onError();
        })
    });

    reader.readAsDataURL(file);
  }
}
</code></pre>
<p>We added new properties to the <strong>ImageSnippet: Pending</strong> and <strong>Status. Pending</strong> can be false or true, depending if an image is currently being uploaded. <strong>Status</strong> is the result of the uploading process. It can be <strong>OK</strong> or <strong>FAILED.</strong></p>
<p><strong>OnSuccess</strong> and <strong>onError</strong> are called after image upload and they set the status of an image.</p>
<p>Ok, now let’s take a look at the updated template file:</p>
<pre><code class="lang-ts">&lt;label <span class="hljs-keyword">class</span>=<span class="hljs-string">"image-upload-container btn btn-bwm"</span>&gt;
  &lt;span&gt;Select Image&lt;/span&gt;
  &lt;input #imageInput
         <span class="hljs-keyword">type</span>=<span class="hljs-string">"file"</span>
         accept=<span class="hljs-string">"image/*"</span>
         (change)=<span class="hljs-string">"processFile(imageInput)"</span>&gt;
&lt;/label&gt;


&lt;div *ngIf=<span class="hljs-string">"selectedFile"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"img-preview-container"</span>&gt;

  &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"img-preview{{selectedFile.status === 'fail' ? '-error' : ''}}"</span>
       [ngStyle]=<span class="hljs-string">"{'background-image': 'url('+ selectedFile.src + ')'}"</span>&gt;
  &lt;/div&gt;

  &lt;div *ngIf=<span class="hljs-string">"selectedFile.pending"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"img-loading-overlay"</span>&gt;
    &lt;div <span class="hljs-keyword">class</span>=<span class="hljs-string">"img-spinning-circle"</span>&gt;&lt;/div&gt;
  &lt;/div&gt;

  &lt;div *ngIf=<span class="hljs-string">"selectedFile.status === 'ok'"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"alert alert-success"</span>&gt; Image Uploaded Succesfuly!&lt;/div&gt;
  &lt;div *ngIf=<span class="hljs-string">"selectedFile.status === 'fail'"</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">"alert alert-danger"</span>&gt; Image Upload Failed!&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p>Here we are displaying our uploaded image and errors on the screen depending on the <strong>state</strong> of an <strong>image</strong>. When the image is pending, we also display a nice spinning image to notify the user of uploading activity.</p>
<h3 id="heading-5-add-some-styling">5. Add some styling</h3>
<p>Stylings are not the focus of this tutorial, so you can get all of the SCSS styles in this <a target="_blank" href="https://gist.github.com/Jerga99/7fe7b1942c6e5bbe4723f2369c760649">link</a>.</p>
<p><strong>Job done! :) That should be it for a simple image upload. If something is not clear, make sure you watched the first part of this tutorial first.</strong></p>
<p>If you like this tutorial, feel free to check my full course on Udemy <strong>— <a target="_blank" href="http://bit.ly/2NeWna4">The Complete Angular, React &amp; Node Guide | Airbnb style app</a>.</strong></p>
<p><strong>Completed Project:</strong> <a target="_blank" href="https://github.com/Jerga99/bwm-ng">My GitHub repository</a></p>
<p><strong>Video Lecture</strong>: <a target="_blank" href="https://www.youtube.com/watch?v=wNqwExw-ECw">YouTube Tutorial</a></p>
<p>Cheers,</p>
<p>Filip</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why AngularJS is my preferred framework for software development ]]>
                </title>
                <description>
                    <![CDATA[ By Rachael Ray AgularJS is one of the most versatile and popular frameworks available today. Google introduced it in 2012. It provides a scalable infrastructure that supports Google’s largest applications. AngularJS Development AngularJS, a structur... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-is-angularjs-the-most-preferred-framework-for-software-development-5253c2c569c9/</link>
                <guid isPermaLink="false">66c366ed8e244e1678738659</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 16 Jul 2018 10:17:12 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*cRboEba6UqJgiLDAqwXY_Q.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Rachael Ray</p>
<p>AgularJS is one of the most versatile and popular frameworks available today. Google introduced it in 2012. It provides a scalable infrastructure that supports Google’s largest applications.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/VLTdJGaboORQvfdim35EVVWF3koDO3aX3feX" alt="Image" width="700" height="400" loading="lazy">
<em>AngularJS Development</em></p>
<p><a target="_blank" href="https://angularjs.org/"><strong>AngularJS</strong></a>, a structured JavaScript framework, builds dynamic single page applications. It is a client-side framework that supports multiple platforms. All the functions and commands of this framework use code templates written in HTML script.</p>
<p>Moreover, the AngularJS framework has many powerful features. These features allow decoupling any application logic from DOM (Document Object Model) manipulation. It also provides a host of amazing and useful features. This is why <a target="_blank" href="https://www.goodfirms.co/directory/languages/top-software-development-companies/angularjs"><strong>AngularJS development</strong></a> is often the preferred option for businesses.</p>
<h3 id="heading-here-is-a-list-of-features-that-angularjs-offers"><strong>Here is a list of features that AngularJS offers</strong></h3>
<h4 id="heading-1-model-view-controller-mvc-framework"><strong>1. Model View Controller (MVC) Framework</strong></h4>
<p>MVC is a software design pattern for developing web applications. It is made up of:</p>
<p><strong>Model:</strong> the first level of the pattern which is responsible for maintaining data. It is similar to primitive data types like booleans, numbers, strings or objects. It is the simplest script without any getter and sorter methods.</p>
<p><strong>View:</strong> responsible for showing portions of data to the user. They present the data in a particular format triggered by the controller’s action.</p>
<p><strong>Controller:</strong> controls the interaction between the Model and the View. It responds to user input and interacts with the data model objects. The controller receives the input, validates it, and then conducts the operations.</p>
<p>As AngularJS is an open-source script, the working model is based on MVC patterns and the newest client-side JavaScript. The Model View Framework Control Architecture in AngularJS is easy, versatile, and dynamic.</p>
<p>MVC makes it easier to build a separate client-side application. With AngularJS, even if the MVC elements were developed separately, you can combine them. There is no need to write extra code to combine all the attributes together.</p>
<h4 id="heading-2-user-interface-with-html"><strong>2. User interface with HTML</strong></h4>
<p>User interfaces in AngularJS are built on HTML. It is a declarative language which has shorter tags and is extremely easy to comprehend. Even the interface it provides is organized, smooth, and structured.</p>
<p>Many times, it becomes complex to develop, organize, and reorganize the JavaScript Interfaces. So, the HTML interface can also regulate the implementation of the application. So, rather than understanding program flow and loading, you can define what you want and AngularJS will carve out the dependencies.</p>
<h4 id="heading-3-pojo-model"><strong>3. POJO Model</strong></h4>
<p>As compared to other frameworks, AngularJS uses POJO (Plain Old JavaScript) objects. Now, that means you do not need to add additional getter and setter elements to bind AngularJS along with additional data sources.</p>
<p>A POJO model also provides spontaneous and well-planned objects. Developers have to create loops of objects and loops of arrays with the required properties. Then they need to adjust and reframe it.</p>
<p>This makes AngularJS self-sufficient and easy to use. The well planned and quick application of the POJO model is one of the <a target="_blank" href="https://topcompaniesreview.wordpress.com/2018/05/15/what-makes-angularjs-a-powerful-javascript-framework-for-your-web-development/">reasons to use AngularJS in your next development project</a>.</p>
<h4 id="heading-4-active-community-on-google"><strong>4. Active community on Google</strong></h4>
<p>Whenever you want to adopt a framework for development, you always look for good community support. AngularJS doesn’t disappoint here either.</p>
<p>Why? Because Google maintains AngularJS. In addition to that, it is released under the MIT license and is available for download on GitHub.</p>
<p>So, if you have any maintenance issues or get stuck somewhere, there are many forums where you can get your queries solved. Also, if you have any suggestions or any can improve something, the source is easily available for download.</p>
<h4 id="heading-5-routing"><strong>5. Routing</strong></h4>
<p>Routing is basically the transition from one view to another. Now, this is the key aspect of single page applications.</p>
<p>In single page applications, everything comes in one single page. Developers don’t want to redirect the users to a new page every time they click on a menu or a sub-menu. The developers want the content to load asynchronously on the same page with just the URL changing.</p>
<p>Almost all websites work on this method. Some of the popular platforms like the Chrome app store and Twitter are the best examples of Single Page Applications. This method helps the user feel as if they are interacting with a desktop app.</p>
<p>Now, with AngularJS, this becomes an easy task and you can make various views for various URLs. AngularJS also enables you to load the appropriate view in the main page for a specific URL request. This is another reason why <a target="_blank" href="https://www.goodfirms.co/directory/languages/top-software-development-companies">developers love AngularJS</a>.</p>
<h4 id="heading-6-two-way-binding"><strong>6. Two-way binding</strong></h4>
<p>Data binding is the automatic synchronization of data between the view and the model. The view indicates the HTML and the model indicates the JavaScript variables.</p>
<p>In AngularJS, you can easily build a template which can bind different components with different models. In this way, whenever the value of any HTML or view component differs, the bound model value also gets updated.</p>
<p>Let’s say if the input text value changes, the bound model is also changed and updated accordingly. To control the changing data, there is no need to program a separate set of callback functions.</p>
<p>With two-way data binding, the application's presentation layer becomes very simple. As a result, the UI is clean and has an improved appeal. Also, complex data manipulations and calculations can be done with ease.</p>
<h3 id="heading-to-sum-up"><strong>To sum up</strong></h3>
<p>Cross-browser web applications built using AngularJS are user-friendly and interactive. One more benefit of AngularJS is that it analyzes the page DOM and then builds bindings which are based on AngularJS-specific elements.</p>
<p>As a result, it significantly reduces the coding part as compared to other frameworks. A single code set for one application and your task is done. Also, less coding means reduced chances of error.</p>
<p>AngularJS is a great multi-functional framework which speeds up your development process. It offers dependency injection and deep linking, and is a robust platform for software development.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The brain-fatigued JavaScripter’s guide to modern frontend tooling ]]>
                </title>
                <description>
                    <![CDATA[ By Amin Mohamed Ajani From package managers to ESLint, CommonJS to AMD, and ES6 Modules to Babel and Webpack — that’s a lot of tools! In this article, we’ll migrate an old AngularJS app where we’ll decode the tools NOW. I’m tired… Yes, I got the fati... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-brain-fatigued-javascripters-guide-to-modern-frontend-tooling-in-2018-9818a04e9ec5/</link>
                <guid isPermaLink="false">66c360f89539e75f2cc24a31</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 29 Jun 2018 01:05:45 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*mbiAnHlVRgaTRr8tgNU5zg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Amin Mohamed Ajani</p>
<p>From package managers to ESLint, CommonJS to AMD, and ES6 Modules to Babel and Webpack — that’s a lot of tools! In this article, we’ll migrate an old AngularJS app where we’ll decode the tools NOW.</p>
<h3 id="heading-im-tired">I’m tired…</h3>
<p>Yes, I got <a target="_blank" href="https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4">the fatigue</a> today.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/reverentgeek/status/1006942235366223872?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1006942235366223872&amp;ref_url=https%3A%2F%2Fmedium.com%2Fmedia%2Fac2b60273f3275b4dd489fc315bc01ac%3FpostId%3D9818a04e9ec5"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p> </p>
<p>Which got me thinking, I could have stayed working in sales and not taken a detour to front end web development. But then I realized that front end development is for the brave hearts, and brave hearts don’t quit. They win.</p>
<p>So I’m choosing to win by writing something worthwhile for fatigued victims of front end development and its tooling. I’ll be writing on how I transformed beginner code to a full-blown production level application, and the tools I configured in the process.</p>
<p>Let’s get started!</p>
<h3 id="heading-what-were-building">What we’re building</h3>
<p>Nothing fancy. We’re building a web application that fetches some random users from an API and displays it on the front-end. It will have <strong>no routing extraordinare*</strong>.* The end goal of the article is to equip you to get used to frontend tooling.</p>
<p>I’m using AngularJS with no boilerplate, so we that aren’t abstracted away from CLIs that leaves us breathless and in the awe of black magic funnery. Note: I’m using AngularJS and not Angular. AngularJS because I couldn’t find any posts related to AngularJS tooling and bundling.</p>
<p>Let’s start by creating an index file on our root directory.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</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">title</span>&gt;</span>Random User!<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://unpkg.com/spectre.css/dist/spectre.min.css"</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">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">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-center"</span>&gt;</span>Random User!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</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">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.0/angular.min.js"</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>
</code></pre>
<p>Good old days of yore. Got an Angularjs file and a minimal CSS framework from the CDN, and then we start cooking our JavaScript code and keep attaching it to the index line by line.</p>
<p>But as your app will grow, it will be necessary to keep track of all your dependencies (in this case, Angular).</p>
<h4 id="heading-enter-package-managers">Enter Package Managers</h4>
<p>So a lot of people resort to having a package manager which keeps track of the versions of dependencies they use on their project. A package manager’s single most USP is to goto the GitHub of the dependency, download it in your folder, and keep track of the version downloaded. This helps you not break your code if you move your repo and later download another version.</p>
<p>There was <a target="_blank" href="http://github.com/duojs/duo">duojs</a>, <a target="_blank" href="https://github.com/jspm/jspm-cli">jspm</a>, <a target="_blank" href="https://github.com/bower/bower">bower</a>, <a target="_blank" href="https://github.com/npm/npm">npm</a> and now, there is:</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/yarnpkg/status/785857780838232064?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E785857780838232064&amp;ref_url=https%3A%2F%2Fmedium.com%2Fmedia%2F6e083025c03285c9318802ed8f8c1632%3FpostId%3D9818a04e9ec5"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p> </p>
<p>Go ahead, <a target="_blank" href="https://yarnpkg.com/en/docs/install">install</a> it. We’re gonna need it. When we <strong>add</strong> a dependency in our application, yarn will download the stuff and keep it inside the node_modules folder. From then on, if you need the file, you can src-reference into your index.</p>
<pre><code class="lang-javascript">yarn add angular
</code></pre>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*MMK6im0fzHzttrpiHHqL5Q.jpeg" alt="Image" width="800" height="397" loading="lazy"></p>
<p>While we’re doing this, let’s also add app.js, userController.js, and userFactory.js files in our root directory and link them up into our index file.</p>
<p>App.js:</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 * /app.js
 */</span>

<span class="hljs-keyword">var</span> app = angular.module(<span class="hljs-string">"RandomApp"</span>, []);
</code></pre>
<p>userFactory.js:</p>
<pre><code class="lang-js"><span class="hljs-comment">// /userFactory.js</span>
app.factory(<span class="hljs-string">"UserF"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">$http</span>) </span>{
    <span class="hljs-keyword">var</span> UserF = {};
    UserF.getUsers = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        <span class="hljs-keyword">return</span> $http({
            <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
            <span class="hljs-attr">url</span>: <span class="hljs-string">'https://www.reqres.in/api/users'</span>,
        })
    };
    <span class="hljs-keyword">return</span> UserF;
});
</code></pre>
<p>userController.js:</p>
<pre><code class="lang-js"><span class="hljs-comment">// /userController.js</span>
app.controller(<span class="hljs-string">"userController"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">$scope, UserF</span>)</span>{
    $scope.users = [];
    UserF.getUsers()
        .then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">res</span>) </span>{
            $scope.users = res.data.data;
        })
});
</code></pre>
<p>index.html:</p>
<pre><code class="lang-html"><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">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, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"ie=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Random User!<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://unpkg.com/spectre.css/dist/spectre.min.css"</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">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span> <span class="hljs-attr">ng-app</span>=<span class="hljs-string">"RandomApp"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-center"</span>&gt;</span>Random User!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ng-controller</span>=<span class="hljs-string">"userController"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ng-repeat</span>=<span class="hljs-string">"user in users"</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> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-image"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">ng-src</span>=<span class="hljs-string">"{{user.avatar}}"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"img-responsive"</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">"card-header"</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-title h5"</span>&gt;</span>{{user.first_name}} {{user.last_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>
            <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">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"node_modules/angular/angular.min.js"</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">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"app.js"</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">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"userController.js"</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">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"userFactory.js"</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>
<h4 id="heading-problems-with-this-approach">Problems with this approach</h4>
<p>The order of our script tag must be in that specific order. app.js makes the variable app and then attaches it to the global window object. This app variable is then used by the rest of the script files. This is often called global namespace pollution, and if you are still using this approach, don’t. Further, if we open any one JS file in any given moment, we will have no idea what the app variable holds.</p>
<p>Another semantic problem with this code is that this code uses anonymous functions. Anonynous functions are both a boon and bane to JavaScript. Always name your anonymous function. It will make stack traces easier to debug.</p>
<p>Now wouldn’t it be cool if we could have a JS police that pointed out this stuff to us while we wrote?</p>
<h4 id="heading-eslint">ESLint</h4>
<p>ESLint is a linter. Kind of like code-pairing with a stricter version of you. Linters save time for you by debugging your code before you even run your application. Also it forces you and your team to follow clean code practices. Who says no to such an awesome teacher?</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/TheOrigenStudio/status/1009391662135513088?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1009391662135513088&amp;ref_url=https%3A%2F%2Fmedium.com%2Fmedia%2Fcfe7864721895d9ab6f2c5486bf9e5c4%3FpostId%3D9818a04e9ec5"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p> </p>
<h4 id="heading-configuring-eslint">Configuring ESLint</h4>
<pre><code class="lang-javascript">yarn add eslint eslint-config-airbnb eslint-config-airbnb-base -D
</code></pre>
<p>We’ll be using <a target="_blank" href="https://github.com/airbnb/javascript/tree/es5-deprecated/es5">Airbnb’s style configuration</a> that runs through our code and tells us wherever we’re writing the code in a non-standard way. The above command will install the configurations in the node_modules folder, but we will need to tell ESLint to use these. Make a file called .eslintrc.json and fill it up with:</p>
<pre><code class="lang-js"><span class="hljs-comment">// .eslintrc.json</span>
{
  <span class="hljs-string">"extends"</span>: [
    <span class="hljs-string">"airbnb/legacy"</span>
  ],
  <span class="hljs-string">"env"</span>: {
    <span class="hljs-string">"browser"</span>: <span class="hljs-literal">true</span>
  }
}
</code></pre>
<p>The extends stack tells ESLint to use the Airbnb rules on top of its own rules. The env variable tells ESLint to not scream at us if we’re using variables like <strong>window</strong> without initializing it. To lint through all our files, you can use a wildcard *.</p>
<pre><code class="lang-javascript">node_modules/.bin/eslint *.js
</code></pre>
<p>Let’s run ESLint on our files and see what happens.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*F47YGCwPC3b-B08jqMd0Mw.jpeg" alt="Image" width="800" height="637" loading="lazy"></p>
<p>These are all rules defined in the Airbnb style guide. I’ll leave it up to you to fix your files. It’s always better to have a linter from the beginning. Of course, you can also switch off a particular rule. For example, if you prefer no-semicolon, or the double-quote style to single quote, you can switch them off. ESLint will give you that flexibility.</p>
<h4 id="heading-modules">Modules</h4>
<p>Now let’s talk about modularity. When making large scale applications, we need to have our code well-structured so that it’s easier to scale. We put in place a separation of concerns by grouping code pieces in separate modules. JavaScript didn’t support modules until ES6 came along. But the concept of modularity came long before ES6.</p>
<h4 id="heading-commonjs">CommonJS</h4>
<p>Before ES6, this standard was adopted as a pattern where you write your piece of code and tell the environment to export that piece. And then you’d use a library like <a target="_blank" href="http://requirejs.org/">RequireJS</a> to import the module.</p>
<pre><code class="lang-js"><span class="hljs-comment">// util.js</span>
<span class="hljs-built_in">module</span>.export = {
    <span class="hljs-attr">noop</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{},
    <span class="hljs-attr">validateUrl</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">s</span>)</span>{
      <span class="hljs-keyword">return</span> s.matches(<span class="hljs-regexp">/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&amp;//=]*)/</span>)
    } 
};
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// postController.js</span>
<span class="hljs-keyword">var</span> validateUrl = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./util'</span>).validateUrl;
<span class="hljs-keyword">var</span> handleSubmit = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">e</span>) </span>{
    <span class="hljs-keyword">if</span>(!validateUrl(e.target.value)) {
       <span class="hljs-keyword">return</span>;
    }
    submitUrl(e.target.value);
}
</code></pre>
<p>If you’ve tinkered around with Node, you may find that piece of code very familiar. But there are downsides to this standard, because it’s synchronous. Which means that unless validateUrl is <strong>required*</strong>,* handleSubmit on Line 3 of postController above isn’t executed. The code halts.</p>
<p>This ideology works fine in Node.js. In Node, we can have a lot of dependencies before starting a server. For example, configuring log files, connecting to the DB on cloud, configuring secret keys. But on the front end, it is not always required.</p>
<h4 id="heading-asynchronous-module-definition-amd">Asynchronous Module Definition (AMD)</h4>
<p>Like the name suggests, it asynchronously loads modules and <a target="_blank" href="http://2ality.com/2012/04/declaring-module-exports.html">has a few more advantages over CommonJS patterns</a>. Here’s how the code looks like in AMD (I added a couple of functions). Do you see something familiar?</p>
<pre><code class="lang-js">define([<span class="hljs-string">'validateSpam'</span>, <span class="hljs-string">'blockUser'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">validateSpam, blockUser</span>)</span>{
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">noop</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{},
    <span class="hljs-attr">validateUrl</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">s</span>) </span>{
      <span class="hljs-keyword">return</span> s.matches(<span class="hljs-regexp">/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&amp;//=]*)/</span>)
    },
    <span class="hljs-attr">validateSpammyComment</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateSpammyComment</span>(<span class="hljs-params">comment, userID</span>) </span>{
      <span class="hljs-keyword">if</span>(validateSpam(comment)) {
        blockUser(userID);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
      }
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
</code></pre>
<p>It kind of feels like the way we Inject Dependencies in AngularJS on Line 1.</p>
<h4 id="heading-es6-modules">ES6 Modules</h4>
<p>Since the committee at TC39 saw developers using external libraries, they clearly felt the need for JavaScript to support modules. So they introduced them in ES6. Let’s use them!</p>
<p>utils.js:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">noop</span>(<span class="hljs-params"></span>)</span>{};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateUrl</span>(<span class="hljs-params">s</span>) </span>{
  <span class="hljs-keyword">return</span> s.matches(<span class="hljs-regexp">/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&amp;//=]*)/</span>)
}
<span class="hljs-keyword">export</span> {
  noop,
  validateUrl
}
</code></pre>
<p>postController:js</p>
<pre><code class="lang-js">
<span class="hljs-keyword">import</span> { validateUrl } <span class="hljs-keyword">from</span> <span class="hljs-string">'./util'</span>;

<span class="hljs-keyword">var</span> handleSubmit = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">e</span>) </span>{
    <span class="hljs-keyword">if</span>(!validateUrl(e.target.value)) {
       <span class="hljs-keyword">return</span>;
    }
    submitUrl(e.target.value);
}
</code></pre>
<p>No external library to call. Import/export natively supported. But there are still versions of browsers <a target="_blank" href="http://kangax.github.io/compat-table/es6/">which do not completely support all the features of ES6</a>. This inconsistency of browser support didn’t stop programmers from writing the next generation of JavaScript. Tools like <a target="_blank" href="https://babeljs.io/">babel</a> are available that scan through the JavaScript and <strong>transpile</strong> it down to browser compatible code. And just like that, your code supports older browsers like IE (oh IE die already!).</p>
<p><strong>Babel and ES6</strong></p>
<p>Okay, so let’s convert our old JavaScript to newer JavaScript. A little bit so that we can add some modularity. All this while, let’s keep our linter from yelling.</p>
<pre><code class="lang-js"><span class="hljs-comment">// /userFactory.js</span>
<span class="hljs-keyword">let</span> angular = <span class="hljs-built_in">window</span>.angular;
<span class="hljs-keyword">let</span> app = angular.module(<span class="hljs-string">'RandomApp'</span>);

<span class="hljs-comment">/**
 * A User factory which gets the user list
 * @param $http
 */</span>

<span class="hljs-keyword">let</span> userFactory = $http =&gt; {
  <span class="hljs-keyword">let</span> UserF = {};
  UserF.getUsers = <span class="hljs-function">() =&gt;</span> $http({
    <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
    <span class="hljs-attr">url</span>: <span class="hljs-string">'https://www.reqres.in/api/users'</span>
  });
  <span class="hljs-keyword">return</span> UserF;
};
app.factory(<span class="hljs-string">'UserF'</span>, userFactory);
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// /userController.js</span>

<span class="hljs-keyword">let</span> angular = <span class="hljs-built_in">window</span>.angular;
<span class="hljs-keyword">let</span> app = angular.module(<span class="hljs-string">'RandomApp'</span>);

<span class="hljs-comment">/**
 * Controls the user
 * @param $scope
 * @param UserF
 */</span>
<span class="hljs-keyword">let</span> userController = <span class="hljs-function">(<span class="hljs-params">$scope, UserF</span>) =&gt;</span> {
  $scope.users = [];
  UserF.getUsers().then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> $scope.users = res.data.data);
};
userController.$inject = [<span class="hljs-string">'$scope'</span>, <span class="hljs-string">'UserFactory'</span>];

app.controller(<span class="hljs-string">'userController'</span>, userController);
</code></pre>
<h4 id="heading-problem-with-this-code">Problem with this code</h4>
<p>This code won’t work. Because the let keyword of ES6 creates block scoped variables, and we can’t redefine a block scoped variable inside it’s own scope again. Remember: we’re still sitting on the global scope. We’ll fix this.</p>
<p>The reason why I asked you to refactor the code is because I want you to use babel on this and see the magic yourself. Time to fire up that terminal.</p>
<pre><code class="lang-javascript">yarn add babel-cli babel-preset-env
</code></pre>
<p>This will add babel-cli and babel-preset-env.</p>
<h4 id="heading-babel-plugins-and-presets">Babel plugins and presets</h4>
<p>The code goes through a series of transformations, and you can choose what kinds of transformations you want. You can have it convert arrow functions to anonymous, transform spread operators, transform for…of loops and a lot more. These transformations are what we call plugins.</p>
<p>You can pick and choose what kinds of transformations you want. Groups of plugins are called presets. Babel-preset-env creates a moving target for your babel. You are not pin-pointing the actual version of JavaScript, but you are asking babel to track the last <em>n</em> versions of all browsers.</p>
<p>Now make a babel configuration file: .babelrc and place it in the root folder.</p>
<pre><code class="lang-js">{
  <span class="hljs-string">"presets"</span>: [
    [<span class="hljs-string">"env"</span>, {
      <span class="hljs-string">"targets"</span>: {
        <span class="hljs-string">"browsers"</span>: <span class="hljs-string">"last 2 versions"</span>
      }
    }]
  ]
}
</code></pre>
<p>Now, if you run the following command on your terminal, babel will do its job. Go ahead, try it out:</p>
<pre><code class="lang-javascript">node_modules/.bin/babel *.js
</code></pre>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*P6hqhWvB52pMsILqo708Zw.jpeg" alt="Image" width="800" height="448" loading="lazy"></p>
<p><em>there’s only so much I can screencap. But you get the drill..</em></p>
<p>Nifty stuff, right? Babel gave a preview of how the files will look if it were to convert the files for us.</p>
<p>Now let’s take a breather and think about what all we’ve accomplished so far. We’ve broken down a JavaScript file into many files. We’ve added a linter so that it yells at us if we write funny code. We’re writing JavaScript in the future and making it available to the browser in a version it understands. We’ve polluted the global namespace, but we’ve done it awesomely which we will fix soon.</p>
<p>If only there was a tool that does all that automatically. We’d tell it to take our code, run the linter for any errors before the code hits production, and transpile it to browser compatible code. Yes, there is such a tool.</p>
<p>Let’s automate the hell out of this.</p>
<h3 id="heading-bundling-with-webpack">Bundling with Webpack</h3>
<p>First, move all JS files into a folder. And let’s use standard mnemonics and name the folder <strong>build</strong>. Also, let’s refactor our JavaScript files so that we can have all our files built up in a single file.</p>
<pre><code class="lang-js">
<span class="hljs-comment">// /build/userController.js</span>

<span class="hljs-comment">/**
 * Controls the user
 * <span class="hljs-doctag">@param <span class="hljs-variable">$scope</span></span>
 * <span class="hljs-doctag">@param <span class="hljs-variable">UserF</span></span>
 */</span>
<span class="hljs-keyword">let</span> userController = <span class="hljs-function">(<span class="hljs-params">$scope, UserF</span>) =&gt;</span> {
    $scope.users = [];
    UserF.getUsers().then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> $scope.users = res.data.data);
};
userController.$inject = [<span class="hljs-string">'$scope'</span>, <span class="hljs-string">'userFactory'</span>];

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> userController;
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// /build/userFactory.js</span>
<span class="hljs-comment">/**
 * A User factory which gets the user list
 * <span class="hljs-doctag">@param <span class="hljs-variable">$http</span></span>
 */</span>

<span class="hljs-keyword">let</span> userFactory = $http =&gt; {
    <span class="hljs-keyword">let</span> UserF = {};
    UserF.getUsers = <span class="hljs-function">() =&gt;</span> $http({
        <span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>,
        <span class="hljs-attr">url</span>: <span class="hljs-string">'https://www.reqres.in/api/users'</span>
    });
    <span class="hljs-keyword">return</span> UserF;
};
userFactory.$inject = [<span class="hljs-string">'$http'</span>];

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> userFactory;
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// /build/app.js</span>
<span class="hljs-keyword">import</span> angular <span class="hljs-keyword">from</span> <span class="hljs-string">'angular'</span>;

<span class="hljs-keyword">import</span> userController <span class="hljs-keyword">from</span> <span class="hljs-string">'./userController'</span>;
<span class="hljs-keyword">import</span> userFactory <span class="hljs-keyword">from</span> <span class="hljs-string">'./userFactory'</span>;

angular.module(<span class="hljs-string">'RandomApp'</span>, [])
  .factory(<span class="hljs-string">'userFactory'</span>, userFactory)
  .controller(<span class="hljs-string">'userController'</span>, userController);
</code></pre>
<pre><code class="lang-javascript">yarn add webpack webpack-dev-server babel-loader eslint-loader -D
</code></pre>
<p>And now, create a webpack.config.js file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);

<span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">mode</span>: <span class="hljs-string">'development'</span>, <span class="hljs-comment">// tells webpack that this is a development build. the 'production' switch will minify the code among other things</span>
    <span class="hljs-attr">devtool</span>: <span class="hljs-string">'cheap-eval-source-map'</span>, <span class="hljs-comment">// generate source maps for better debugging and dont take much time.</span>
    <span class="hljs-attr">context</span>: __dirname, <span class="hljs-comment">// since this runs in a node environment, webpack will need the current directory name</span>
    <span class="hljs-attr">entry</span>: <span class="hljs-string">'./build/app.js'</span>, <span class="hljs-comment">// take this file and add to the bundled file whatever this file imports</span>
    <span class="hljs-attr">output</span>: {
        <span class="hljs-attr">path</span>: path.join(__dirname, <span class="hljs-string">'dist'</span>), <span class="hljs-comment">// output this in a dist folder</span>
        <span class="hljs-attr">filename</span>: <span class="hljs-string">'bundle.js'</span> <span class="hljs-comment">// and name it bundle.js</span>
    },
  <span class="hljs-comment">// read medium post to know what's module and devServer because I dont have much room for comments</span>
    <span class="hljs-attr">module</span>: {
      <span class="hljs-attr">rules</span>: [{
        <span class="hljs-attr">enforce</span>: <span class="hljs-string">'pre'</span>,
        <span class="hljs-attr">loader</span>: <span class="hljs-string">'eslint-loader'</span>,
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>
      }, {
        <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>,
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>
      }]
    },
    <span class="hljs-attr">devServer</span>: {
        <span class="hljs-attr">publicPath</span>: <span class="hljs-string">'/dist/'</span>,
        <span class="hljs-attr">filename</span>: <span class="hljs-string">'bundle.js'</span>,
        <span class="hljs-attr">historyApiFallback</span>: <span class="hljs-literal">true</span>,
        <span class="hljs-attr">overlay</span>: <span class="hljs-literal">true</span>
    }
};
</code></pre>
<p>If you now fire up Webpack, you will see all files bundled up in a single file in a dist folder.</p>
<pre><code class="lang-javascript">webpack
</code></pre>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Vz4cQWFXYZdkU-TCJAVyIg.jpeg" alt="Image" width="800" height="341" loading="lazy"></p>
<p>Bliss.</p>
<h4 id="heading-dissecting-webpack-configuration">Dissecting Webpack Configuration</h4>
<p>Congratulations. Give yourself a pat on the back. You bundled your files so that they’re almost production ready. Now let’s talk about the configuration. I’ll break it down and tell you exactly what each key is. For more, <a target="_blank" href="https://webpack.js.org/">you can always read the manual</a>.</p>
<p>I’ve commented most of the stuff. Here, I talk about the left out stuff:</p>
<h4 id="heading-webpack-loaders-module-object">Webpack Loaders (module object)</h4>
<p>Think of this as a chain of code-loading units in a pipeline. The last one in the stack (babel-loader in our case) is the first one which Webpack uses for loading the code chunks. We’re asking Webpack to go through our code and transpile it first into ES5 using the babel-loader.</p>
<p>A loader object will also need a test key. It uses this key to find all files it needs to pick up (in our case, a regex that matches files ending with the extension dot JS). Once transpiled, proceed to the next loader (eslint-loader in our case). And in the end, write the changes from memory to a file and dump it in the file which we’ve specified in the output object.</p>
<p>But that’s not what our config does. We’ve added an enforce-pre on our ESLint loader because we want the linting first. Because the output will be a single file. And that file will be in a barely human readable format if we use <a target="_blank" href="https://webpack.js.org/guides/production/">minification and obfuscation</a> (which is often the case in production). The Linter will go crazy looking at our end code. We don’t want that. So Webpack will lint first and <strong>then</strong> transpile.</p>
<p>Apart from these, there are many loaders you can use, be it to load your style files, your SVGs, or fonts. One loader that I almost always end up using at work is the html-loader.</p>
<h4 id="heading-html-loader">HTML loader</h4>
<p>In the case of Angular, when we have templates in directives/components, we can use an html-loader in Webpack.</p>
<pre><code class="lang-javascript">templateUrl: <span class="hljs-string">'./users/partial/user.tpl.html'</span> <span class="hljs-comment">// instead of this,</span>
<span class="hljs-attr">templateUrl</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'./users/partial/user.tpl.html'</span>)
</code></pre>
<p>Webpack thrives on a <a target="_blank" href="https://github.com/webpack-contrib">super huge community</a> which comes up with awesome loaders with great documentation. For all your needs, chances are, there is at least one loader written.</p>
<h4 id="heading-webpack-dev-server-devserver">Webpack Dev Server (devServer)</h4>
<p>Webpack dev server is a module that comes separate from Webpack. It spins up its own server and watches the files we change. If you make any changes, the WDS will bundle it again and refresh the page. If there are errors, it will refresh the page to an overlay screen (configured by the overlay key) and show you the error right on the browser. And it’s super fast because it does all that in the memory and not on the hard storage.</p>
<p>Of course, to get it to work, you first need to have a base build file (that is, run Webpack at least once to have a build file). Once you have that, you can fire up this command. It will start the server and serve the static files, open the browser for you on port 8080 by default, and keep watching the changes.</p>
<pre><code class="lang-javascript">webpack-dev-server --open
</code></pre>
<p>That’s it!</p>
<p>But this is not the end of it if you think about it. There are still so many things you can do. At work, we use <a target="_blank" href="https://flow.org/en/">Flow</a> for static type check while we code. A static type checker looks at your code and warns you if you’re, say, calling functions with the wrong type of arguments. You can integrate that as well in Webpack.</p>
<p>We also use <a target="_blank" href="https://prettier.io/">Prettier</a> to format our code automatically as we type. It just makes the code more readable.</p>
<blockquote>
<p>Any fool can write code that a computer can understand. Good programmers write code that humans can understand — Martin Fowler.</p>
</blockquote>
<p>I’m going to put that up as a poster on my desk soon.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Congratulations! You did it!</p>
<p>If you survived reading this larger than life article, let me give you an over-the-internet-hi-five and tell you that today, you won. Surviving JavaScript is not easy for me. I wish I could have known all this while working on my first project as a UI guy. But I guess that’s how front-end development is for me. Keep learning, keep evolving.</p>
<p>I’m tinkering with React for now, and I soon may come up with another article if you liked this one. Maybe include <a target="_blank" href="https://reasonml.github.io/">ReasonML</a>, <a target="_blank" href="https://graphql.org/">GraphQL</a> or <a target="_blank" href="https://redux.js.org/">Redux</a>. If you liked this article or hated it or have some feedback, please do tell me.</p>
<p>I live on twitter as <a target="_blank" href="https://www.twitter.com/AminSpeaks">@AminSpeaks</a> and everywhere else as @binarybaba.</p>
<p>Cheers and Godspeed.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to get started with Angular 6.0 ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Learn what’s new and build an app Angular has released its latest version, Angular 6.0. In this article, we will understand the new features of Angular 6.0 and also set up a new project with the help of Angular CLI 6.0 and Visual Stud... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-get-started-with-angular-6-0-a196cbfb9bbb/</link>
                <guid isPermaLink="false">66d45db3246e57ac83a2c715</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Visual Studio Code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 06 May 2018 16:16:54 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*mmxWHaqZZtNMs_ggYnx8hg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h4 id="heading-learn-whats-new-and-build-an-app">Learn what’s new and build an app</h4>
<p>Angular has released its latest version, Angular 6.0. In this article, we will understand the new features of Angular 6.0 and also set up a new project with the help of Angular CLI 6.0 and Visual Studio Code.</p>
<h3 id="heading-whats-new-in-angular-60">What’s new in Angular 6.0?</h3>
<h4 id="heading-ng-update">ng update</h4>
<p>A new CLI command that will update your project dependencies to their latest versions.</p>
<h4 id="heading-ng-add">ng add</h4>
<p>Another new CLI command that makes adding new capabilities to your project easier.</p>
<h4 id="heading-angular-elements">Angular Elements</h4>
<p>This is a new feature that allows us to compile Angular components to native web components which we can use in our Angular app.</p>
<h4 id="heading-element-is-deprecated"> element is deprecated</h4>
<p>You can’t use  anymore inside of your component templates. You need to use  instead.</p>
<h4 id="heading-library-support">Library support</h4>
<p>Angular CLI now has the support for creating and building libraries. To create a library project within your CLI workspace, run the following command: ng generate library  (for example: ng generate library my-demo-lib)</p>
<h4 id="heading-angular-material-starter-components">Angular Material Starter Components</h4>
<p>If you run “ng add @angular/material” to add material to an existing application, you will also be able to generate 3 new starter components:</p>
<ul>
<li><strong>Material Sidenav</strong><br>A starter component including a toolbar with the app name and the side navigation</li>
<li><strong>Material Dashboard</strong><br>A starter dashboard component containing a dynamic grid list of cards</li>
<li><strong>Material Data Table</strong><br>A starter data table component that is pre-configured with a datasource for sorting and pagination</li>
</ul>
<h4 id="heading-workspace-support">Workspace support</h4>
<p>Angular CLI now has support for workspaces containing multiple projects, such as multiple applications and/or libraries.</p>
<h4 id="heading-the-angular-clijson-file-has-been-deprecated">The “.angular-cli.json” file has been deprecated</h4>
<p>Angular projects will now use “angular.json” instead of “.angular-cli.json” for build and project configuration.</p>
<h4 id="heading-use-rxjs-v6">Use RxJS V6</h4>
<p>Angular 6 will also allow us to use RxJS V6 with our application.</p>
<h4 id="heading-tree-shakable-providers">Tree Shakable Providers</h4>
<p>Angular 6.0 allows us to bundle services into the code base in modules where they are injected. This will help us to make our application smaller.</p>
<p>For example: Earlier, we used to reference our services as below.</p>
<pre><code><span class="hljs-comment">// In app.module.ts    @NgModule({    ...    providers: [MyService]  })  export class AppModule {}    // In myservice.ts     import { Injectable } from '@angular/core';    @Injectable()  export class MyService {    constructor() { }  }</span>
</code></pre><p>This approach will still work, but Angular 6.0 provides a new and easier alternative to this. We no longer need to add references in our NgModule. We can inject the reference directly into the service. Therefore, we can use the service as below:</p>
<pre><code><span class="hljs-comment">// In myservice.ts    import { Injectable } from '@angular/core';    @Injectable({    providedIn: 'root',  })  export class MyService {    constructor() { }  }</span>
</code></pre><p>Those are the new features/improvements in the latest release of Angular. Let’s move on and create our first application using Angular 6.0.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>Install the latest version of Node.js from <a target="_blank" href="https://nodejs.org/en/download/">here</a></li>
<li>Install Visual Studio Code from <a target="_blank" href="https://code.visualstudio.com/">here</a></li>
</ul>
<p>Installing Node.js will also install npm on your machine. After installing Node.js, open the command prompt and run the following set of commands to check the version of Node and npm installed on your machine.</p>
<p>Refer to the below image:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/PpLMXyOskr9A5wpHDndRTG8IkvpRvJ6H9DVb" alt="Image" width="613" height="282" loading="lazy"></p>
<p>Now that we’ve installed Node and npm, the next step is to install Angular CLI. Run the following command in a command window. This will install Angular 6.0 CLI globally on your machine.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/rskMSFRtqxuqxXA80OYMwHVhnR-3AGrxDsS5" alt="Image" width="650" height="305" loading="lazy"></p>
<p>Open VS Code and navigate to View &gt;&gt; Integrated Terminal.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/-bJC4pD8YZXAZdB2h6ez7WjmdZWcS0D5IpMo" alt="Image" width="524" height="732" loading="lazy"></p>
<p>This will open a terminal window in VS Code.</p>
<p>Type the following sequence of commands in the terminal window. These commands will create a directory with the name “<em>ng6Demo</em>” and then create an Angular application with the name “<em>ng6App</em>” inside that directory.</p>
<ul>
<li>mkdir ng6Demo</li>
<li>cd ng6Demo</li>
<li>ng new ng6App</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/n7ub05-40gA8P9HxCosSWJDoy5PyYSA0kHoA" alt="Image" width="479" height="389" loading="lazy"></p>
<p>There we go — we have created our first Angular 6 application using VS Code and Angular CLI. Now run the following command to open the project.</p>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/hcwLxqSELFiSmKaGJ9Wbjmlmtm4ThL1ZpNVU" alt="Image" width="409" height="107" loading="lazy"></p>
<p>This will open the code file of our application in a new VS Code window. You can see the following file structure in Solution Explorer.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/m8PPvMTg1DzehHavw-zrEx16BuG-RIQ5jMSy" alt="Image" width="256" height="412" loading="lazy"></p>
<p>Notice that the folder structure is a little bit different from the older version of Angular. We have a new “angular.json” file instead of the old “.angular-cli.json” file. This config file will still serve the same task as before, but the schema has changed a bit.</p>
<p>Open the package.json file and you can observe that we have the latest Angular 6.0.0 packages installed in our project.</p>
<pre><code>{    <span class="hljs-string">"name"</span>: <span class="hljs-string">"ng6-app"</span>,    <span class="hljs-string">"version"</span>: <span class="hljs-string">"0.0.0"</span>,    <span class="hljs-string">"scripts"</span>: {      <span class="hljs-string">"ng"</span>: <span class="hljs-string">"ng"</span>,      <span class="hljs-string">"start"</span>: <span class="hljs-string">"ng serve"</span>,      <span class="hljs-string">"build"</span>: <span class="hljs-string">"ng build"</span>,      <span class="hljs-string">"test"</span>: <span class="hljs-string">"ng test"</span>,      <span class="hljs-string">"lint"</span>: <span class="hljs-string">"ng lint"</span>,      <span class="hljs-string">"e2e"</span>: <span class="hljs-string">"ng e2e"</span>    },    <span class="hljs-string">"private"</span>: <span class="hljs-literal">true</span>,    <span class="hljs-string">"dependencies"</span>: {      <span class="hljs-string">"@angular/animations"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular/common"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular/compiler"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular/core"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular/forms"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular/http"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular/platform-browser"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular/platform-browser-dynamic"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular/router"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"core-js"</span>: <span class="hljs-string">"^2.5.4"</span>,      <span class="hljs-string">"rxjs"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"zone.js"</span>: <span class="hljs-string">"^0.8.26"</span>    },    <span class="hljs-string">"devDependencies"</span>: {      <span class="hljs-string">"@angular/compiler-cli"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@angular-devkit/build-angular"</span>: <span class="hljs-string">"~0.6.0"</span>,      <span class="hljs-string">"typescript"</span>: <span class="hljs-string">"~2.7.2"</span>,      <span class="hljs-string">"@angular/cli"</span>: <span class="hljs-string">"~6.0.0"</span>,      <span class="hljs-string">"@angular/language-service"</span>: <span class="hljs-string">"^6.0.0"</span>,      <span class="hljs-string">"@types/jasmine"</span>: <span class="hljs-string">"~2.8.6"</span>,      <span class="hljs-string">"@types/jasminewd2"</span>: <span class="hljs-string">"~2.0.3"</span>,      <span class="hljs-string">"@types/node"</span>: <span class="hljs-string">"~8.9.4"</span>,      <span class="hljs-string">"codelyzer"</span>: <span class="hljs-string">"~4.2.1"</span>,      <span class="hljs-string">"jasmine-core"</span>: <span class="hljs-string">"~2.99.1"</span>,      <span class="hljs-string">"jasmine-spec-reporter"</span>: <span class="hljs-string">"~4.2.1"</span>,      <span class="hljs-string">"karma"</span>: <span class="hljs-string">"~1.7.1"</span>,      <span class="hljs-string">"karma-chrome-launcher"</span>: <span class="hljs-string">"~2.2.0"</span>,      <span class="hljs-string">"karma-coverage-istanbul-reporter"</span>: <span class="hljs-string">"~1.4.2"</span>,      <span class="hljs-string">"karma-jasmine"</span>: <span class="hljs-string">"~1.1.1"</span>,      <span class="hljs-string">"karma-jasmine-html-reporter"</span>: <span class="hljs-string">"^0.2.2"</span>,      <span class="hljs-string">"protractor"</span>: <span class="hljs-string">"~5.3.0"</span>,      <span class="hljs-string">"ts-node"</span>: <span class="hljs-string">"~5.0.1"</span>,      <span class="hljs-string">"tslint"</span>: <span class="hljs-string">"~5.9.1"</span>    }  }
</code></pre><p>The name of our Angular application is <em>ng6app</em> which is inside <em>ng6demo</em> directory.</p>
<p>So, we will first navigate to our application using the below commands.</p>
<p>And then we use the following command to start the web server.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aERCZwSg9S74d2ZxBtQxwx50kL2IRfmJjSYy" alt="Image" width="650" height="265" loading="lazy"></p>
<p>After running this command, you can see that it is asking to open <a target="_blank" href="http://localhost:4200"><em>http://localhost:4200</em></a> in your browser. So, open any browser on your machine and navigate to this URL. Now, you can see the following page.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/IjRPyX7l6pOcgmXtT3ml1WSYRFU09uhDrGAD" alt="Image" width="650" height="322" loading="lazy"></p>
<p>Now we will try to change the welcome text on the screen. Navigate to <em>/src/app/app.component.ts</em> file and replace the code with the below code.</p>
<pre><code><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;    @Component({    <span class="hljs-attr">selector</span>: <span class="hljs-string">'app-root'</span>,    <span class="hljs-attr">templateUrl</span>: <span class="hljs-string">'./app.component.html'</span>,    <span class="hljs-attr">styleUrls</span>: [<span class="hljs-string">'./app.component.css'</span>]  })  <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">'Csharp Corner'</span>;  }
</code></pre><p>Now open the browser, you can see that the web page has been updated with new welcome message “Welcome to Csharp Corner!”</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/c5mAy0iqq0fAlCVSgceh51pMHuH7OEoreQXN" alt="Image" width="650" height="321" loading="lazy"></p>
<p>In this article we learned about the new features of Angular 6.0. We have installed the Angular 6.0 CLI and created our first Angular 6.0 application with the help of Visual Studio Code. We have also customized the welcome message on the webpage.</p>
<p>You can also find this article at <a target="_blank" href="https://www.c-sharpcorner.com/article/getting-started-with-angular-6/">C# Corner</a>.</p>
<p>You can check my other articles on Angular <a target="_blank" href="http://ankitsharmablogs.com/category/angular/">here</a></p>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
