<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bima</title>
    <description>The latest articles on DEV Community by Bima (@olabima_).</description>
    <link>https://dev.to/olabima_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F746133%2Ffa96fcbf-dfec-4d17-9d49-f987fc999c98.png</url>
      <title>DEV Community: Bima</title>
      <link>https://dev.to/olabima_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olabima_"/>
    <language>en</language>
    <item>
      <title>How I replaced Sentry and the rest for Good: The $0 Telegram Alerting Hack</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Thu, 19 Mar 2026 18:37:54 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/how-i-replaced-sentry-and-the-rest-for-good-the-0-telegram-alerting-hack-2ecl</link>
      <guid>https://dev.to/playfulprogramming/how-i-replaced-sentry-and-the-rest-for-good-the-0-telegram-alerting-hack-2ecl</guid>
      <description>&lt;p&gt;Most production applications need some form of &lt;strong&gt;real-time alerting&lt;/strong&gt;.&lt;br&gt;
When something goes wrong — a payment fails, an API crashes, or a user submits a contact form — someone needs to know immediately.&lt;/p&gt;

&lt;p&gt;Large teams often use tools like Sentry, Datadog, or PagerDuty for this. These platforms are powerful, but they can also be expensive and complex to configure, especially for small projects or solo developers.&lt;/p&gt;

&lt;p&gt;So instead of integrating a full observability stack, I built a lightweight alerting system using something I already use every day: &lt;strong&gt;Telegram&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, I’ll show you how to set up a &lt;strong&gt;free Telegram-based notification system&lt;/strong&gt; that can alert you about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;server errors&lt;/li&gt;
&lt;li&gt;new leads and contact form submissions&lt;/li&gt;
&lt;li&gt;important business events like payments or signups&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Why Telegram Works So Well for Alerting
&lt;/h1&gt;

&lt;p&gt;Telegram is surprisingly perfect as a developer alerting channel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s free&lt;/li&gt;
&lt;li&gt;Push notifications are instant&lt;/li&gt;
&lt;li&gt;Bots are easy to create&lt;/li&gt;
&lt;li&gt;Messages support Markdown, HTML, emojis, and buttons&lt;/li&gt;
&lt;li&gt;You can add your entire team to a group and everyone gets notified at once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of building dashboards or constantly checking logs, your application can send messages directly to a Telegram group.&lt;/p&gt;
&lt;h1&gt;
  
  
  What You Need Before Starting
&lt;/h1&gt;

&lt;p&gt;You only need four things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Telegram account&lt;/li&gt;
&lt;li&gt;A Telegram bot&lt;/li&gt;
&lt;li&gt;A Telegram group&lt;/li&gt;
&lt;li&gt;Your &lt;strong&gt;bot token&lt;/strong&gt; and &lt;strong&gt;chat ID&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it. No servers, no SDKs, no third-party monitoring service.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 1: Create a Telegram Bot
&lt;/h1&gt;

&lt;p&gt;Open Telegram and search for &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt;&lt;/strong&gt;.&lt;br&gt;
Run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/newbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts and Telegram will give you a &lt;strong&gt;bot token&lt;/strong&gt;.&lt;br&gt;
This token is basically the password your application will use to send messages.&lt;/p&gt;

&lt;p&gt;If you’ve never done this before, you can simply ask any AI assistant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How do I create a Telegram bot and get the bot token?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or follow this &lt;a href="https://youtu.be/DJReLYV_1Ww?si=fNApL6sLBWa0J9zf" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 2: Create a Group and Add the Bot
&lt;/h1&gt;

&lt;p&gt;Create a Telegram group for alerts, then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add your bot to the group&lt;/li&gt;
&lt;li&gt;Add your teammates&lt;/li&gt;
&lt;li&gt;Make sure notifications are enabled for the group&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This allows your app to send one message and notify everyone at once.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 3: Get the Telegram Chat ID (Important Step)
&lt;/h1&gt;

&lt;p&gt;Telegram bots don’t send messages using usernames or group names. They use a &lt;strong&gt;chat ID&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To get it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send any message in the group&lt;/li&gt;
&lt;li&gt;Open your browser and visit:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;https://api.telegram.org/bot&amp;lt;YOUR_TOKEN&amp;gt;/getUpdates
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You’ll see a JSON response. Look for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"chat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-1001234567890&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Alerts Group"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the &lt;code&gt;id&lt;/code&gt;. That is your &lt;strong&gt;chat ID&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Send Your First Message Using the Telegram Bot API
&lt;/h1&gt;

&lt;p&gt;Telegram provides a simple HTTP endpoint called &lt;strong&gt;sendMessage&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST https://api.telegram.org/bot&amp;lt;TOKEN&amp;gt;/sendMessage
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chat_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-1001234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello from my web app"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can test this using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;curl&lt;/li&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;li&gt;or directly from your backend code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this works, your alerting system is already functional. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Additionally, you can read more about the telegram api &lt;a href="https://core.telegram.org/methods" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Making Alerts Readable (Markdown, Emojis, and Structure)
&lt;/h1&gt;

&lt;p&gt;Raw text alerts quickly become hard to read. Instead, format them so they are easy to scan on mobile.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;🚨 &lt;span class="ge"&gt;*Server Error*&lt;/span&gt;
Endpoint: /api/payments
Status: 500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Telegram supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Markdown&lt;/li&gt;
&lt;li&gt;HTML formatting&lt;/li&gt;
&lt;li&gt;emojis&lt;/li&gt;
&lt;li&gt;inline buttons&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means you can send alerts that look structured and professional instead of messy log dumps.&lt;/p&gt;

&lt;h1&gt;
  
  
  Real-World Things You Can Alert On
&lt;/h1&gt;

&lt;p&gt;Once you have this set up, you can send notifications for almost anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend alerts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Unhandled exceptions&lt;/li&gt;
&lt;li&gt;Failed background jobs&lt;/li&gt;
&lt;li&gt;Payment confirmations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Frontend alerts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Contact form submissions&lt;/li&gt;
&lt;li&gt;New user registrations&lt;/li&gt;
&lt;li&gt;Demo bookings&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DevOps alerts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Deployment completed&lt;/li&gt;
&lt;li&gt;Server restarted&lt;/li&gt;
&lt;li&gt;Environment variables missing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This turns Telegram into a lightweight &lt;strong&gt;observability and business monitoring tool&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Sending Alerts from a Backend (Node.js Example)
&lt;/h1&gt;

&lt;p&gt;Here’s a minimal reusable function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TELEGRAM_BOT_TOKEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TELEGRAM_CHAT_ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendTelegramAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://api.telegram.org/bot&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/sendMessage`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;chat_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chatId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;parse_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Markdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can call this anywhere in your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendTelegramAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🚨 Database connection failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Using Telegram Alerts in Frontend Applications
&lt;/h1&gt;

&lt;p&gt;You can also trigger alerts from the frontend when API calls fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendTelegramAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;⚠️ Order creation failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially useful for catching silent failures during production that users might not report.&lt;/p&gt;

&lt;h1&gt;
  
  
  Example: Alerting on Contact Form Submissions
&lt;/h1&gt;

&lt;p&gt;Instead of relying only on email, you can push new leads directly to Telegram:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight email"&gt;&lt;code&gt;&lt;span class="nt"&gt;📩 New Contact Form Submission
Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="na"&gt; John Doe&lt;/span&gt;
&lt;span class="nt"&gt;Email&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="na"&gt; john@example.com&lt;/span&gt;
&lt;span class="nt"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="na"&gt; I’m interested in your services.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures you never miss an important message because it landed in spam.&lt;/p&gt;

&lt;h1&gt;
  
  
  Limitations of This Approach
&lt;/h1&gt;

&lt;p&gt;Telegram alerts are simple and effective, but they are not a full replacement for tools like Sentry or Datadog.&lt;/p&gt;

&lt;p&gt;You won’t get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dashboards&lt;/li&gt;
&lt;li&gt;error grouping&lt;/li&gt;
&lt;li&gt;performance tracing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;side projects&lt;/li&gt;
&lt;li&gt;startups&lt;/li&gt;
&lt;li&gt;internal tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;this approach provides a huge improvement over having no alerting at all.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;You don’t always need a complex observability stack to stay informed about what’s happening in your application. With just a Telegram bot and a few lines of code, you can build a real-time alerting system that notifies you and your team instantly.&lt;/p&gt;

&lt;p&gt;It’s free, quick to set up, and flexible enough to integrate with both frontend and backend workflows.&lt;/p&gt;

&lt;p&gt;Sometimes, simple tools are all you need.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>telegram</category>
      <category>node</category>
      <category>devops</category>
    </item>
    <item>
      <title>5 Essential Security Headers for Modern Frontend Devs (Next.js, Angular, &amp; Vue)</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Mon, 26 Jan 2026 11:55:46 +0000</pubDate>
      <link>https://dev.to/olabima_/5-essential-security-headers-for-modern-frontend-devs-nextjs-angular-vue-3icf</link>
      <guid>https://dev.to/olabima_/5-essential-security-headers-for-modern-frontend-devs-nextjs-angular-vue-3icf</guid>
      <description>&lt;h2&gt;
  
  
  I. Introduction: The "Invisible" Firewall
&lt;/h2&gt;

&lt;p&gt;Let’s be honest: as frontend engineers, we spend 90% of our time wrestling with state management, CSS layouts, API data, etc. Security usually feels like someone else's job—something handled by "The Backend Team" or a mysterious DevOps engineer in a dark room.&lt;/p&gt;

&lt;p&gt;But here’s the truth: you can have the most secure database in the world, and your user can still get compromised because your browser instructions were too vague.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;We often think of security as building a massive, complex fortress. We worry about sophisticated SQL injections or server-side exploits. Meanwhile, the "front door" is left wide open to &lt;strong&gt;XSS (Cross-Site Scripting)&lt;/strong&gt;, &lt;strong&gt;Clickjacking&lt;/strong&gt;, and &lt;strong&gt;MIME-sniffing&lt;/strong&gt; because of a few missing lines of text in our HTTP responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: Low-Hanging Fruit
&lt;/h3&gt;

&lt;p&gt;You don’t need to rewrite your authentication logic or change your component structure to fix this. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" rel="noopener noreferrer"&gt;HTTP Security Headers&lt;/a&gt; are essentially a "Rules of Engagement" list you send to the browser.&lt;/p&gt;

&lt;p&gt;By spending just 10 minutes configuring these 5 headers, you’re not just writing code—you’re telling the browser exactly how to protect your users. &lt;strong&gt;Zero refactoring. High impact&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  II. The 5 Essential Headers
&lt;/h2&gt;

&lt;p&gt;For most modern frontend apps (React, Vue, Angular), these headers are handled at the &lt;strong&gt;Infrastructure level&lt;/strong&gt; (where your app is hosted) or via &lt;strong&gt;Framework Config&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Strict-Transport-Security (HSTS)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The "Anti-Downgrade" Shield&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Threat:&lt;/strong&gt; A "Man-in-the-Middle" (MitM) attacker intercepts an unencrypted &lt;code&gt;http://&lt;/code&gt; request before it redirects to &lt;code&gt;https://&lt;/code&gt;, stripping your security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; Force the browser to &lt;em&gt;only&lt;/em&gt; communicate via HTTPS for a specified duration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Implementation String:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Strict-Transport-Security max-age=31536000; includeSubDomains; preload

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modern Note:&lt;/strong&gt; Use &lt;code&gt;preload&lt;/code&gt; only after you’ve verified your HTTPS setup is perfect, as it adds you to a hardcoded browser list that is difficult to "undo" quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. X-Content-Type-Options
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The "Anti-Sniffing" Guard&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Threat:&lt;/strong&gt; "MIME-sniffing." If a browser thinks a &lt;code&gt;.txt&lt;/code&gt; file looks like a &lt;code&gt;.js&lt;/code&gt; file, it might execute it, allowing an attacker to run malicious code hidden in an "innocent" upload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; Force the browser to strictly follow the &lt;code&gt;Content-Type&lt;/code&gt; header sent by the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Implementation String:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;X-Content-Type-Options: nosniff

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. X-Frame-Options
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The "Clickjacking" Barrier&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Threat:&lt;/strong&gt; An attacker embeds your site in an invisible &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; on their malicious site. They trick users into clicking buttons on &lt;em&gt;your&lt;/em&gt; site (like "Delete Account") while the user thinks they are clicking something else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; Block other sites from framing your content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Implementation String:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;X-Frame-Options: SAMEORIGIN

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pro Tip:&lt;/strong&gt; Modern apps should also use the &lt;code&gt;frame-ancestors 'self'&lt;/code&gt; directive in their &lt;strong&gt;Content Security Policy (CSP)&lt;/strong&gt;, but &lt;code&gt;X-Frame-Options&lt;/code&gt; remains the essential fallback for older browsers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Referrer-Policy
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The "Privacy" Filter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Threat:&lt;/strong&gt; When a user clicks a link to an external site, the browser sends the full URL of your page in the &lt;code&gt;Referer&lt;/code&gt; header. If your URLs contain sensitive data (like &lt;code&gt;/reset-password/token-123&lt;/code&gt;), you’re leaking secrets to third parties.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; Send the full URL for your own site, but only the domain name (origin) for everyone else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Implementation String:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Referrer-Policy: strict-origin-when-cross-origin

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Permissions-Policy
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The "Hardware" Lock&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Threat:&lt;/strong&gt; A compromised third-party script (like an ad or analytics tool) tries to access a user's camera, microphone, or geolocation without their knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; Explicitly disable browser features you don't use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Implementation String:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Permissions-Policy: camera=(), microphone=(), geolocation=()

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;History Lesson:&lt;/strong&gt; This header has officially replaced the older &lt;code&gt;Feature-Policy&lt;/code&gt;. If you see &lt;code&gt;Feature-Policy&lt;/code&gt; in old tutorials, it’s time to update!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where to Paste These (Quick Reference)
&lt;/h3&gt;

&lt;p&gt;Since these are &lt;strong&gt;HTTP Response Headers&lt;/strong&gt;, you don't put them in your &lt;code&gt;.js&lt;/code&gt; or &lt;code&gt;.ts&lt;/code&gt; components. Here is the modern "pasting" guide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js:&lt;/strong&gt; Add to the &lt;code&gt;async headers()&lt;/code&gt; function in your &lt;code&gt;next.config.js&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel / Netlify:&lt;/strong&gt; Add to your &lt;code&gt;vercel.json&lt;/code&gt; or &lt;code&gt;_headers&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Angular / Vue (Standard):&lt;/strong&gt; These are usually set in your &lt;strong&gt;Nginx/Apache&lt;/strong&gt; config or via a &lt;strong&gt;Middleware&lt;/strong&gt; (like &lt;code&gt;helmet&lt;/code&gt; for Node/Express) that serves your build folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Time to get hands-on. This is where the "10-minute" promise comes to life. Since our audience ranges from Next.js fans to Angular/Nginx traditionalists, we’ll provide the two most common "recipes."&lt;/p&gt;

&lt;h2&gt;
  
  
  III. Implementation: The 10-Minute "Copy-Paste"
&lt;/h2&gt;

&lt;p&gt;The beauty of these headers is that you don't need to touch your application logic. You just need to tell your &lt;strong&gt;web server&lt;/strong&gt; or &lt;strong&gt;framework&lt;/strong&gt; to attach these strings to every response.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Next.js Way (Modern Full-Stack)
&lt;/h3&gt;

&lt;p&gt;If you’re using Next.js, you can manage this directly in your configuration. This covers your React-based crowd perfectly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;next.config.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;securityHeaders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Strict-Transport-Security&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;max-age=31536000; includeSubDomains; preload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-Content-Type-Options&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nosniff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-Frame-Options&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SAMEORIGIN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Referrer-Policy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strict-origin-when-cross-origin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Permissions-Policy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;camera=(), microphone=(), geolocation=()&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/(.*)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Apply these headers to all routes&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;securityHeaders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. The Nginx Way (Angular, Vue, &amp;amp; SPAs)
&lt;/h3&gt;

&lt;p&gt;For Angular or Vue developers, your app is usually a collection of static files served by a web server like Nginx. You’ll want to add these to your server block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;/etc/nginx/conf.d/default.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;your-app.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Security Headers&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Strict-Transport-Security&lt;/span&gt; &lt;span class="s"&gt;"max-age=31536000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;includeSubDomains&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;preload"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;X-Content-Type-Options&lt;/span&gt; &lt;span class="s"&gt;"nosniff"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;X-Frame-Options&lt;/span&gt; &lt;span class="s"&gt;"SAMEORIGIN"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Referrer-Policy&lt;/span&gt; &lt;span class="s"&gt;"strict-origin-when-cross-origin"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Permissions-Policy&lt;/span&gt; &lt;span class="s"&gt;"camera=(),&lt;/span&gt; &lt;span class="s"&gt;microphone=(),&lt;/span&gt; &lt;span class="s"&gt;geolocation=()"&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/usr/share/nginx/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. The "Platform" Way (Vercel / Netlify)
&lt;/h3&gt;

&lt;p&gt;If you aren't managing a server and just deploying to a PaaS, use a config file in your root directory.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vercel (&lt;code&gt;vercel.json&lt;/code&gt;):&lt;/strong&gt; Uses a similar JSON structure to the Next.js example above.&lt;/li&gt;
&lt;li&gt;**Netlify (&lt;code&gt;_headers&lt;/code&gt;):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  IV. Verification: "How do I know it worked?"
&lt;/h2&gt;

&lt;p&gt;You’ve updated your config and deployed your code. But security is invisible—how do you actually &lt;em&gt;see&lt;/em&gt; that you’re protected? There are two main ways to verify your headers in under 60 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The "Under the Hood" Method (DevTools)
&lt;/h3&gt;

&lt;p&gt;You don't need fancy tools; the proof is already in your browser.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your app and hit &lt;code&gt;F12&lt;/code&gt; (or &lt;code&gt;Cmd+Option+I&lt;/code&gt;) to open &lt;strong&gt;Developer Tools&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Network&lt;/strong&gt; tab and refresh the page.&lt;/li&gt;
&lt;li&gt;Click on the very first request (usually your domain name).&lt;/li&gt;
&lt;li&gt;Look for the &lt;strong&gt;Response Headers&lt;/strong&gt; section in the right-hand pane.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you see your new headers listed there, you’re officially live.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The "Report Card" Method (SecurityHeaders.com)
&lt;/h3&gt;

&lt;p&gt;If you want to show off your work to your team (or your boss), use a scanner like &lt;strong&gt;SecurityHeaders.com&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Process:&lt;/strong&gt; Enter your URL and hit "Scan."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Goal:&lt;/strong&gt; Most apps start with a &lt;strong&gt;"D"&lt;/strong&gt; or &lt;strong&gt;"F"&lt;/strong&gt; grade. After adding these five headers, you’ll likely jump straight to an &lt;strong&gt;"A"&lt;/strong&gt;. It’s an incredibly satisfying visual "win" for 10 minutes of work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  V. The "AI Agent" Shortcut: One Prompt to Rule Them All
&lt;/h2&gt;

&lt;p&gt;If you’re using an AI coding assistant, don’t manually type these headers. Instead, use this &lt;strong&gt;System Prompt&lt;/strong&gt; to ensure your agent implements them perfectly every time.&lt;/p&gt;

&lt;p&gt;You can paste this into your "Project Rules" (like &lt;code&gt;.cursorrules&lt;/code&gt; or a custom Copilot instruction) or simply use it as a one-time request.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Security Header Prompt
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"I need to harden the security of my frontend application. Please update my configuration to implement the 'Essential 5' security headers.&lt;br&gt;
&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HSTS:&lt;/strong&gt; Enforce HTTPS with a 1-year max-age, including subdomains and preloading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X-Content-Type-Options:&lt;/strong&gt; Set to 'nosniff'.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X-Frame-Options:&lt;/strong&gt; Set to 'SAMEORIGIN' to prevent clickjacking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Referrer-Policy:&lt;/strong&gt; Set to 'strict-origin-when-cross-origin' to protect sensitive tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions-Policy:&lt;/strong&gt; Disable unused hardware features (camera, microphone, geolocation).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Context:&lt;/strong&gt; My app is built using [Insert Framework: e.g., Next.js / Angular] and is hosted on [Insert Platform: e.g., Vercel / Nginx]. Provide the exact configuration file changes needed."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why this works:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Precision:&lt;/strong&gt; It uses the specific directives (like &lt;code&gt;nosniff&lt;/code&gt; and &lt;code&gt;SAMEORIGIN&lt;/code&gt;) we covered, so the AI doesn't hallucinate weaker settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context-Aware:&lt;/strong&gt; By telling the AI your framework and host, it will choose between a &lt;code&gt;next.config.js&lt;/code&gt;, a &lt;code&gt;vercel.json&lt;/code&gt;, or an &lt;code&gt;nginx.conf&lt;/code&gt; automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety First:&lt;/strong&gt; It treats security as a "requirement," not a suggestion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  VI. Conclusion: One Giant Leap for Dev-kind
&lt;/h2&gt;

&lt;p&gt;Implementing these headers doesn't make your app 100% unhackable—nothing does—but it &lt;strong&gt;massively&lt;/strong&gt; raises the cost and effort required for an attacker to succeed. You've effectively moved from leaving your front door wide open to installing a deadbolt and a security camera.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of your new baseline:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HSTS:&lt;/strong&gt; No more unencrypted connections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X-Content-Type-Options:&lt;/strong&gt; No more file-type "guessing."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X-Frame-Options:&lt;/strong&gt; No more invisible iframes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Referrer-Policy:&lt;/strong&gt; No more leaking sensitive URLs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions-Policy:&lt;/strong&gt; No more rogue hardware access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Got thoughts? Questions? Ideas? Please discuss in the comment section below. CHEERS!!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>security</category>
      <category>frontend</category>
    </item>
    <item>
      <title>From Zero to Wow: Building a Beginner-Friendly Angular GPT AI-Powered App</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Sun, 26 Jan 2025 18:23:16 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/from-zero-to-wow-building-a-beginner-friendly-angular-gpt-powered-app-1j1n</link>
      <guid>https://dev.to/playfulprogramming-angular/from-zero-to-wow-building-a-beginner-friendly-angular-gpt-powered-app-1j1n</guid>
      <description>&lt;h1&gt;
  
  
  Section 1: Introduction 🖋️
&lt;/h1&gt;

&lt;h3&gt;
  
  
  What This Article is About
&lt;/h3&gt;

&lt;p&gt;Welcome to the exciting journey of building your very first Angular application! This article is designed specifically for beginners who want to dive into the world of web development. Together, we’ll build a simple yet powerful chat application powered by OpenAI’s GPT API. Along the way, you’ll discover how Angular, a popular front-end framework, enables developers to create scalable, modern web applications.&lt;/p&gt;

&lt;p&gt;Whether you’re entirely new to coding or just starting with Angular, this article will guide you every step of the way, ensuring no prior experience is required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Angular?
&lt;/h3&gt;

&lt;p&gt;Angular is one of the most versatile frameworks for building interactive and dynamic web applications. Here’s why we’ve chosen it for this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beginner-Friendly: Angular provides a structured and consistent development experience, making it an excellent choice for those just starting out.&lt;/li&gt;
&lt;li&gt;TypeScript Integration: It leverages TypeScript, a strongly typed superset of JavaScript, to enhance productivity and catch errors during development.&lt;/li&gt;
&lt;li&gt;Powerful Ecosystem: With features like built-in dependency injection, reusable components, and an active community, Angular equips you to build professional-grade applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What You’ll Achieve
&lt;/h3&gt;

&lt;p&gt;By the end of this article, you will have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;A Fully Functional GPT-Powered App&lt;/strong&gt;: A simple, interactive chat application where users can ask questions and receive responses from OpenAI’s GPT model.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Angular Knowledge&lt;/strong&gt;: A foundational understanding of how Angular components, services, and configurations come together to create a web application.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;API Integration Experience&lt;/strong&gt;: Learn how to connect Angular applications to external APIs, like OpenAI’s GPT, through HTTP requests.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What Makes This Article Special
&lt;/h3&gt;

&lt;p&gt;Unlike many tutorials, this guide not only walks you through creating an app but also provides clear explanations for every step, helping you grasp the underlying concepts of Angular. By the end, you’ll not only have a working app but also the confidence to build your own projects.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Ready to start coding?&lt;/strong&gt; In the next section, we’ll explore the basic tools and setup required to build this app.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;Full Code Repository&lt;/strong&gt;: You can find the complete source code for this tutorial &lt;a href="https://github.com/boluwatifee4/Angular-talk-openAi-Demo-app" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Section 2: Getting Ready to Learn Angular: Becoming an Angular developer
&lt;/h1&gt;

&lt;p&gt;Before you start building your Angular GPT-powered app, it’s important to prepare your environment and familiarize yourself with the tools and concepts you’ll be using. This section guides you step-by-step to ensure a smooth setup and learning experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Need to Learn First
&lt;/h2&gt;

&lt;p&gt;To build an Angular app, there are a few foundational skills you need to acquire:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. HTML and CSS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What They Are&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;HTML (HyperText Markup Language) defines the structure of your webpage.&lt;/li&gt;
&lt;li&gt;CSS (Cascading Style Sheets) is used to style the content.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Why They’re Important&lt;/strong&gt;: 
Angular components rely on HTML templates and CSS styles to define their structure and appearance.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Resources&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/learn/responsive-web-design/" rel="noopener noreferrer"&gt;HTML and CSS for Beginners: Article&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/UB1O30fR-EE?si=MI44lMIWB4PKbcpw" rel="noopener noreferrer"&gt;HTML Crash course: Video&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. TypeScript
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What It Is&lt;/strong&gt;: 
TypeScript is a strongly typed superset of JavaScript, used by Angular to enhance code quality and maintainability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why It’s Important&lt;/strong&gt;: 
Angular uses TypeScript for features like type checking, interfaces, and decorators.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/" rel="noopener noreferrer"&gt;TypeScript Official Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/BCg4U1FzODs?si=yfmOCw5XNlDb19yF" rel="noopener noreferrer"&gt;Typescript Crash Course: Video&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Node.js
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: &lt;br&gt;
Node.js is a JavaScript runtime that Angular uses to manage dependencies and run development tools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;How to Install&lt;/strong&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Download the installer for your OS from &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js Official Website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Follow the instructions to complete the installation.&lt;/li&gt;
&lt;li&gt;Verify the installation:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   node &lt;span class="nt"&gt;-v&lt;/span&gt;
   npm &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Git Basics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What It Is&lt;/strong&gt;: 
Git is a version control system that allows you to track changes and collaborate effectively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Steps&lt;/strong&gt;:

&lt;ol&gt;
&lt;li&gt;Install Git: &lt;a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git" rel="noopener noreferrer"&gt;Git Installation Guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Initialize a repository:
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resource&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/doc" rel="noopener noreferrer"&gt;Git Basics Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up Angular CLI
&lt;/h2&gt;

&lt;p&gt;The Angular CLI (Command Line Interface) is a powerful tool that helps you scaffold and manage Angular projects effortlessly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the Angular CLI globally using npm:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify the installation:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ng version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Resource&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.io/cli" rel="noopener noreferrer"&gt;Angular CLI Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Your OpenAI API Key
&lt;/h2&gt;

&lt;p&gt;You’ll need an API key to connect your Angular app to OpenAI’s GPT API.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create an OpenAI Account&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Sign up at &lt;a href="https://platform.openai.com/signup" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate Your API Key&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Navigate to the &lt;a href="https://platform.openai.com/account/api-keys" rel="noopener noreferrer"&gt;API Keys section&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create New Key&lt;/strong&gt; and copy the generated key. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Important&lt;/strong&gt;: Keep your API key private to avoid unauthorized access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Familiarizing Yourself with Angular
&lt;/h2&gt;

&lt;p&gt;Take time to understand Angular’s structure and ecosystem. Here are some helpful resources:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Official Tutorials&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The Angular team provides beginner-friendly guides to help you get started.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/start" rel="noopener noreferrer"&gt;Angular Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Angular Documentation&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Use the official documentation as a reference throughout your journey.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/docs" rel="noopener noreferrer"&gt;Angular Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communities to Join&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/Angular/" rel="noopener noreferrer"&gt;Angular Reddit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/tagged/angular" rel="noopener noreferrer"&gt;Stack Overflow - Angular Questions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Angular Discord Community&lt;/strong&gt;: Engage with developers to ask questions and share knowledge.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 &lt;strong&gt;You’re Ready!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;With the environment set up and foundational knowledge in place, you’re prepared to start planning your GPT-powered app.&lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;Section 3: Planning the GPT-Powered Chat App&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Section 3: Planning the GPT-Powered Chat App
&lt;/h1&gt;

&lt;p&gt;Before diving into coding, it’s essential to have a clear plan. In this section, you’ll understand the app’s purpose, the technologies involved, and how the app will function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of the App
&lt;/h2&gt;

&lt;p&gt;The goal is to build a &lt;strong&gt;GPT-powered chat interface&lt;/strong&gt; that allows users to send a prompt and receive responses from OpenAI’s GPT API. The app will focus on simplicity and usability while introducing key Angular concepts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A user-friendly chat interface.&lt;/li&gt;
&lt;li&gt;Integration with OpenAI’s GPT API to handle prompts and generate responses.&lt;/li&gt;
&lt;li&gt;A responsive design for better usability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technologies You’ll Use
&lt;/h2&gt;

&lt;p&gt;To bring this app to life, you’ll rely on the following technologies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Angular&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular serves as the frontend framework for building a dynamic and scalable user interface.&lt;/li&gt;
&lt;li&gt;You’ll leverage Angular features such as &lt;strong&gt;components&lt;/strong&gt;, &lt;strong&gt;services&lt;/strong&gt;, and &lt;strong&gt;dependency injection&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;OpenAI’s GPT API&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The GPT API will power the chatbot’s responses.&lt;/li&gt;
&lt;li&gt;You’ll use the &lt;strong&gt;Chat Completions API&lt;/strong&gt; to send and receive user prompts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How the App Works
&lt;/h2&gt;

&lt;p&gt;Here’s a step-by-step breakdown of how your app will function:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User Input&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The user types a prompt into the chat input field.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Request&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The input is sent to OpenAI’s GPT API using Angular’s HTTP client service.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Handling&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The GPT API generates a response based on the prompt and sends it back.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Display Response&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The response is displayed in the chat interface for the user to see.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Preparing for Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  API Key Reminder:
&lt;/h3&gt;

&lt;p&gt;Before you proceed, ensure you have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Registered for an OpenAI account.&lt;/li&gt;
&lt;li&gt;Generated and securely saved your API key. You’ll need it to configure the GPT service in your app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 &lt;strong&gt;Next Steps&lt;/strong&gt;: Now that you have a plan, it’s time to set up your Angular project in &lt;strong&gt;Section 4: Setting Up the Angular Project&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Fantastic! Ready to move forward with &lt;strong&gt;Section 4: Setting Up the Angular Project&lt;/strong&gt;. Let’s get it done! 🚀🖋️&lt;/p&gt;

&lt;h1&gt;
  
  
  Section 4: Setting Up the Angular Project
&lt;/h1&gt;

&lt;p&gt;With your environment ready and a clear plan in place, it’s time to create the foundation of your GPT-powered Angular app. In this section, you’ll set up the Angular project, explore its structure, and ensure everything runs correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Angular CLI
&lt;/h2&gt;

&lt;p&gt;If you haven’t already installed the Angular CLI, here’s a quick recap:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your terminal and run the following command to install the CLI globally:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify the installation:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ng version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create and Explore Your Project
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate a New Project&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Use the Angular CLI to scaffold a new project:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ng new gpt-powered-app 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Navigate to Your Project Directory&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Once the project is created, move into the project folder:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cd &lt;/span&gt;gpt-powered-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project Structure Overview
&lt;/h2&gt;

&lt;p&gt;Angular generates a default project structure. Here are the key folders and files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;src/app&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;The main folder where your app’s code lives.&lt;/li&gt;
&lt;li&gt;You’ll create components, services, and modules here.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;angular.json&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;The configuration file for your Angular app.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;package.json&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;Lists all dependencies and scripts for your project.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;node_modules&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Contains all installed dependencies for the app.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Understanding this structure will help you navigate your project as you develop.&lt;/p&gt;

&lt;h2&gt;
  
  
  First Run: Test Your Setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Start the Angular development server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ng serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open your browser and navigate to:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   http://localhost:4200/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;You should see the default Angular app running. If the page loads successfully, your setup is complete!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 &lt;strong&gt;Next Steps&lt;/strong&gt;: With the foundation in place, it’s time to start building the core features of your GPT-powered chat app in &lt;strong&gt;Section 5: Building the Chat App&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Section 5: Building the GPT Powered Angular Chat App
&lt;/h1&gt;

&lt;p&gt;Now that your Angular project is set up, it’s time to build the core feature: the GPT-powered chat app. In this section, you’ll create a chat component, implement the GPT service, and connect them together for a fully functional experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the Chat Component
&lt;/h2&gt;

&lt;p&gt;Angular components are the building blocks of your application. Follow these steps to create a standalone chat component:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate the Component&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Use the Angular CLI to generate a standalone chat component:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ng generate component components/chat &lt;span class="nt"&gt;--standalone&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What Happens&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;This command creates the following files in &lt;code&gt;src/app/components/chat/&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;chat.component.ts&lt;/code&gt; (logic and structure)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chat.component.html&lt;/code&gt; (HTML template)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chat.component.css&lt;/code&gt; (styles)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Update the Chat Component Template
&lt;/h2&gt;

&lt;p&gt;To create the chat interface, update &lt;code&gt;chat.component.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;   &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"chat-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;GPT-Powered Chat&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;[(ngModel)]=&lt;/span&gt;&lt;span class="s"&gt;"userInput"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Ask something..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"sendPrompt()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Send&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

     &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"response"&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"response"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Response:&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ response }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;: Captures user input using Angular’s two-way data binding (&lt;code&gt;[(ngModel)]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;: Triggers the &lt;code&gt;sendPrompt()&lt;/code&gt; function when clicked.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;div class="response"&amp;gt;&lt;/code&gt;: Displays GPT’s response conditionally (&lt;code&gt;*ngIf="response"&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add Logic to the Chat Component
&lt;/h2&gt;

&lt;p&gt;Edit &lt;code&gt;chat.component.ts&lt;/code&gt; to handle user input and display the GPT API response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GptService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../services/gpt.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CommonModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormsModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
     &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CommonModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormsModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
     &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./chat.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./chat.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
   &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

     &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;gptService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GptService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

     &lt;span class="nf"&gt;sendPrompt&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gptService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
           &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something went wrong. Please try again.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Injection&lt;/strong&gt;: The &lt;code&gt;GptService&lt;/code&gt; is injected into the component through the constructor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two-Way Binding&lt;/strong&gt;: The &lt;code&gt;userInput&lt;/code&gt; variable is bound to the &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; for seamless input handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Integration&lt;/strong&gt;: The &lt;code&gt;sendPrompt()&lt;/code&gt; function calls the GPT service, handles responses, and updates the &lt;code&gt;response&lt;/code&gt; variable.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create the GPT Service
&lt;/h2&gt;

&lt;p&gt;Services in Angular manage data and logic that can be reused across components. Follow these steps to create and configure the GPT service:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate the Service&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Run the following command:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ng generate service services/gpt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update the GPT Service Logic&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Open &lt;code&gt;src/app/services/gpt.service.ts&lt;/code&gt; and update it as follows:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
     &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GptService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;apiUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.openai.com/v1/chat/completions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-api-key-here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your OpenAI API key&lt;/span&gt;

     &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

     &lt;span class="nf"&gt;generateResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;};&lt;/span&gt;
       &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You are a helpful assistant.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;],&lt;/span&gt;
         &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;};&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apiUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HttpClient&lt;/strong&gt;: Used to send HTTP requests to OpenAI’s GPT API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;generateResponse()&lt;/strong&gt;: Sends the user prompt to the API and returns an observable with the response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Key&lt;/strong&gt;: Replace &lt;code&gt;'your-api-key-here'&lt;/code&gt; with your actual OpenAI API key.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Style the Chat Component
&lt;/h2&gt;

&lt;p&gt;Add basic styling to &lt;code&gt;chat.component.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;   &lt;span class="nc"&gt;.chat-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nt"&gt;textarea&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nc"&gt;.response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;chat-container&lt;/code&gt; centers the chat interface.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;textarea&lt;/code&gt; and &lt;code&gt;button&lt;/code&gt; styles ensure usability and aesthetics.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Securing Your API Key with Environment Variables
&lt;/h2&gt;

&lt;p&gt;Hardcoding sensitive data like API keys in your service files is risky. A better approach is to use &lt;strong&gt;environment variables&lt;/strong&gt; to keep your keys secure. This section will guide you on how to set up and use environment files in your Angular project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create Environment Files
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the &lt;code&gt;src/&lt;/code&gt; directory in your project.&lt;/li&gt;
&lt;li&gt;Create a new folder named &lt;code&gt;environments&lt;/code&gt; if it doesn’t already exist.&lt;/li&gt;
&lt;li&gt;Inside the &lt;code&gt;environments/&lt;/code&gt; folder, create two files:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;environment.ts&lt;/code&gt;: For development settings.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment.prod.ts&lt;/code&gt;: For production settings.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Add Your API Key
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;code&gt;environment.ts&lt;/code&gt; file and define your API key:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;openAiApiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-api-key-here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open the &lt;code&gt;environment.prod.ts&lt;/code&gt; file and add the same key for production:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;openAiApiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-api-key-here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 3: Update the GPT Service
&lt;/h3&gt;

&lt;p&gt;Modify the &lt;code&gt;gpt.service.ts&lt;/code&gt; file to use the environment variable instead of a hardcoded API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../environments/environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openAiApiKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 4: Prevent Sensitive Data from Being Committed
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;code&gt;.gitignore&lt;/code&gt; file in your project’s root directory.&lt;/li&gt;
&lt;li&gt;Add the following line to ignore your environment files:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   src/environments/*.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures your API keys and sensitive data won’t be included in version control.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 5: Share Environment Setup Instructions
&lt;/h3&gt;

&lt;p&gt;When working on a team or sharing the project, provide clear instructions (like this section) on how to create and configure environment files. Avoid sharing actual API keys.&lt;/p&gt;




&lt;p&gt;💡 &lt;strong&gt;Why Use Environment Variables?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This approach keeps your sensitive information secure while allowing different configurations for development and production environments. It’s a best practice for modern web development.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Next Steps&lt;/strong&gt;: Now that the chat component and GPT service are ready, you’ll integrate the component into your app in &lt;strong&gt;Section 6: Testing Your Application&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Section 6: Testing Your Application
&lt;/h1&gt;

&lt;p&gt;Now that your GPT-powered chat app is built, it’s time to test it and ensure everything works as expected. This section will guide you through running your app locally, testing its features, and troubleshooting common issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the App Locally
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Start the development server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ng serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open your browser and navigate to:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   http://localhost:4200/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What You Should See&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;The default Angular app should load with your custom GPT-powered chat component at the center.&lt;/li&gt;
&lt;li&gt;If you can interact with the chat interface and get responses from the API, congratulations! Your app is working.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Interact with the Chat Interface
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Enter a message or question into the chat input field.&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Send&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;Wait for the GPT API to respond. The reply should display in the response area below the input.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;h2&gt;
  
  
  Troubleshooting Tips
&lt;/h2&gt;

&lt;p&gt;If something isn’t working as expected, use the following checklist to debug your app:&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Issues and Solutions
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Page Doesn't Load&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Check the terminal output for errors when running &lt;code&gt;ng serve&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ensure all dependencies are installed:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;     npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No Response from GPT API&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify your API key in the &lt;code&gt;environment.ts&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Check for typos in your GPT service URL (&lt;code&gt;https://api.openai.com/v1/chat/completions&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Ensure you’ve included the necessary headers (&lt;code&gt;Authorization&lt;/code&gt; and &lt;code&gt;Content-Type&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CORS Issues&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure your browser isn’t blocking API requests due to Cross-Origin Resource Sharing (CORS).&lt;/li&gt;
&lt;li&gt;If needed, use a browser extension or configure your backend to allow CORS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Error in the Console&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for error messages in the browser developer console.&lt;/li&gt;
&lt;li&gt;If the error relates to the API, double-check your service configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Styling Issues&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure the styles in &lt;code&gt;chat.component.css&lt;/code&gt; are applied correctly.&lt;/li&gt;
&lt;li&gt;Use browser developer tools to inspect the DOM and debug CSS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 &lt;strong&gt;Pro Tip&lt;/strong&gt;: Regularly check the terminal and browser console for any warnings or errors. These often provide useful hints for troubleshooting.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Next Steps&lt;/strong&gt;: Once your app is tested and functional, you can enhance it further in &lt;strong&gt;Section 7: Taking the Next Steps&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Section 7: Taking the Next Steps
&lt;/h1&gt;

&lt;p&gt;Congratulations! You’ve successfully built and tested a GPT-powered chat app using Angular. Now, let’s explore Angular-specific enhancements and techniques to elevate your app and expand your skillset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhancing Your App
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Loading Indicators&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improve user experience by adding a loading spinner or message while waiting for a response.&lt;/li&gt;
&lt;li&gt;Use Angular’s &lt;code&gt;*ngIf&lt;/code&gt; directive to display a spinner conditionally during HTTP calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Styling with Angular Material&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enhance your app’s appearance with Angular Material components.&lt;/li&gt;
&lt;li&gt;Install Angular Material:
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ng add @angular/material
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add prebuilt components like buttons, input fields, and dialog boxes for a polished look.&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Resource&lt;/strong&gt;: &lt;a href="https://material.angular.io/" rel="noopener noreferrer"&gt;Angular Material Documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Form Validation&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Implement validation for user inputs to ensure prompts meet criteria (e.g., non-empty, character limits).&lt;/li&gt;
&lt;li&gt;Use Angular’s &lt;code&gt;FormBuilder&lt;/code&gt; and reactive forms to manage form state and validation logic.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormBuilder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chatForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
     &lt;span class="na"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)]],&lt;/span&gt;
   &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reusability with Shared Components&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extract reusable UI elements, such as buttons or input fields, into shared components.&lt;/li&gt;
&lt;li&gt;Use these components across multiple parts of your app to maintain consistency.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Routing&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add multiple pages to your app, such as a settings page for customization or a help page for user guidance.&lt;/li&gt;
&lt;li&gt;Use Angular Router to set up and navigate between these pages.&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Resource&lt;/strong&gt;: &lt;a href="https://angular.io/guide/router" rel="noopener noreferrer"&gt;Angular Routing Guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;State Management&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage app-wide state, such as chat history or user preferences, using Angular services or state management libraries like NgRx.&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Resource&lt;/strong&gt;: &lt;a href="https://ngrx.io/" rel="noopener noreferrer"&gt;Introduction to NgRx&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Connecting to Other Endpoints
&lt;/h2&gt;

&lt;p&gt;Learning how to work with APIs is a crucial skill in Angular development. Practice by integrating additional endpoints into your app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;REST API Integration&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Experiment with connecting to public APIs, such as weather or news APIs.&lt;/li&gt;
&lt;li&gt;Use Angular’s &lt;code&gt;HttpClient&lt;/code&gt; to fetch data and display it dynamically in your app.&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Resource&lt;/strong&gt;: &lt;a href="https://angular.io/guide/http" rel="noopener noreferrer"&gt;Angular HTTPClient Guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CRUD Operations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a simple feature to Create, Read, Update, and Delete data using a RESTful API.&lt;/li&gt;
&lt;li&gt;Practice building forms for input, lists for data display, and edit/delete functionality.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn to handle API errors gracefully using Angular’s &lt;code&gt;catchError&lt;/code&gt; operator in &lt;code&gt;rxjs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Display user-friendly error messages for better usability.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Share Your Work
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy Your App&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Host your app using platforms like Firebase, Vercel, or Netlify.&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Resource&lt;/strong&gt;: &lt;a href="https://angular.io/guide/deployment" rel="noopener noreferrer"&gt;Angular Deployment Guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Collaborate with Others&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share your code on GitHub and invite feedback or contributions from the Angular community.&lt;/li&gt;
&lt;li&gt;Include a README file with setup instructions and a project overview.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 &lt;strong&gt;Next Steps&lt;/strong&gt;:&lt;br&gt;
Keep refining your app, experimenting with Angular’s features, and building more projects to deepen your understanding. Angular offers powerful tools to build dynamic and scalable web applications—mastering them is your next milestone!&lt;/p&gt;

&lt;h1&gt;
  
  
  Section 8: Conclusion
&lt;/h1&gt;

&lt;p&gt;You’ve come a long way! From setting up your development environment to building and testing your GPT-powered chat app, you’ve successfully taken your first steps into Angular development. Along the way, you’ve learned critical skills like creating components, managing services, and integrating APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You’ve Accomplished
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Built a Functional Angular App&lt;/strong&gt;: You created a GPT-powered chat interface using Angular's powerful framework and tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learned Angular Fundamentals&lt;/strong&gt;: From components to dependency injection, you’ve explored Angular’s core features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connected to External APIs&lt;/strong&gt;: You integrated a third-party API and handled HTTP requests and responses effectively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Followed Best Practices&lt;/strong&gt;: By using environment variables and secure development techniques, you’ve adopted professional coding standards.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Call to Action
&lt;/h2&gt;

&lt;p&gt;Your journey into Angular development has only just begun. Here’s how you can keep progressing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Practice Regularly&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build more projects to solidify your understanding of Angular concepts.&lt;/li&gt;
&lt;li&gt;Experiment with features like routing, state management, and animations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Explore Advanced Angular Topics&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn about lazy loading, optimizing performance, and testing Angular applications.&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Resource&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://angular.io/docs" rel="noopener noreferrer"&gt;Angular Advanced Topics&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://drive.google.com/file/d/1AwQLejCl1P3FHXME1eMlmj1sNbYEOxbL/view" rel="noopener noreferrer"&gt;Angular &amp;amp; AI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Join the Community&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engage with other Angular developers for inspiration and support.&lt;/li&gt;
&lt;li&gt;Contribute to open-source Angular projects to sharpen your skills.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Stay Updated&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular is a constantly evolving framework. Follow the official Angular blog and community channels to stay informed about new features and best practices.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Encouragement
&lt;/h2&gt;

&lt;p&gt;Starting something new can be daunting, but remember: &lt;strong&gt;every expert was once a beginner.&lt;/strong&gt; The effort you’ve put into learning Angular will pay off as you continue to build and grow. With the resources and knowledge you now have, you’re well-equipped to tackle more ambitious projects.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Keep Building&lt;/strong&gt;: The world of web development is vast and full of opportunities. Angular is just the beginning—dive deeper, experiment, and make your ideas come to life. Please feel free to ask questions if any or make contributions, you are highly welcomed!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Explore the Code&lt;/strong&gt;: The full source code for this project is available on &lt;a href="https://github.com/boluwatifee4/Angular-talk-openAi-Demo-app" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. Feel free to clone, modify, or contribute to the project!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>angular</category>
    </item>
    <item>
      <title>From Web2 to DeFi: Leveraging Liquidity Aggregation Tools for Seamless Integration: OneLiquidity</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Thu, 17 Oct 2024 20:51:07 +0000</pubDate>
      <link>https://dev.to/olabima_/from-web2-to-defi-leveraging-liquidity-aggregation-tools-for-seamless-integration-oneliquidity-2omk</link>
      <guid>https://dev.to/olabima_/from-web2-to-defi-leveraging-liquidity-aggregation-tools-for-seamless-integration-oneliquidity-2omk</guid>
      <description>&lt;p&gt;A big change is happening in the IT sector. It's not just a catchphrase; the transition from Web2's centralized models to Web3's decentralized promise is a revolution changing how we think about the Internet, banking, and digital connections. Decentralized Finance (DeFi) is at the vanguard of this movement, offering businesses and entrepreneurs previously unheard-of potential.&lt;/p&gt;

&lt;p&gt;Web2 developers and IT specialists may find it difficult to include DeFi features in existing projects. However, this integration can be easy and very fruitful if you have the correct resources and knowledge. This article explains how to use liquidity aggregation technologies such as &lt;a href="https://www.oneliquidity.com/" rel="noopener noreferrer"&gt;OneLiquidity&lt;/a&gt; to improve your platforms and maintain an advantage in the cutthroat IT industry by bridging the Web2 and DeFi gaps.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Section 1: The Evolution from Web2 to DeFi
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 Understanding Web2 and Its Limitations
&lt;/h3&gt;

&lt;p&gt;Web2 has been the backbone of the internet for over a decade, characterized by user-generated content, social media platforms, and centralized control of data. While it has enabled significant advancements, it also comes with limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Centralized Control:&lt;/strong&gt; A few entities hold the majority of control over data and platforms, leading to concerns about privacy and censorship.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability Issues:&lt;/strong&gt; Central servers can become bottlenecks, affecting performance and user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Innovation Constraints:&lt;/strong&gt; Centralization can stifle innovation due to gatekeeping and proprietary systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.2 Introduction to DeFi
&lt;/h3&gt;

&lt;p&gt;Enter Decentralized Finance (DeFi)—a movement that leverages blockchain technology to create an open, permissionless, and highly interoperable financial ecosystem. &lt;a href="https://www.coinbase.com/learn/crypto-basics/what-is-defi#:~:text=Definition,on%20public%20blockchains%2C%20primarily%20Ethereum." rel="noopener noreferrer"&gt;DeFi&lt;/a&gt; aims to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Eliminate Intermediaries:&lt;/strong&gt; By using smart contracts, DeFi removes the need for traditional financial middlemen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhance Transparency:&lt;/strong&gt; Transactions are recorded on public blockchains, ensuring transparency and trust.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promote Accessibility:&lt;/strong&gt; Anyone with an internet connection can access DeFi services, fostering financial inclusion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.3 Why Transition to DeFi
&lt;/h3&gt;

&lt;p&gt;For developers and businesses, embracing DeFi offers numerous benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Innovative Opportunities:&lt;/strong&gt; Create new financial products and services that were not possible in the Web2 paradigm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global Reach:&lt;/strong&gt; Access a global market without the limitations imposed by centralized platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Demand:&lt;/strong&gt; As users become more aware of data privacy and control, there's a growing demand for decentralized solutions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Section 2: The Role of Liquidity in DeFi Integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Importance of Liquidity
&lt;/h3&gt;

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

&lt;p&gt;In any financial system, liquidity refers to the ease with which assets can be bought or sold without causing significant price changes. High liquidity ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficient Markets:&lt;/strong&gt; Smooth execution of trades with minimal slippage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Pricing:&lt;/strong&gt; Competitive rates for buyers and sellers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market Stability:&lt;/strong&gt; Reduced volatility due to the availability of assets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Challenges with Liquidity in Decentralized Platforms
&lt;/h3&gt;

&lt;p&gt;Despite its advantages, DeFi faces liquidity challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fragmented Markets:&lt;/strong&gt; Liquidity is spread across multiple decentralized exchanges (DEXs), leading to inefficiencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slippage and Inefficiencies:&lt;/strong&gt; Low liquidity can cause significant price slippage, affecting trade execution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex Navigation:&lt;/strong&gt; Users and developers need to interact with multiple platforms to access sufficient liquidity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Liquidity Aggregation as a Solution
&lt;/h3&gt;

&lt;p&gt;Liquidity aggregation addresses these challenges by consolidating liquidity from various sources into a single platform. This approach offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Trade Execution:&lt;/strong&gt; Access to deeper liquidity pools reduces slippage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Integration:&lt;/strong&gt; Developers can tap into multiple liquidity sources through a single API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved User Experience:&lt;/strong&gt; Users benefit from better pricing and faster transaction times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Introducing OneLiquidity:&lt;/strong&gt; A leading liquidity aggregation tool that simplifies DeFi integration for developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Discover how &lt;a href="https://docs.oneliquidity.technology/" rel="noopener noreferrer"&gt;OneLiquidity&lt;/a&gt; can provide seamless access to aggregated liquidity pools for your projects.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Section 3: Leveraging Liquidity Aggregation Tools for Seamless Integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Benefits for Web2 Developers and Businesses
&lt;/h3&gt;

&lt;p&gt;Integrating liquidity aggregation tools into your projects brings several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplified DeFi Integration:&lt;/strong&gt; Reduce the complexity of connecting to multiple DEXs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced User Experience:&lt;/strong&gt; Offer users better pricing and faster transactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competitive Edge:&lt;/strong&gt; Stay ahead by adopting cutting-edge technologies that set your platform apart.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.2 Key Features of OneLiquidity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;OneLiquidity&lt;/strong&gt; stands out with features tailored for developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Developer-Friendly APIs and SDKs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Easy Integration:&lt;/strong&gt; Straightforward APIs allow for quick and efficient integration into your existing platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Language Support:&lt;/strong&gt; Compatible with various programming languages to suit your development environment.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Cross-Chain Compatibility&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Broad Network Access:&lt;/strong&gt; Interact with multiple blockchain networks, including Ethereum, Binance Smart Chain, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expanded Functionality:&lt;/strong&gt; Offer users access to a wider range of assets and services.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Smart Order Routing&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Optimized Trades:&lt;/strong&gt; Automatically find the best execution paths across different liquidity sources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Efficiency:&lt;/strong&gt; Minimizes transaction costs and maximizes value for users.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.3 Integration Process Overview
&lt;/h3&gt;

&lt;p&gt;Integrating OneLiquidity into your project is straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.oneliquidity.com/sign-up/" rel="noopener noreferrer"&gt;Sign Up:&lt;/a&gt; Create an account on the OneLiquidity platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access the Developer Portal&lt;/strong&gt;: Obtain your API keys and access documentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrate the APIs:&lt;/strong&gt; Use the provided SDKs and code samples to integrate into your application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test and Deploy:&lt;/strong&gt; Utilize sandbox environments for testing before going live.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Ready to integrate DeFi into your platform effortlessly? Visit the &lt;a href="https://docs.oneliquidity.technology/reference/intro/my-requests" rel="noopener noreferrer"&gt;OneLiquidity Developer Portal&lt;/a&gt; to get started.&lt;/p&gt;

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

&lt;p&gt;The integration of DeFi functionalities into Web2 platforms is no longer a futuristic concept—it's a present-day opportunity that can redefine your business and development projects. By leveraging liquidity aggregation tools like OneLiquidity, you can seamlessly bridge the gap between traditional web technologies and the decentralized finance revolution.&lt;/p&gt;

&lt;p&gt;Embracing these tools not only enhances your platform's capabilities but also positions you at the forefront of technological innovation. With improved user experiences, access to global markets, and the ability to create novel financial products, the benefits are substantial.&lt;/p&gt;

&lt;p&gt;Transform your development journey and stay ahead in the evolving tech landscape.&lt;/p&gt;

&lt;p&gt;👉 Embrace the future of finance today. Integrate with OneLiquidity and transform your platform with cutting-edge DeFi capabilities. &lt;a href="https://www.oneliquidity.com/sign-up/" rel="noopener noreferrer"&gt;Get Started Now&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Integrate Fingerprint and Face ID Authentication in Your Angular App Using WebAuthn: A Step-by-Step Guide</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Thu, 05 Sep 2024 09:50:27 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/integrate-fingerprint-and-face-id-authentication-in-your-angular-app-using-webauthn-a-step-by-step-guide-3o2b</link>
      <guid>https://dev.to/playfulprogramming-angular/integrate-fingerprint-and-face-id-authentication-in-your-angular-app-using-webauthn-a-step-by-step-guide-3o2b</guid>
      <description>&lt;p&gt;Let’s be honest—we’ve all wished we could log into websites using our fingerprints or Face ID, just like on mobile apps, right? Well, thanks to web biometrics, that dream isn’t so far-fetched anymore. Imagine ditching those long, complicated passwords and simply using our fingerprint or face to sign in to our favorite websites. Sounds cool, doesn’t it?&lt;/p&gt;

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

&lt;p&gt;Web biometrics, powered by WebAuthn, is making this possible. It's a fancy name for something quite simple: authenticating us with the same kind of security as our phone’s fingerprint sensor or facial recognition, but directly in our web browser. No more worrying about passwords getting leaked or stolen—just a quick scan, and we’re in.&lt;/p&gt;

&lt;p&gt;In this tutorial, we’re going to get hands-on with integrating fingerprint and Face ID login into our Angular apps. We’ll cover the essentials, like how the WebAuthn API works and what we need to do on the backend to keep everything secure and smooth. It’s easier than you might think, and by the end, we’ll have our app all set up for the future of authentication. So, let’s dive in and make logging in a breeze!&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding WebAuthn: The Basics for Fingerprints and Face-recognition in Angular Apps
&lt;/h2&gt;

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

&lt;p&gt;Alright, before we jump into the code, let’s get a quick handle on what WebAuthn is all about. Think of WebAuthn as the bridge that connects our apps to the cool biometric features we love on our phones—like fingerprints and Face ID—right in our browsers. It uses public key cryptography to authenticate users, which means no more storing plain old passwords that hackers can easily snatch up. Instead, we’re talking about securely generated keys that make our logins both safe and seamless.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Objects and Their Roles
&lt;/h3&gt;

&lt;p&gt;To get things rolling, we need to understand a couple of key players in the WebAuthn game: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions" rel="noopener noreferrer"&gt;PublicKeyCredentialCreationOptions&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialRequestOptions" rel="noopener noreferrer"&gt;PublicKeyCredentialRequestOptions&lt;/a&gt;. Don’t let the long names scare you—they’re just fancy ways to tell the browser how we want to register and authenticate users. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. PublicKeyCredentialCreationOptions
&lt;/h3&gt;

&lt;p&gt;This is our go-to object when setting up new user credentials. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;challenge&lt;/strong&gt;: A unique, random value generated by the server to ensure the response is fresh and can’t be reused.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;rp&lt;/strong&gt;: Stands for Relying Party (our app) and includes details like the app’s name and ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;user&lt;/strong&gt;: Info about the user, like a unique ID, username, and display name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pubKeyCredParams&lt;/strong&gt;: A list of public key algorithms we’ll allow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;authenticatorSelection&lt;/strong&gt;: Helps us choose the right type of authenticator based on things like attachment type (platform or cross-platform) and user verification level.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. PublicKeyCredentialRequestOptions
&lt;/h3&gt;

&lt;p&gt;When it’s time to verify our users, this object takes the spotlight. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;challenge&lt;/strong&gt;: Just like before, this ensures our authentication request is fresh and unique.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;allowCredentials&lt;/strong&gt;: Specifies which credentials are allowed for the user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;userVerification&lt;/strong&gt;: Dictates whether user verification (like a fingerprint scan) is required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these objects in hand, our Angular app will be able to guide users through registering their biometric data and authenticating quickly and securely. Next, we’ll get into the code and see how to make this magic happen in our app!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Angular App
&lt;/h2&gt;

&lt;p&gt;In this section, we’ll guide you through setting up an Angular application with biometric authentication using WebAuthn. We’ll focus on using fingerprints and Face ID, so let's get our hands dirty!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Setting Up Our Angular Project
&lt;/h3&gt;

&lt;p&gt;To get started, let’s create a new Angular project. Open your terminal and type the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng new web-biometrics-demo
&lt;span class="nb"&gt;cd &lt;/span&gt;web-biometrics-demo
ng serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sets up a basic Angular application, and running &lt;code&gt;ng serve&lt;/code&gt; will start your app on &lt;code&gt;http://localhost:4200/&lt;/code&gt;. You should see the default Angular welcome page. Now, we’re ready to integrate WebAuthn for biometric authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Creating the WebAuthn Service
&lt;/h3&gt;

&lt;p&gt;We need a service in Angular to manage all our WebAuthn functionality, including registration and authentication using biometrics. Let’s create this service by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate service services/webauthn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, open &lt;code&gt;webauthn.service.ts&lt;/code&gt; and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WebAuthnService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

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

  &lt;span class="c1"&gt;// Generates a random buffer to use as a challenge, which is a unique value needed for security&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;generateRandomBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Uint8Array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;randomBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Fills the buffer with cryptographically secure random values&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;randomBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Registers a new credential (like a fingerprint or Face ID) for the user&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Generate a unique challenge for the registration process&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;challenge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateRandomBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// PublicKeyCredentialCreationOptions is the core object needed for registration&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PublicKeyCredentialCreationOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// A random value generated by the server to ensure the request is fresh and unique&lt;/span&gt;
      &lt;span class="na"&gt;rp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Relying Party (your app) information&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OurAwesomeApp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// Display name of your app&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// User information&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateRandomBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// A unique identifier for the user&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// User's email or username&lt;/span&gt;
        &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User Example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// A friendly name for the user&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;pubKeyCredParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="c1"&gt;// Array of acceptable public key algorithms&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;alg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;  &lt;span class="c1"&gt;// Represents the ES256 algorithm (Elliptic Curve Digital Signature Algorithm)&lt;/span&gt;
      &lt;span class="p"&gt;}],&lt;/span&gt;
      &lt;span class="na"&gt;authenticatorSelection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Criteria for selecting the appropriate authenticator&lt;/span&gt;
        &lt;span class="na"&gt;authenticatorAttachment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;platform&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Ensures we use the device's built-in biometric authenticator like Touch ID or Face ID&lt;/span&gt;
        &lt;span class="na"&gt;userVerification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// Requires user verification (e.g., fingerprint or face scan)&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Timeout for the registration operation in milliseconds&lt;/span&gt;
      &lt;span class="na"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;direct&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// Attestation provides proof of the authenticator's properties and is sent back to the server&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// This will prompt the user to register their biometric credential&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;PublicKeyCredential&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;storeCredential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Store the credential details locally for demo purposes&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Registration successful!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Return the credential object containing the user's public key and other details&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Registration failed:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Handle any errors that occur during registration&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Authenticates the user with stored credentials (like a fingerprint or Face ID)&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storedCredential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStoredCredential&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Retrieve stored credential information&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;storedCredential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No stored credential found. Please register first.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Error if no credentials are found&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// PublicKeyCredentialRequestOptions is used to prompt the user to authenticate&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PublicKeyCredentialRequestOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storedCredential&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// A new challenge to ensure the request is fresh and unique&lt;/span&gt;
      &lt;span class="na"&gt;allowCredentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="c1"&gt;// Specifies which credentials can be used for authentication&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storedCredential&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rawId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// The ID of the credential to use&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}],&lt;/span&gt;
      &lt;span class="na"&gt;userVerification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Requires user verification (e.g., fingerprint or face scan)&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt; &lt;span class="c1"&gt;// Timeout for the authentication operation in milliseconds&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// This will prompt the user to authenticate using their registered biometric credential&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;PublicKeyCredential&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authentication successful!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Return the credential object with authentication details&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authentication failed:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Handle any errors that occur during authentication&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Stores credential data in localStorage (for demo purposes only; this should be handled securely in production)&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;storeCredential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PublicKeyCredential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;credentialData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;rawId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rawId&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="c1"&gt;// Converts the raw ID to an array for storage&lt;/span&gt;
      &lt;span class="na"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Converts the challenge to an array for storage&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webauthn_credential&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credentialData&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Store the data as a JSON string&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Retrieves stored credential data from localStorage&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;getStoredCredential&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storedCredential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webauthn_credential&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;storedCredential&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storedCredential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Parse the stored JSON back into an object&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What’s Happening in the Code?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;generateRandomBuffer&lt;/code&gt;: Creates a random buffer that serves as a challenge to ensure each authentication or registration request is unique.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;register&lt;/code&gt;: This method sets up the biometric registration process. It uses &lt;code&gt;PublicKeyCredentialCreationOptions&lt;/code&gt; to define parameters like the &lt;code&gt;challenge&lt;/code&gt;, &lt;code&gt;relying party&lt;/code&gt; (your app), user information, and acceptable public key algorithms. When &lt;code&gt;navigator.credentials.create()&lt;/code&gt; is called, the browser prompts the user to register their biometric data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;authenticate&lt;/code&gt;: This method handles user authentication with biometrics. It uses &lt;code&gt;PublicKeyCredentialRequestOptions&lt;/code&gt; to define the authentication challenge and credentials that can be used. The method prompts the user to authenticate with their registered biometrics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;storeCredential&lt;/code&gt; and &lt;code&gt;getStoredCredential&lt;/code&gt;: These methods handle storing and retrieving credentials in &lt;code&gt;localStorage&lt;/code&gt; for demonstration purposes. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a real-world app, you’d securely store this information on your backend.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Building the UI
&lt;/h3&gt;

&lt;p&gt;Now, let’s create a basic UI with buttons to trigger the registration and login functions. This UI will provide feedback based on whether the registration or login was successful.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;app.component.ts&lt;/code&gt; and replace the content with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebAuthnService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./services/webauthn.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div class="auth-container"&amp;gt;
      &amp;lt;h1&amp;gt;Web Biometrics in Angular&amp;lt;/h1&amp;gt;
      &amp;lt;button (click)="register()"&amp;gt;Register with Fingerprint&amp;lt;/button&amp;gt;
      &amp;lt;button (click)="login()"&amp;gt;Login with Face ID&amp;lt;/button&amp;gt;
      &amp;lt;p *ngIf="message" [ngClass]="{'success': isSuccess, 'error': !isSuccess}"&amp;gt;{{ message }}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`
    .auth-container {
      text-align: center;
      padding: 50px;
    }
    .success {
      color: green;
    }
    .error {
      color: red;
    }
    button {
      margin: 10px;
      padding: 10px 20px;
      font-size: 16px;
    }
    p {
      margin: 10px;
      font-size: 16px;
    }
  `&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Message to display feedback to the user&lt;/span&gt;
  &lt;span class="nl"&gt;isSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Indicates if the last action was successful&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;webAuthnService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;WebAuthnService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Trigger registration process and update the UI based on the outcome&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webAuthnService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Registration successful!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success message if registration works&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Registration failed. Please try again.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Error message if something goes wrong&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Trigger authentication process and update the UI based on the outcome&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webAuthnService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authentication successful!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success message if authentication works&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authentication failed. Please try again.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Error message if something goes wrong&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What’s Happening in the Component?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;register&lt;/code&gt; and &lt;code&gt;login methods&lt;/code&gt;: These methods call the respective register and authenticate methods from the &lt;code&gt;WebAuthnService&lt;/code&gt;. If successful, a success message is displayed; otherwise, an error message is shown.&lt;/p&gt;

&lt;p&gt;Template and Styling: The template includes buttons to trigger registration and login, and it displays messages to the user based on the operation's outcome. The buttons are styled for simplicity.&lt;/p&gt;

&lt;p&gt;That’s it! We’ve built a basic Angular app with WebAuthn-based biometric authentication, supporting fingerprints and Face ID. This setup captures the core concepts and lays a foundation that can be expanded with additional features and security measures for a production environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backend Considerations
&lt;/h2&gt;

&lt;p&gt;When implementing biometric authentication like fingerprints or Face ID in web applications using WebAuthn, the backend plays a crucial role in managing the security and flow of data. Here’s a breakdown of how the backend processes work in theory, focusing on registration and login functionalities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registration: Sign-up
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. User Registration Flow:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Data Capture&lt;/strong&gt;: During registration, the user provides basic credentials, such as an email and password. If biometric data is also being registered, this is captured as part of the WebAuthn response.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Password Hashing&lt;/strong&gt;: For security, passwords are never stored in plain text. Instead, they are hashed using a library like bcrypt before being stored in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Storing WebAuthn Credentials&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Challenge Handling&lt;/strong&gt;: The server sends a challenge during the registration process, which is a randomly generated value to prevent replay attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Validation&lt;/strong&gt;: When the client responds with the WebAuthn data, it includes clientDataJSON and attestationObject that need to be decoded and verified.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credential Storage&lt;/strong&gt;: After validation, key data from the response—like the webauthnId (a unique identifier for the credential) and the publicKey (used to verify future authentications)—are stored in the database alongside the user record.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Backend Code Responsibilities:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The backend uses libraries like cbor to decode binary data formats from the WebAuthn response, extracting necessary elements like the public key and authenticator data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It ensures that the challenge from the initial registration request matches what is returned in the WebAuthn response to verify the authenticity of the registration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the WebAuthn response passes all checks, the credentials are saved in the database, linked to the user account.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Login
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. User Login Flow:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Challenge Generation&lt;/strong&gt;: Similar to registration, the server generates a &lt;code&gt;challenge&lt;/code&gt; that must be responded to by the client’s authenticator during login.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Validating the WebAuthn Response&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client sends back a PublicKeyCredentialRequestOptions object containing the response to the challenge.&lt;/li&gt;
&lt;li&gt;The backend decodes and verifies this response, ensuring that the challenge and the credentials match what is stored in the database.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Credential Verification&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The public key stored during registration is used to verify the signature in the login response.&lt;/li&gt;
&lt;li&gt;If the credentials match, the backend allows the login and generates an authentication token (like a JWT) for the session.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Error Handling:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mismatch or Invalid Response&lt;/strong&gt;: If the challenge response does not match the expected values, or if the WebAuthn credentials do not verify correctly, the backend responds with an error, preventing unauthorized access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fallback to Password&lt;/strong&gt;: If WebAuthn fails or is unavailable, the system can revert to traditional password verification, ensuring users can still access their accounts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Integrity&lt;/strong&gt;: The integrity of WebAuthn credentials is critical. Any modification in storage or transmission would cause verification to fail, thereby securing the authentication process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Challenge Nonces&lt;/strong&gt;: The use of unique, time-limited challenges ensures that responses cannot be reused, protecting against replay attacks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Public Key Storage&lt;/strong&gt;: Storing only public keys (which cannot be used to impersonate the user) enhances security, as private keys remain on the client device.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these principles, the backend effectively manages biometric authentication, ensuring a secure, seamless experience for users wanting to use features like fingerprint or Face ID in their Angular apps.&lt;/p&gt;

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

&lt;p&gt;In this tutorial, we walked into integrating biometric authentication with Angular using WebAuthn. We covered the essentials, from understanding key WebAuthn objects like &lt;code&gt;PublicKeyCredentialCreationOptions&lt;/code&gt; and &lt;code&gt;PublicKeyCredentialRequestOptions&lt;/code&gt; to setting up Angular services and UI components for a smooth registration and login process. We also discussed the backend considerations necessary for handling biometric authentication securely.&lt;/p&gt;

&lt;p&gt;For those eager to see WebAuthn in action, I have provided a demo and a repository with a complete implementation. You can check out the demo &lt;a href="https://ng-bima-fingerprint-web-authn.netlify.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and explore the source code on GitHub at this &lt;a href="https://github.com/boluwatifee4/ng-fingerprint-web-auth" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Embracing biometric authentication not only enhances security but also simplifies the user experience, paving the way for a future where logging in is as easy as a fingerprint scan or a quick face recognition. As you integrate these features into your Angular apps, you'll be contributing to a more secure and user-friendly web. Happy coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>webbiometrics</category>
    </item>
    <item>
      <title>What are Angular Signals?: Exploring State Control and Rendering in Angular Apps</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Mon, 17 Jul 2023 20:29:44 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/what-are-angular-signals-exploring-state-control-and-rendering-in-angular-apps-4e5e</link>
      <guid>https://dev.to/playfulprogramming-angular/what-are-angular-signals-exploring-state-control-and-rendering-in-angular-apps-4e5e</guid>
      <description>&lt;p&gt;The ability to create stable and feature-rich web applications has made Angular, a potent JavaScript framework, extremely popular. Managing states becomes a crucial part of development as applications become more complex. Angular Signals can be used in this situation. Within Angular applications, signals offer a method for effectively managing state and improving rendering updates.&lt;/p&gt;

&lt;p&gt;Developers can take fine-grained control over state changes by utilizing Signals, which enables Angular to optimize rendering updates for faster performance and a seamless user experience. We will examine the foundations of Angular Signals in this article, along with their types and applications. We will delve into real-world scenarios and code snippets to demonstrate the advantages of utilizing Angular Signals for state management and rendering optimization in our Angular applications. Let's get started and see how Signals can transform the way we manage state and optimize rendering updates, resulting in Angular applications that are more effective and reactive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is important to note that the Angular signal is a new update that is usable only when we have the new &lt;a href="https://blog.angular.io/angular-v16-is-here-4d7a28ec680d" rel="noopener noreferrer"&gt;Angular 16&lt;/a&gt; version installed or running.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hands-on experience with Angular&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic knowledge of Angular's Reactive principles&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Importance of Signals in Angular Apps
&lt;/h2&gt;

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

&lt;p&gt;Angular Signals play an important role in state management and rendering optimization in Angular applications, providing distinct advantages over other reactive primitives such as RxJS and Co. The importance of Angular Signals lies in their lazily evaluated and memoized computed Signals, automatic dependency tracking, simplified state updates, granular state tracking, and change detection integration. Signals give developers granular control over state changes, allowing for more effective and focused state management.&lt;/p&gt;

&lt;p&gt;The writable Signals make updating state values simpler without requiring difficult operations. By only launching necessary updates, automatic dependency tracking optimizes rendering performance. Computed signals that have been hastily evaluated and memorized save time by avoiding unnecessary calculations. The efficient updates in &lt;code&gt;OnPush&lt;/code&gt; components are ensured by the integration with Angular's change detection. Angular Signals is a useful tool for state management and rendering optimization in Angular applications because of these benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Angular Signals?
&lt;/h2&gt;

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

&lt;p&gt;We appear to have begun defining what angular signals are in the preceding sections, but let us first define what a signal is. Assume we are in a room with people who cannot hear or speak, and we can only communicate with them by using signs with our hands and expression. For example, if we need to tell them to stand on their feet, we do so by sequentially moving our hands upwards, they get the sign, and then stand on their feet, and so on. We have signaled to them with our hands, causing them to change their current state from sitting to standing.&lt;/p&gt;

&lt;p&gt;Angular signals work in the same way; we have a variable written as a signal, and when we update it, the signal catches it and automatically updates the variable, resulting in reactivity. Signals in angular, on the other hand, are variables that store a variable and provide a signal or notification whenever the variable is updated.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create and use Angular Signals
&lt;/h2&gt;

&lt;p&gt;Now that we know what signals are and why they are important, we can look at how to use them in our angular applications. In its version 16 release, the angular team included three (3) reactive primitives (signals):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Writable Signals&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Computed Signals&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Effects&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are the primary primitives for using Signals to achieve reactivity in angular applications. However, let us go a step further and learn how to combine and use the aforementioned primitives.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We can check out this article's Stackblitz project &lt;a href="https://stackblitz.com/edit/io-signals-codelab-starter-y6wunb?file=src%2FourFirstSignal%2FlearningSignal.ts" rel="noopener noreferrer"&gt;here&lt;/a&gt; for a better understanding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1. Writable Signals
&lt;/h3&gt;

&lt;p&gt;Writable signals are Angular signals whose values can be directly updated. They are essentially pre-defined signals. A signal must be defined or created before it can be written to, updated, or read. To have a writable signal, we must first define it. However, defining or creating a signal is not a difficult process; consider the code below to see how a signal is defined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// defination of a signal&lt;/span&gt;
&lt;span class="nx"&gt;our_first_signal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above line of code is the technical demonstration of how to define or create a signal. We create a property named &lt;code&gt;our_first_signal&lt;/code&gt;, we then assign the &lt;code&gt;signal()&lt;/code&gt; function, provided by the &lt;a href="https://twitter.com/angular" rel="noopener noreferrer"&gt;angular team&lt;/a&gt; with an initial value of 0, hence making the property &lt;code&gt;our_first_signal&lt;/code&gt; a signal and not a normal property.&lt;/p&gt;

&lt;p&gt;Generally, signals are getter functions hence, to read the value of our defined signal we would need to call the signal like we would call a function. The lines of code below demonstrate how to read the value from a signal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//reading the value of signal&lt;/span&gt;
&lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Our first signal:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;our_first_signal&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
 &lt;span class="c1"&gt;// returns 0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above line of code, we have a &lt;code&gt;console.log&lt;/code&gt; statement that logs the value of the signal that we are reading by calling it.&lt;/p&gt;

&lt;p&gt;So far we have defined a signal and read its value. Now let us get to the interesting part of updating or writing to the signal. Let us take for example we want to update the value of our signal from 0 to 5, how do we go about this? Thanks to the angular team, we can use the &lt;code&gt;set()&lt;/code&gt; or &lt;code&gt;update()&lt;/code&gt; method to change or update our signal. The &lt;code&gt;update()&lt;/code&gt; method modifies the signal based on its current value while the &lt;code&gt;set()&lt;/code&gt; method changes the value of a signal. Let us examine the following lines of code below for a better understanding of how to use these methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt; &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;our_first_signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// or&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;our_first_signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Our first signal:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;our_first_signal&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="c1"&gt;// expected results: 10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;set()&lt;/code&gt; method, we set the value of &lt;code&gt;our_first_signal&lt;/code&gt; signal to 8, as shown in the code above. In the second line, we use the &lt;code&gt;update()&lt;/code&gt; method to add 2 to the value of &lt;code&gt;our_first_signal&lt;/code&gt;. The update method accepts a callback function as an argument, which is called with the current value of the signal, and the callback function's return value is set as the new value of the signal. The value of &lt;code&gt;our_first_signal&lt;/code&gt; is logged to the console in the third line.&lt;/p&gt;

&lt;p&gt;It is important to note that signals also work with strings, numbers, arrays, and objects. When working with either arrays or strings, situations may require updating a particular property while maintaining other values in the array. To achieve this, the angular team has a &lt;code&gt;mutate()&lt;/code&gt; method that changes the content of a signal value rather than the value itself. Let us take for example we have an array of objects with properties &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;age&lt;/code&gt; and we want to update the &lt;code&gt;age&lt;/code&gt; property while retaining the value of &lt;code&gt;name&lt;/code&gt; we would use the &lt;code&gt;mutate()&lt;/code&gt; method to do this. Let us carefully examine the lines of code below to understand the technical application of the &lt;code&gt;mutate()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// creating the signal&lt;/span&gt;

 &lt;span class="nx"&gt;persons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// using the mutate() method to replace the first object's age to 21&lt;/span&gt;

&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// reading our signal by calling and logging it to the console&lt;/span&gt;
&lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;personsSignal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We created a signal called &lt;code&gt;persons&lt;/code&gt; and assigned it an array of objects in the preceding code. We then used the &lt;code&gt;mutate()&lt;/code&gt; method to change the &lt;code&gt;age&lt;/code&gt; of the first object to 21. Finally, we called the signal and recorded it on the console. The console's output can be seen in the image below.&lt;/p&gt;

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

&lt;p&gt;As we can see, the age of the first object has been replaced with 21. This is because the mutate() method is used to change the signal's value. A callback function is passed as an argument to the mutate() method. The callback function takes the current signal value as an argument and returns the new signal value.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Computed Signals: Getting Dynamic Values
&lt;/h3&gt;

&lt;p&gt;Computed signals are a powerful tool in Angular applications for deriving values from other signals. When calculating derived values, computed signals are lazily evaluated and memoized, resulting in efficient and reactive behavior.&lt;/p&gt;

&lt;p&gt;We use the &lt;code&gt;computed()&lt;/code&gt; function with a derivation function as its argument to create a computed signal. Let's look at some code samples to see how computed signals work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create two signals: price and quantity&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Create a computed signal for total cost based on price and quantity&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;totalCost&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Output: 50&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We created two signals, &lt;code&gt;price&lt;/code&gt;, and &lt;code&gt;quantity&lt;/code&gt;, in the code above to represent the price and quantity of a product.&lt;/p&gt;

&lt;p&gt;Following that, we define a computed signal named &lt;code&gt;totalCost&lt;/code&gt;. The total cost is calculated by multiplying the values of the price and quantity signals. Only when the computed signal is read for the first time or when its dependencies (&lt;code&gt;price&lt;/code&gt; or &lt;code&gt;quantity&lt;/code&gt;) changes will it perform this calculation.&lt;/p&gt;

&lt;p&gt;Finally, we log the value of &lt;code&gt;totalCost&lt;/code&gt; to the console, which in this case is 50 based on the initial price and quantity values.&lt;/p&gt;

&lt;p&gt;The ability of computed signals to handle complex calculations and transformations is a notable advantage. Consider the following scenario: we have a signal that represents an array of products, and we want to compute the total value of all products:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// Create a signal for the array of products&lt;/span&gt;
  &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product B&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product C&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Create a computed signal for total value based on products&lt;/span&gt;
 &lt;span class="nx"&gt;totalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;products&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//reading the signal&lt;/span&gt;
&lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;computed2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;totalValue&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Output: 45&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we define a signal called &lt;code&gt;products&lt;/code&gt;, which represents an array of products and their prices. The computed signal, &lt;code&gt;totalValue&lt;/code&gt; is then created, which uses the &lt;code&gt;reduce()&lt;/code&gt; method to calculate the sum of all product prices in the array.&lt;/p&gt;

&lt;p&gt;We can easily calculate the total value of the products by using computed signals, regardless of changes in individual product prices.&lt;/p&gt;

&lt;p&gt;Overall, computed signals offer a declarative and effective method of handling derived values. By avoiding pointless calculations, their hastily evaluated and memoized nature ensures optimal performance. With computed signals, we can keep our application responsive and effective while carrying out complicated computations, filtering data, or producing derived values from other signals.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Effects: Reacting to Signal Changes
&lt;/h3&gt;

&lt;p&gt;Effects are methods that take place whenever the values of one or more signals change. Effects offer a practical way to respond to changes in the signal and carry out additional tasks or actions in response to those changes. Let's investigate effects more thoroughly with the aid of some code examples.&lt;/p&gt;

&lt;p&gt;We employ the &lt;code&gt;effect()&lt;/code&gt; function and supply a callback function as its argument to produce an effect. The action that needs to be taken whenever the dependent signals change is represented by this callback function. Let's use a real-world example to demonstrate how effects work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// Create a signal for user authentication status&lt;/span&gt;
     &lt;span class="nx"&gt;isAuthenticated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Create an effect to perform actions based on authentication status&lt;/span&gt;
    &lt;span class="c1"&gt;// Place in ngOninit &lt;/span&gt;
    &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isAuthenticated&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User is authenticated. Redirecting to dashboard...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
           &lt;span class="c1"&gt;// Code to redirect to the dashboard can be added here&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User is not authenticated. Redirecting to login page...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="c1"&gt;// Code to redirect to the login page can be added here&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
          &lt;span class="c1"&gt;// Simulate authentication status change&lt;/span&gt;
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAuthenticated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this illustration, the authentication status of a user is represented by a signal called &lt;code&gt;isAuthenticated&lt;/code&gt;. The effect is triggered when the &lt;code&gt;isAuthenticated&lt;/code&gt; signal changes and, depending on the authentication status, takes particular actions.&lt;/p&gt;

&lt;p&gt;We determine the value of &lt;code&gt;isAuthenticated&lt;/code&gt; inside the callback function for the effect. We log a message to the console and redirect to the dashboard page if it is true, indicating that the user has been authenticated. We log a different message and direct the user to the login page, however, if the &lt;code&gt;isAuthenticated&lt;/code&gt; value is false, indicating that the user is not authenticated.&lt;/p&gt;

&lt;p&gt;The use of effects to respond to changes in authentication status and initiate corresponding actions in our Angular application is illustrated by the example given here. It demonstrates the adaptability of effects in handling a variety of scenarios, like user authentication, and lets us include custom logic to meet the requirements of our application.&lt;/p&gt;

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

&lt;p&gt;In this article, we looked at how Angular Signals play an important role in state management and rendering optimization in Angular applications. Developers gain precise control over state changes by using Signals, resulting in improved performance and reactivity. These Signals, which include writable signals, computed signals, and effects, provide benefits such as granular state tracking, simplified updates, automatic dependency tracking, and computed values that are evaluated lazily. Using Angular Signals allows developers to build stable, feature-rich web applications that provide a consistent user experience. Using Signals in Angular development projects allows us to realize the full potential of state management and rendering optimization, improving application performance and maintainability.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>angular</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>4 Best Code Practices for Creating a Responsive Website</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Sat, 24 Jun 2023 20:03:57 +0000</pubDate>
      <link>https://dev.to/olabima_/4-best-code-practices-for-creating-a-responsive-website-la6</link>
      <guid>https://dev.to/olabima_/4-best-code-practices-for-creating-a-responsive-website-la6</guid>
      <description>&lt;p&gt;It's a pleasure to have you here as we explore the "4 Best Code Practices for Creating a Responsive Website." You've come to the right place if you want to improve your web development abilities and make sure that your websites work properly on a variety of devices and screen sizes. Join me as we examine the essential tactics and strategies for creating user-friendly, responsive websites. Let's begin code optimization for a fantastic user experience on all devices!&lt;/p&gt;

&lt;p&gt;Before we begin looking at code optimizations and other code-related applications, let us take a look at why it is needed to build websites that look good on various screen sizes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is Responsiveness crucial in Web design and performance?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--psiQT_m6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwagl9lfja8dfa8nkhlo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--psiQT_m6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwagl9lfja8dfa8nkhlo.png" alt="curios image" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using a responsive design strategy, you can make sure that a website will function properly and adapt to different devices and screen sizes. The website dynamically modifies its layout, images, and content to offer the best user experience, fully aware that responsive design entails creating a website that responds to its environment.&lt;/p&gt;

&lt;p&gt;The ability of responsiveness to improve user experience, increase search engine visibility, and increase conversion rates makes it crucial. A responsive design makes sure that your website is accessible and aesthetically pleasing on all the devices that your audience uses, despite the increasing dominance of mobile devices and the constantly shifting technological landscape. The responsive design encourages greater engagement, lowers bounce rates, and increases general customer satisfaction by providing a consistent and user-friendly experience. In the end, investing in responsive design ensures that your website is future-proof and can easily adapt to new devices and screen sizes as they are developed, which will be advantageous for your company in the long run.&lt;/p&gt;

&lt;p&gt;Having known this, let us go ahead to discuss the 4 best code practices to follow when building a responsive web page for better web performance in the section below.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 4 Best Code Practices for Creating a Responsive Web Design.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Proper Page Layouting
&lt;/h3&gt;

&lt;p&gt;Most websites have a header at the top that includes the logo, navigation menu, and a few other menus. which could be positioned to take up the entire width of the screen, the left, the center, or both, followed by the hero section, and so on.&lt;/p&gt;

&lt;p&gt;Moreover, Page Layouting is the process of arranging and positioning these various elements on a web page to produce a high-quality content rendering that is visually appealing to users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/3YW65K6LcIA"&gt;Flexbox&lt;/a&gt; and &lt;a href="https://youtu.be/0xMQfnTU6oo"&gt;Grid&lt;/a&gt; systems are primarily used in web design to position layouts. These are effective layout systems with unique strengths and functions. The key to choosing which system to use in any given situation is to have a thorough understanding of how both of them operate. Once we have this understanding, we can move forward and start the act of proper page layout.&lt;/p&gt;

&lt;p&gt;The CSS Flexbox system is great for making responsive designs, vertical centering, and handling dynamically expanding or contracting content. While the CSS Grid, with its capacity to manage both rows and columns simultaneously, is well-suited for overall page layouts. It supports responsive grid structures, grid alignment, spanning, and placing objects within particular cells.&lt;/p&gt;

&lt;p&gt;The CSS Flexbox systems, as is well known, have many different properties, including &lt;code&gt;flex-direction&lt;/code&gt;, &lt;code&gt;justify-content&lt;/code&gt;, and &lt;code&gt;flex-wrap&lt;/code&gt;. With these characteristics and simulation using CSS Media Queries, we are not far from achieving a completely responsive layout. As a result, it is the easiest layout system to use when designing not overly complicated layouts. Let's say that on large screens, two elements are placed side by side; however, on smaller screens, these elements are compressed and appear squeezed. On smaller screens, however, we prefer that these components stack one on top of the other for convenience. How do we proceed with this? This is accomplished by setting the flex-direction property to row on big screens and column on smaller ones. For a better understanding, let's look at the code illustration below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.contents&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nc"&gt;.contents&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@media&lt;/code&gt; rule was used in the code above to apply various styles for various media types and devices to the contents class. This means that the contents class will have the &lt;code&gt;flex-direction: column;&lt;/code&gt; property applied to it if the screen size is less than 600px. Additionally, the contents class will have the &lt;code&gt;flex-direction: row;&lt;/code&gt; property applied to it if the screen size is greater than 600px. making the contents appear on smaller screens in a column and on larger screens in a row.&lt;/p&gt;

&lt;p&gt;It is crucial to remember that CSS Flexbox also provides other styling options, including the &lt;code&gt;flex-wrap&lt;/code&gt; property, to enable the creation of fluid, responsive layouts. Since the &lt;code&gt;flex-wrap&lt;/code&gt; property regulates how flex items are wrapped or displayed when they exceed the available space within a flex container along the main axis, applying it to the logic in the previous explanation would eliminate the need for media queries. In this manner, the elements adapt automatically as our screen size changes, producing the desired responsive response.&lt;/p&gt;

&lt;p&gt;Overall, it is significant to note that a thorough understanding of the CSS Grid and Flexbox systems is crucial to achieving proper page layout because it will aid in the proper structuring of divs and provide knowledge of when to use Flexbox or Grid.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Embracing Percentage for Width Sizes
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RvtzJzog--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v78dimg1potd8vr0hewp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RvtzJzog--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v78dimg1potd8vr0hewp.png" alt="percentage for responsive web-design" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are quite familiar with setting sizes for the widths of images, sections, elements, and other components as front-end engineers and UI/UX designers. Then as we move forward with our development, particularly on the part of frontend engineers who write the code, we would notice that when we adjust screen sizes into smaller and smaller pixels, we tend to have problems with the page having an excessive width that causes a scroll bar to appear at the bottom of the screen. Yes, of course. The interesting part is that, despite the fact that most browsers use pixels (px) as their standard unit of measurement, we can still think of our computer's screen as a space that is 100% wide and tall. This means that regardless of whether the screen size decreases or increases, the width, and height remain at 100%.&lt;/p&gt;

&lt;p&gt;As a result, problems with elements or divs having extra width are lessened or completely resolved, assisting in the creation of a responsive layout. Let's say we have two adjacent div elements. To prevent extra width issues and ensure that they maintain the screen's width across all devices, we would set the width of the aforementioned elements or divs to 50%. This indicates that these elements or divs should take up 50% of the full screen on any screen size or device. And keep in mind that, as was already mentioned, the measurement for the entire HTML page remains at 100%, regardless of the size of the screen. By doing this, the aforementioned elements or divs will easily adapt to any screen size, resulting in simpler and more seamless responsive web design.&lt;/p&gt;

&lt;p&gt;Furthermore, it's essential to remember that the 100% rule can be applied to divs or elements in addition to the entire page, as described in the paragraphs above in this section. This indicates that the child div or elements view the div above them as their parent div and that this parent div also acts as if it were our entire screen, with 100% height and 100% width. The styling for the child div or element can therefore be set to take 50% of its parent div, and so on. which makes a significant contribution to the fluidity of our apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Harness the Power of "em" Units for Font Sizes
&lt;/h3&gt;

&lt;p&gt;Font size is a key factor in determining readability and overall design aesthetics when it comes to designing visually appealing and user-friendly websites. Employing &lt;strong&gt;em&lt;/strong&gt; units to specify font sizes has become a potent strategy in web design that has a wealth of advantages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Em&lt;/strong&gt; units, also known as "emerald units," are a type of relative measurement that is frequently applied in web development. &lt;strong&gt;em&lt;/strong&gt; units offer a flexible and scalable method for defining font sizes in contrast to fixed pixel values. With such adaptability, the text on your website can easily adjust to various screen sizes and resolutions, improving user experience on a variety of devices.&lt;/p&gt;

&lt;p&gt;You can have more control over the typography on your website by utilizing the strength of &lt;strong&gt;em&lt;/strong&gt; units. &lt;strong&gt;Em&lt;/strong&gt; units are based on the parent element's font size, allowing you to create a unified visual hierarchy across all of your web pages. A consistent and well-balanced design is achieved by changing the font size at the parent level, which automatically cascades the changes to child elements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Em&lt;/strong&gt; units also provide a responsive design benefit. Font sizes specified in &lt;strong&gt;em&lt;/strong&gt; units will proportionally scale as users zoom in or out on their browsers, maintaining optimal legibility and readability. In the mobile age, where users access websites on a variety of devices with different screen sizes and resolutions, this adaptability is especially valuable.&lt;/p&gt;

&lt;p&gt;Additionally, &lt;strong&gt;em&lt;/strong&gt; units encourage inclusivity and accessibility by enabling dynamic text resizing. Websites using &lt;strong&gt;em&lt;/strong&gt; units will gracefully respond to these modifications, accommodating their needs without compromising the design integrity. People with visual impairments or those who prefer larger text sizes can easily adjust the font size in their browser settings.&lt;/p&gt;

&lt;p&gt;It's critical to maintain balance when using &lt;strong&gt;em&lt;/strong&gt; units to specify font sizes. Although &lt;strong&gt;em&lt;/strong&gt; units' relative nature allows for flexibility, it is important to avoid overcrowding elements with &lt;strong&gt;em&lt;/strong&gt; units because this can result in compounding font size increases or decreases. A unified and aesthetically pleasing outcome will be achieved by maintaining a clear hierarchy and carefully applying em units to the appropriate elements.&lt;/p&gt;

&lt;p&gt;Finally, utilizing em units for font sizes gives web designers the ability to produce visually stunning, responsive, and inclusive websites. By following this best practice, you can improve the readability, adaptability, and overall aesthetics of the typography on your website. So take advantage of em units' potential to open up a world of opportunities for your web projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Embrace the Art of Minimalism: Mastering the Practice for Responsive Web Designs
&lt;/h3&gt;

&lt;p&gt;It has become essential to create a responsive web design in the quick-paced digital environment where users browse websites on a variety of devices. Websites must now seamlessly adjust to various screen sizes and resolutions; it is no longer enough for them to just look good visually. Adopting the minimalist aesthetic in web design not only improves aesthetics but is essential for creating a website that is truly responsive.&lt;/p&gt;

&lt;p&gt;With its emphasis on clarity and simplicity, minimalism is perfectly in line with the fundamentals of responsive web design. Minimalistic designs offer a strong foundation for creating fluid layouts that adapt naturally to different screen sizes by eliminating extraneous clutter and elements. A minimalist design's clear and uncluttered interface gives content room to breathe and gives responsive elements room to resize and reposition themselves gracefully.&lt;/p&gt;

&lt;p&gt;The use of minimalism in responsive web design enhances user experience across various devices. The user interface can be made simpler and less distracting by removing extraneous visuals, excessive text, and redundant features. This makes it possible for users to interact and navigate your website without any difficulty, whether they are using a desktop, tablet, or smartphone. A consistent and intuitive user experience across devices is offered by minimalist designs, which improves engagement and promotes repeat visits.&lt;/p&gt;

&lt;p&gt;Improved website performance is another advantage of minimalism in responsive web design. Minimalist designs help reduce the overall file size, which leads to faster load times as there is an increasing expectation for websites to load quickly. Your website becomes more effective by reducing the number of elements and improving the code, providing users with a fluid and responsive browsing experience across various devices and network conditions.&lt;/p&gt;

&lt;p&gt;Additionally, minimalism encourages a mobile-first mindset, which is crucial in the current mobile-centric era. You can make sure that your website works flawlessly on mobile devices by giving priority to the content and features that are absolutely necessary. A minimalist design's clarity and simplicity make it simpler to identify and prioritize the most important components for smaller screens, ensuring that users can access and interact with your content without difficulty.&lt;/p&gt;

&lt;p&gt;It's critical to strike a balance between functionality and simplicity when incorporating minimalism into responsive web design. You should keep the essential components and make sure the website is still simple to use while removing any extraneous elements. To ensure a consistent and satisfying experience for all users, pay attention to how elements respond to changes in size and test the design on various devices.&lt;/p&gt;

&lt;p&gt;In conclusion, embracing the minimalist aesthetic is a potent technique for developing responsive web designs. You can achieve aesthetic appeal, improve user experience, and increase website performance across devices by implementing minimalist principles. So, if you want to realize the full potential of responsive web design, dive into the world of minimalism and become an expert practitioner.&lt;/p&gt;

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

&lt;p&gt;We have looked at the "4 Best Code Practices for Creating a Responsive Website" throughout this article, as well as the key methods and procedures for achieving the best possible web design. By incorporating these practices, your websites would appear flawlessly on a variety of devices and screen sizes.&lt;/p&gt;

&lt;p&gt;So keep in mind the strength of these coding techniques because they can make your websites more responsive and user-friendly. Apply them diligently, try out various strategies, and keep improving your abilities. By doing this, you'll not only stay ahead in the fast-paced field of web development but also build websites that engage visitors across all platforms.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>css</category>
      <category>responsivenes</category>
    </item>
    <item>
      <title>The Power of Angular @Input and @Output Decorators: A Comprehensive Overview</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Sun, 11 Jun 2023 02:23:49 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/the-power-of-angular-input-and-output-decorators-a-comprehensive-overview-1832</link>
      <guid>https://dev.to/playfulprogramming-angular/the-power-of-angular-input-and-output-decorators-a-comprehensive-overview-1832</guid>
      <description>&lt;p&gt;Are you working on a codebase in which you use a component you created but need to display data or perform a click function in your child component from the parent component? or perhaps you learned about reusable components and wanted to test them out, but your child or reusable component is having issues talking and communicating with other components? Cheers and congratulations; the purpose of this article is to help you not only comprehend but also solve the problem of communication between components in Angular using Angular's @input and @output decorators.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the &lt;code&gt;@input&lt;/code&gt; and &lt;code&gt;@output&lt;/code&gt; Decorator?
&lt;/h2&gt;

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

&lt;p&gt;So, first and foremost, let's talk about decorators. Decorators are a way of adding metadata to a class, its properties, or its methods in the context of Angular. Decorators are basically functions that wrap around a class, property, or method and change its behavior in some way.&lt;/p&gt;

&lt;p&gt;However, let us briefly discuss class decorators and class field decorators. Class decorators are used to decorate classes, whereas class field decorators are used to decorate class fields or properties.&lt;/p&gt;

&lt;p&gt;Class decorators modify the behavior of the entire class. By way of illustration, the &lt;code&gt;@Component()&lt;/code&gt; decorator, which is mentioned immediately before a class definition, contains metadata that aids Angular in understanding how the classes or properties should function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
 &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whereas class field decorators modify the behavior of a specific property or field within a class. The best examples are the &lt;code&gt;@Input&lt;/code&gt; and &lt;code&gt;@Output&lt;/code&gt; decorators.&lt;/p&gt;

&lt;p&gt;Now that we've covered that, let's look at the &lt;code&gt;@Input&lt;/code&gt; and &lt;code&gt;@Output&lt;/code&gt; decorators in particular. These are two of the most common Angular decorators.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;@Input&lt;/code&gt; Decorator - Parent-to-Child communication
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;@Input&lt;/code&gt; decorator is used to pass data from one component to another. When the &lt;code&gt;@Input&lt;/code&gt; decorator is applied to a property in a child component, it transforms it into a property that can receive data from its parent component. This enables the parent component to communicate with the child component and pass data to it, which can then be used in the template or logic file of the child component.&lt;/p&gt;

&lt;p&gt;To have a practical understanding of the above theory, take for example you have two components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Parent Component&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Child Component&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The parent component is trying to teach its child how to count numbers, it does this by asking its child to render the number of times a button in its component was clicked. How would this be achieved? Let's take a look at how the parent component &lt;code&gt;HTML&lt;/code&gt; would look like below:&lt;/p&gt;

&lt;h3&gt;
  
  
  parent-component.html file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"teachChildNumbersCounting()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Ask Child&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;app-child&lt;/span&gt; &lt;span class="na"&gt;[clickCounts]=&lt;/span&gt;&lt;span class="s"&gt;"clicks"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/app-child&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The child component is given the value of clicks in the code above. The child component keeps track of changes in the &lt;code&gt;clickCounts&lt;/code&gt; value and updates the child component's count value accordingly. Using interpolation from the child.component.html file, the child component will then show the value of the count in the template.&lt;/p&gt;

&lt;p&gt;Wondering what the logic file for the parent component would look like? You can examine the following lines of code below:&lt;/p&gt;

&lt;h3&gt;
  
  
  parent-component.ts file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Component1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nx"&gt;clicks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="nf"&gt;teachChildNumbersCounting&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clicks&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above lines of code, the property &lt;code&gt;clicks&lt;/code&gt; is defined and a value of 0 is set to it. Following it is a definition of the &lt;code&gt;teachChildNumbersCounting()&lt;/code&gt; function used in &lt;code&gt;parent-component.html&lt;/code&gt;, the file that adds +1 to the clicks' value whenever the function is triggered by clicks from the button and then passed to the child component.&lt;/p&gt;

&lt;p&gt;However, the child component's &lt;code&gt;clickCounts&lt;/code&gt; property is decorated with the &lt;code&gt;@Input&lt;/code&gt; decorator in the &lt;code&gt;child-component.ts&lt;/code&gt; file so that the child component can render the clicks property through it. The majority of the work is completed here. As was already said, the &lt;code&gt;@Input&lt;/code&gt; decorator turns the property &lt;code&gt;clickCounts&lt;/code&gt; into a data-receiving property for its parent component. This allows communication between the parent and child components, all thanks to the &lt;code&gt;@Input&lt;/code&gt; decorator.&lt;/p&gt;

&lt;p&gt;The code implementation for the above explanation on how the &lt;code&gt;@Input&lt;/code&gt; decorator is used in the &lt;code&gt;child-component.ts&lt;/code&gt; file can be examined in the lines of code below:&lt;/p&gt;

&lt;h3&gt;
  
  
  child-component.ts file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;childComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;clickCounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the above implementation, the child component can now render the number of times the parent component clicked the button in its &lt;code&gt;component.html&lt;/code&gt; file by making use of interpolation for data binding to display the value set to the &lt;code&gt;clickCounts&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;However, you can examine the code implementation for the explanation made below:&lt;/p&gt;

&lt;h3&gt;
  
  
  child-component.html file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt; &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;No of clicks from parent's Component - {{clickCounts}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  @Output Decorator - Child-to-Parent communication
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;@Output&lt;/code&gt; decorator, on the other hand, is used to emit events from a child component to a parent component. When the &lt;code&gt;@Output&lt;/code&gt; decorator is applied to a property or method in a child component, it transforms it into an event emitter that can be triggered to emit data or events from the child component to its parent component. This enables the child component to communicate with and send data or events back to the parent component.&lt;/p&gt;

&lt;p&gt;Nevertheless, keep in mind the example from the section above. Since the child component can now display how many times the button in the parent component was clicked on. Now consider our example in reverse, where the parent component displays the number of times the button in its child component was clicked.&lt;/p&gt;

&lt;p&gt;To achieve this, some edits would be made to the child component. First, you can take a look at the child's template component in the following lines of code below:&lt;/p&gt;

&lt;h3&gt;
  
  
  child-component.html file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;No of clicks from parent's Component - {{clickCounts}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;(click)='countClicks()'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click to count from child&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic file for the above template can be examined below:&lt;/p&gt;

&lt;h3&gt;
  
  
  child-component.ts file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Component2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;childToPrentCountClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventEmitter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EventEmitter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;clickCounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;countClicks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childToPrentCountClick&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The event emitter in the component mentioned above is &lt;code&gt;childToPrentCount&lt;/code&gt;. This listens to when a click event is triggered. For this to be effective, the parent component would need to be updated. This can be observed in the following lines of code:&lt;/p&gt;

&lt;h3&gt;
  
  
  parent-component.html file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;(click)="teachChildNumbersCounting()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Ask Child&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;No of clicks from child's Component - {{clicks}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;app-child&lt;/span&gt; 
&lt;span class="err"&gt;[clickCounts]="clicks"&lt;/span&gt; 
&lt;span class="na"&gt;childToPrentCountClick=&lt;/span&gt;&lt;span class="s"&gt;"teachChildNumbersCounting()"&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/app-child&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above lines of code, the function &lt;code&gt;teachChildNumbersCounting()&lt;/code&gt; was passed to the &lt;code&gt;childToParentCountClick&lt;/code&gt; event emitter that is decorated with the &lt;code&gt;@Output&lt;/code&gt; decorator in the child's decorator. This allows our button clickable with desired logic controlled by the parent component without the child component performing any logic on the button click.&lt;/p&gt;

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

&lt;p&gt;To summarize, during this article, we have discussed how the &lt;code&gt;@Input&lt;/code&gt; decorator passes data from a parent component to a child component, whereas the &lt;code&gt;@Output&lt;/code&gt; decorator emits events from a child component to a parent component. These decorators, when used together, enable powerful communication and interaction between components in Angular applications.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>angular</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Implement Animate on Scroll in Angular Web Apps - Using the AOS Library</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Wed, 18 May 2022 03:58:17 +0000</pubDate>
      <link>https://dev.to/playfulprogramming-angular/how-to-implement-animate-on-scroll-in-angular-web-apps-using-the-aos-library-28d7</link>
      <guid>https://dev.to/playfulprogramming-angular/how-to-implement-animate-on-scroll-in-angular-web-apps-using-the-aos-library-28d7</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Animations pique a user's interest in applications. Not only that, animations can also be used to improve UX(user experience) considering the fact that making dramatic transitions and movements on the screen can be a way to retain a user’s attention while the content of a page loads .  In this article, we’ll go over how to use the &lt;a href="https://michalsnik.github.io/aos/" rel="noopener noreferrer"&gt;Animate On Scroll (AOS)&lt;/a&gt; library to animate Angular web pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Objectives&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the end of this article, you would have learned how to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install and configure the Animate On Scroll Library&lt;/li&gt;
&lt;li&gt;Initialize and animate web pages in Angular applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get the most out of this tutorial, a basic understanding of the following is required;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;Typescript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get started by going over the step-by-step process to &lt;br&gt;
  achieve  the learning objectives of this tutorial.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Setting up/installing an Angular app.
&lt;/h2&gt;

&lt;p&gt;An angular app must be running before we begin at all. This can be accomplished by executing the following sequence of commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new my-app

 // ? Would you like to add Angular routing? Yes
 // ? Which stylesheet format would you like to use? CSS

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

&lt;/div&gt;



&lt;p&gt;All of our routing configuration would need to be defined in&lt;br&gt;
our&lt;br&gt;
angular project's app-routing.module.ts file. Angular CLI&lt;br&gt;
will add the app-routing.module.ts file to our Angular&lt;br&gt;
project if we answer "YES" to the question "Would you like&lt;br&gt;
to add Angular routing?".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd myApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would change our directory to myApp folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng serve --o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would serve and open our Angular project on &lt;a href="http://localhost:4200" rel="noopener noreferrer"&gt;http://localhost:4200&lt;/a&gt; by default. This way we can now view our project.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Configuring/installing the Animate On Scroll (AOS) library.
&lt;/h2&gt;

&lt;p&gt;We will install and configure the animation library in this step so that it can be accessed and used in the project. To install the library, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install aos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will install the animation library, and once it has been successfully installed, it is important to update the styles array in the angular.json file to include the animation library. To do this, open the angular.json file and add the following line to it;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;node_modules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;aos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;aos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having done that correctly, we have successfully installed and configured the AOS library, which makes  it ready for use  in our project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We may need to restart our server in order for our project to be updated with recent changes after installation, but only if our project appears to be out of date.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Initializing/ Animating with the Animate On Scroll Library (AOS).
&lt;/h2&gt;

&lt;p&gt;In this step, we would finally bring our animations to life and make them work as we scroll through our web pages. Let's get started and see what happens.&lt;br&gt;
First, we must open our desired component's TS file, for example, “home-component.ts”, import the AOS library, and initialize it. This can be accomplished by following the steps outlined below;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Import the library:&lt;/strong&gt;
Inside the desired component.ts file, add the import;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AOS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Initialize the functionality:&lt;/strong&gt;
To get the AOS library functioning, it is important to call the init() function in the ngOnInit of our component.ts file. This can simply be done by adding the the following line of code:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;AOS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;By doing this, the AOS library has been initialized and  our animations are ready for action. But before we can see the effects, we must open our component.html file(e.g home-component.html), which must be the html component of the ts file we just worked on, and set animation using the data-aos attribute in our desired divs. Example;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-aos=&lt;/span&gt;&lt;span class="s"&gt;"fade-up"&lt;/span&gt; &lt;span class="na"&gt;data-aos-duration=&lt;/span&gt;&lt;span class="s"&gt;"3000"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- our contents —-&amp;gt;
&amp;lt;/div&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;The code above would add a fade-up animation to the div on scroll, but the capability of the AOS Library is not limited to this. To discover more animations, The official Animate on Scroll website has an experience of animations and effects provided by the library. You may check it out &lt;a href="https://michalsnik.github.io/aos/" rel="noopener noreferrer"&gt;here&lt;/a&gt;  and notice how the effects happen as you scroll down and up the page.&lt;/p&gt;

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

&lt;p&gt;So far in this article, we've been able to see how easy it is to set up an Angular app with Animate On Scroll effects on its pages using the AOS Library. Questions and suggestions are always welcome in the comments. See you in the next article.&lt;br&gt;
Happy Coding!&lt;/p&gt;

&lt;p&gt;Thank you for reading this far. I hope you found the tutorial useful. If you have any questions or comments, please leave them in the comments section.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>animation</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>HOW TO BUILD A LOGIN AND SIGN UP PAGE WITH API AUTHENTICATION IN ANGULAR</title>
      <dc:creator>Bima</dc:creator>
      <pubDate>Mon, 10 Jan 2022 04:17:55 +0000</pubDate>
      <link>https://dev.to/olabima_/how-to-build-a-login-and-sign-up-page-with-api-authentication-in-angular-nec</link>
      <guid>https://dev.to/olabima_/how-to-build-a-login-and-sign-up-page-with-api-authentication-in-angular-nec</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Login and sign-up pages are used to control some aspects of a website's user interactions. In this article, we'll go over how to use an &lt;a href="https://www.freecodecamp.org/news/what-is-an-api-in-english-please-b880a3214a82/"&gt;API&lt;/a&gt; to authenticate a login and sign-up page in Angular.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning Objectives
&lt;/h2&gt;

&lt;p&gt;By the end of this article, we should be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Perform basic route configurations in angular.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call an API to register users (sign-up).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call an API to login users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create and make use of JSON server.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We will make use of JSON server as our fake backend in this &lt;br&gt;
article&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get started and walk through the steps to archiving this article's learning objectives. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Setting up/installing Angular app
&lt;/h2&gt;

&lt;p&gt;A running angular app must be created before beginning work on the login or sign-up forms. This can be accomplished by executing the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new myApp

 // ? Would you like to add Angular routing? Yes
 // ? Which stylesheet format would you like to use? CSS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of our routing configuration would need to be defined in &lt;br&gt;
  our &lt;br&gt;
  angular project's &lt;strong&gt;app-routing.module.ts&lt;/strong&gt; file. Angular CLI &lt;br&gt;
  will add the &lt;strong&gt;app-routing.module.ts&lt;/strong&gt; file to our Angular &lt;br&gt;
  project if we answer "&lt;strong&gt;YES&lt;/strong&gt;" to the question "&lt;strong&gt;Would you like &lt;br&gt;
  to add Angular routing?&lt;/strong&gt;".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd myApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would change our directory to myApp folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng serve --o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would serve and open our Angular project on  &lt;a href="http://localhost:4200"&gt;http://localhost:4200&lt;/a&gt; by default. This way we can now view our project.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Generating components
&lt;/h2&gt;

&lt;p&gt;Angular applications are composed of components, which serve as the foundation for angular projects or applications. We would create or generate three (3) components, which are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign-up component&lt;/li&gt;
&lt;li&gt;Login component&lt;/li&gt;
&lt;li&gt;Home page component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following commands must be executed to generate the required components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component components/signup-up-page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component components/login-page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component components/home
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The commands above would generate our required component.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Routing And Route Configuration
&lt;/h2&gt;

&lt;p&gt;Navigation between our components or pages would be possible thanks to routing and route configuration. You can learn more about angular routing &lt;a href="https://www.smashingmagazine.com/2018/11/a-complete-guide-to-routing-in-angular/"&gt;Here&lt;/a&gt;. The steps to accomplishing this, however, are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to the app.component.html file, delete everything in it (for newly installed projects only), and add&lt;br&gt;
&lt;code&gt;&amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;&lt;/code&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to the app-routing.module.ts file, import all of our generated components in it. &lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LoginPageComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/login-page/login-page.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SignUpPageComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/sign-up-page/sign-up-page.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HomeComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/home/home.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Still in the app-routing.module.ts file , we would go to our routes array and, define our path of our route using our generated Angular components. Here in our path: ".." we would insert our route name.
Example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;redirectTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;pathMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;LoginPageComponent&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;signUp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;SignUpPageComponent&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;HomeComponent&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;With the above configuration, our angular application would default to displaying the login component and other components when their pathnames (e.g., /login) are called.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Building a simple Login and Sign-Up form
&lt;/h2&gt;

&lt;p&gt;We would create our login and sign-up forms here. To begin, navigate to our  &lt;strong&gt;login-page.component.html&lt;/strong&gt; file and copy the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hi Welcome Back&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Login Here&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;  &lt;span class="na"&gt;required&lt;/span&gt;  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Don't have an account? 
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;routerLink=&lt;/span&gt;&lt;span class="s"&gt;"/signUp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;signUp&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our login page is complete (we can add our desired stylings), let's move on to our &lt;strong&gt;sign-up-page.component.html&lt;/strong&gt; file and copy the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello Welcome &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Create An Account&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;  &lt;span class="na"&gt;required&lt;/span&gt;  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Already have an account? 
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;routerLink=&lt;/span&gt;&lt;span class="s"&gt;"/login"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;signUp&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, we have gotten our login and sign-up form ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Setting up JSON server
&lt;/h2&gt;

&lt;p&gt;In a matter of seconds, JSON server creates a rest API with no code, and we can access the full documentation &lt;a href="https://github.com/typicode/json-server"&gt;HERE&lt;/a&gt;. This would serve as our fake backend, allowing our application to function as if it had a real backend. Let's get started with our setup by going through the steps below:&lt;/p&gt;

&lt;p&gt;1 Install JSON server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g json-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 Create db.json file&lt;/p&gt;

&lt;p&gt;Let's create a &lt;strong&gt;db.json&lt;/strong&gt; file with some data &lt;br&gt;
We will create a new file inside myApp folder in our project and name it &lt;strong&gt;db.json&lt;/strong&gt;. We would as well copy some data in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;signupUsersList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bolu@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1234&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 Start JSON server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;json-server --watch db.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let us  open &lt;a href="http://localhost:3000/signupUsersList(would"&gt;http://localhost:3000/signupUsersList(would&lt;/a&gt; serve as our API link), we would see the data we added previously. This way we have successfully gotten our JSON server up and running.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Making API calls for authentication
&lt;/h2&gt;

&lt;p&gt;To begin, we would need to make a post request in our sign-up form in order to register our users, followed by a get request for validation and authentication. We will be working with &lt;a href="https://angular.io/guide/reactive-forms"&gt;REACTIVE FORMS&lt;/a&gt; in angular. Let's follow the steps below to get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call API to register users&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Import necessary modules
Let's go to our &lt;strong&gt;sign-up-page.component.ts&lt;/strong&gt; file and copy the following:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormGroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormBuilder&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Call API to register users
Still inside our &lt;strong&gt;sign-up-page.component.ts&lt;/strong&gt; let's go inside our exports and copy the following code:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;signUpForm&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormGroup&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;formBuilder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormBuilder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signUpForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000/signupUsersList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signUpForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SIGNIN SUCCESFUL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signUpForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Something went wrong&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Let's go into our &lt;strong&gt;sign-up-page.component.html&lt;/strong&gt; file to implement our formGroup in our form tag, formControlName in our input tags and signUp function.&lt;br&gt;
we would simply rewrite previous code as the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello Welcome &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Create An Account&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;[formGroup]=&lt;/span&gt;&lt;span class="s"&gt;"signUpForm"&lt;/span&gt; &lt;span class="na"&gt;(ngSubmit)=&lt;/span&gt;&lt;span class="s"&gt;"signUp()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;formControlName=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;  &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;formControlName=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Already have an account? 
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;routerLink=&lt;/span&gt;&lt;span class="s"&gt;"/login"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;signUp&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code blocks above would retrieve all of our formGroup's input field values, store them in our db.json file with the help of our JSON server, and navigate our page to our login page. &lt;/p&gt;

&lt;p&gt;Cheers!! We were able to successfully register our users by making an API call.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call API to login users
Now let's go into our &lt;strong&gt;login-page.component.ts&lt;/strong&gt; file and follow the steps below:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Import necessary modules&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormGroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormBuilder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Inside our exports&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;loginForm&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormGroup&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;formbuilder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormBuilder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loginForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formbuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000/signupUsersList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loginForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loginForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt; 
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login Succesful&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loginForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Something went wrong&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go into our &lt;strong&gt;sign-up-page.component.html&lt;/strong&gt; file &lt;br&gt;
we would rewrite previous code as the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hi Welcome Back&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Login Here&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;  &lt;span class="na"&gt;[formGroup]=&lt;/span&gt;&lt;span class="s"&gt;"loginForm"&lt;/span&gt; &lt;span class="na"&gt;(ngSubmit)=&lt;/span&gt;&lt;span class="s"&gt;"login()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;formControlName=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;  &lt;span class="na"&gt;required&lt;/span&gt;  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;formControlName=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Don't have an account? 
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;routerLink=&lt;/span&gt;&lt;span class="s"&gt;"/signUp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;signUp&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code blocks above would retrieve all of our formGroup's input field values, validate them against the data in our db.json file, and navigate our page to our home page using our JSON server. &lt;br&gt;
Cheers!! We successfully used an API call to authenticate our users.&lt;/p&gt;

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

&lt;p&gt;Finally, we went through the process of "How to build a login and sign-up page in Angular," where we learned how to perform basic routing in angular, set up and use a JSON server, and login and sign-up our users using api calls.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>angular</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
