<?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: seanbh</title>
    <description>The latest articles on DEV Community by seanbh (@seanbh).</description>
    <link>https://dev.to/seanbh</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%2F1089466%2F5ee5f39c-4869-47ae-b30d-894a75c5b0e0.jpeg</url>
      <title>DEV Community: seanbh</title>
      <link>https://dev.to/seanbh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/seanbh"/>
    <language>en</language>
    <item>
      <title>Quick Summary of Angular 17</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Mon, 13 Nov 2023 18:14:42 +0000</pubDate>
      <link>https://dev.to/seanbh/quick-summary-of-angular-17-27gl</link>
      <guid>https://dev.to/seanbh/quick-summary-of-angular-17-27gl</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QJQi_bA5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/960/0%2AB8w8g6fh_tYV_TI7" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QJQi_bA5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/960/0%2AB8w8g6fh_tYV_TI7" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Angular’s New Logo&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Angular 17 was released last week, and this is my attempt to summarize Minko Gechev’s excellent post “&lt;a href="https://blog.angular.io/introducing-angular-v17-4d7033312e4b"&gt;Introducing Angular v17&lt;/a&gt;” as succinctly as possible. I recommend reading his post in full, but here is the Reader’s Digest version:&lt;/p&gt;
&lt;h4&gt;
  
  
  New control flow syntax (developer preview)
&lt;/h4&gt;

&lt;p&gt;More intuitive and performant (up to 90% faster) &lt;a href="https://angular.io/guide/control_flow"&gt;control flow&lt;/a&gt; syntax (replaces *ngIf, *ngSwitch and *ngFor). Here are the examples presented in the &lt;a href="https://blog.angular.io/introducing-angular-v17-4d7033312e4b"&gt;post&lt;/a&gt; (condensed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// if
@if (loggedIn) {
  The user is logged in
} @else {
  The user is not logged in
}

// switch
@switch (accessLevel) {
  @case ('admin') { &amp;lt;admin-dashboard/&amp;gt; }
  @case ('moderator') { &amp;lt;moderator-dashboard/&amp;gt; }
  @default { &amp;lt;user-dashboard/&amp;gt; }
}

// for loop
@for (user of users; track user.id) {
  {{ user.name }}
} @empty {
  Empty list of users
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Deferrable views (developer preview)
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://angular.io/guide/defer#deferrable-views"&gt;Deferrable views&lt;/a&gt; utilize &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"&gt;dynamic imports&lt;/a&gt; and the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API"&gt;Intersection Observer API&lt;/a&gt; to lazy load components and their dependencies (optionally with prefetching) based on various triggers, such as when the component enters the viewport. Here is an example from the &lt;a href="https://blog.angular.io/introducing-angular-v17-4d7033312e4b"&gt;post&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@defer (on viewport; prefetch on idle) {
  &amp;lt;comment-list/&amp;gt;
} @loading {
  Loading…
} @error {
  Loading failed :(
} @placeholder {
  &amp;lt;img src="comments-placeholder.png"&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other &lt;a href="https://angular.io/guide/defer#triggers"&gt;triggers&lt;/a&gt; are idle, immediate, timer, interaction, hover and when .&lt;/p&gt;

&lt;h4&gt;
  
  
  SSR/SSG improvements
&lt;/h4&gt;

&lt;p&gt;Angular Universal (SSR) has been moved to the &lt;a href="https://angular.io/guide/ssr#enable-server-side-rendering"&gt;CLI&lt;/a&gt; so that you get prompted to enable SSR and SSG when executing ng new (or you can add it later with ng add @angular/ssr). Also, &lt;a href="https://angular.io/guide/hydration"&gt;&lt;em&gt;hydration&lt;/em&gt;&lt;/a&gt; is out of developer preview and is enabled by default.&lt;/p&gt;

&lt;h4&gt;
  
  
  Miscellaneous
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Standalone is now the default for all schematics and the recommendation is to move all projects to standalone gradually.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://angular.dev/"&gt;Angular.dev&lt;/a&gt; will replace Angular.io in v18 for documentation and interactive learning. It also has a &lt;a href="https://angular.dev/playground"&gt;Playground&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Signals are out of developer preview and more enhancements are coming in v18.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://esbuild.github.io/"&gt;esbuild&lt;/a&gt; plus &lt;a href="https://vitejs.dev/"&gt;Vite&lt;/a&gt; is out of developer preview and enabled by default, yielding 67%, 87%, 80% speed improvements for build time, hybrid build time and hybrid serve time respectively.&lt;/li&gt;
&lt;li&gt;New &lt;a href="https://angular.io/api/core/afterRender"&gt;afterRender&lt;/a&gt; and &lt;a href="https://angular.io/api/core/afterNextRender"&gt;afterNextRender&lt;/a&gt; lifecycle hooks.&lt;/li&gt;
&lt;li&gt;You don’t need to use an array when setting a component style — e.g., styleUrl: ‘styles.css’ instead of styleUrl: [‘styles.css’].&lt;/li&gt;
&lt;li&gt;New UI in &lt;a href="https://angular.io/guide/devtools"&gt;Angular DevTools&lt;/a&gt; for dependency injection debugging.&lt;/li&gt;
&lt;li&gt;Ability to use native browser animated transitions between routes by passing &lt;a href="https://angular.dev/api/router/withViewTransitions"&gt;withViewTransitions()&lt;/a&gt; to provideRouter().&lt;/li&gt;
&lt;li&gt;Ability to lazy load the animations module with &lt;a href="https://angular.dev/guide/animations#enabling-the-animations-module"&gt;provideAnimationsAsync()&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Continued work on &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; and &lt;a href="https://modern-web.dev/docs/test-runner/overview/"&gt;Web Test Runner&lt;/a&gt; (which will replace Karma).&lt;/li&gt;
&lt;li&gt;You can do this  instead of this  if you add a &lt;a href="https://angular.dev/guide/components/inputs#input-transforms"&gt;transform&lt;/a&gt; to your input like this: @Input({ transform: booleanAttribute }) expanded: boolean = false;&lt;/li&gt;
&lt;li&gt;Rebranding.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Reminders
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Developer preview doesn’t mean that something is not ready to use, it just means that breaking changes could be introduced before the next major release.&lt;/li&gt;
&lt;li&gt;Always check to see if there is a schematic to help you migrate legacy code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Bibliography&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.angular.io/introducing-angular-v17-4d7033312e4b"&gt;Introducing Angular v17. Last month marked the 13th anniversary… | by Minko Gechev | Nov, 2023 | Angular Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>summary</category>
      <category>newfeatures</category>
      <category>angular17</category>
      <category>angular</category>
    </item>
    <item>
      <title>Enhancing npm Script Tasks with Node.js and JavaScript</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Mon, 06 Nov 2023 14:24:52 +0000</pubDate>
      <link>https://dev.to/seanbh/enhancing-npm-script-tasks-with-nodejs-and-javascript-1jjj</link>
      <guid>https://dev.to/seanbh/enhancing-npm-script-tasks-with-nodejs-and-javascript-1jjj</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d8jWWpfu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AH--AyqUH-GOvNvgq" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d8jWWpfu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AH--AyqUH-GOvNvgq" alt="" width="800" height="530"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Kelly Sikkema on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Npm script tasks are an integral part of any modern JavaScript project. They allow us to automate mundane tasks and prevent us from having to remember a bunch of different commands.&lt;/p&gt;

&lt;p&gt;You can accomplish many things without ever leaving package.json. But sometimes you need to do more than can be done in the single line definition of a script task or with multiple tasks.&lt;/p&gt;

&lt;p&gt;If you find yourself in that situation you can offload the work to a JavaScript file and define the script task so that it runs that file with Node.js.&lt;/p&gt;
&lt;h3&gt;
  
  
  Running a JavaScript file with Node
&lt;/h3&gt;

&lt;p&gt;Running a JavaScript file with an &lt;strong&gt;npm&lt;/strong&gt; script task is as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"my-script-task": "node ./my-script.mjs"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you execute npm run my-script-task in the terminal, &lt;strong&gt;npm&lt;/strong&gt; will execute this task, which runs the my-script.mjs file using  &lt;strong&gt;Node&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why does the file have an .mjs extension? The .mjs extension stands for “Module JavaScript”. It is used to explicitly tell Node that the file should be run as an ES module, which allows us to use ESM syntax. See this post to learn more about JavaScript &lt;a href="https://dev.to/seanbh/modules-modules-modules-oh-my-fn8"&gt;Modules&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Helpful Modules
&lt;/h3&gt;

&lt;p&gt;I have found that I can accomplish a lot by only importing 3 modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { execSync } from 'child_process';
import readline from 'readline';
import chalk from 'chalk';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using ESLint, it may complain about the import statement unless you add this to your .eslintrc.json file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "files": ["*.mjs"],
  "parserOptions": {
    "sourceType": "module",
    "ecmaVersion": "latest"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  execSync
&lt;/h4&gt;

&lt;p&gt;execSync is built into Node and is the workhorse. It is used to execute shell commands which actually accomplish the work we need to perform. Note that it is surrounded by {} in the import statement because it is a named export rather than the default export.&lt;/p&gt;

&lt;p&gt;To use it, you just pass in the command that you would normally run in the terminal. For example, if I want to bump the prerelease version of my package, I can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;execSync(`npm version prerelease --preid=test`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  readLine
&lt;/h4&gt;

&lt;p&gt;readLine also comes with Node and allows for user interaction. For example, we can make the user confirm what they are about to do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

// make the user confirm what they are about to do
rl.question('Are you sure? (y/n) ', (answer) =&amp;gt; {
  if (answer.toLowerCase() === 'y') {
    // do your work
  } else {
    // abort
    rl.close();
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  chalk
&lt;/h4&gt;

&lt;p&gt;chalk is a third-party &lt;a href="https://github.com/chalk/chalk"&gt;package&lt;/a&gt; we can use to style the terminal, so that we can make questions and messages stand out. To use it, you just wrap the text in a function call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chalk.yellowBright(
   ‘This text will be bright yellow’
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this when passing text to both rl.question and console.log:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(
   chalk.redBright(
     ‘This text will be bright red’
   )
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this combination of tools, I’ve been able to greatly enhance our development workflows.&lt;/p&gt;

&lt;p&gt;That’s it! I hope you found this useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/api/child_process.html#child_processexecsynccommand-options"&gt;Child process | Node.js v21.1.0 Documentation (nodejs.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/api/readline.html"&gt;Readline | Node.js v21.1.0 Documentation (nodejs.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://v8.dev/features/modules#mjs"&gt;JavaScript modules · V8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/cli/v10/using-npm/scripts"&gt;scripts | npm Docs (npmjs.com)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/chalk/chalk"&gt;GitHub — chalk/chalk: 🖍 Terminal string styling done right&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>developmentworkflow</category>
      <category>npmscripts</category>
      <category>automation</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What’s a Nonce?</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Wed, 25 Oct 2023 16:12:46 +0000</pubDate>
      <link>https://dev.to/seanbh/whats-a-nonce-3ppp</link>
      <guid>https://dev.to/seanbh/whats-a-nonce-3ppp</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AibvU-N6yux0jbODz" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AibvU-N6yux0jbODz"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by FLY:D on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What’s a &lt;em&gt;nonce&lt;/em&gt;? It sounds like a creature in a Dr. Seuss book or maybe the lesser known de León brother. But in fact, it is one piece of an important security technique, and you should be aware of it. In this article, we will explore what a &lt;em&gt;nonce&lt;/em&gt; is and how it can be used to make an Angular application more secure.&lt;/p&gt;
&lt;h3&gt;
  
  
  Content-Security-Policy (CSP)
&lt;/h3&gt;

&lt;p&gt;To understand what a &lt;em&gt;nonce&lt;/em&gt; is, we first need to take a step back and talk about Content-Security-Policy or CSP. A CSP is one mechanism used to mitigate Cross-Site-Scripting (XSS) attacks which allow attackers to trick the browser into executing malicious content.&lt;/p&gt;

&lt;p&gt;A CSP limits the &lt;em&gt;sources&lt;/em&gt; of content, so that the browser will only execute content from predefined sources or domains. To implement a CSP, the server adds a Content-Security-Policy response header that defines the acceptable sources. You can set values for default-src that apply to all content, or you can get more fine-grained and define sources for specific content. For example, script-src for scripts, style-src for styles, etc. It is common to set default-src ‘self’; which allows all content from the same domain as the site itself.&lt;/p&gt;

&lt;p&gt;Setting a CSP also blocks all inline scripts and styles by default. Many applications, including Angular applications, need to execute inline scripts and styles to make the magic happen. Have you ever wondered how the encapsulated component styles actually work? Angular injects these at runtime and this functionality is blocked if you have a CSP.&lt;/p&gt;

&lt;p&gt;The quick fix for this is to add the ‘unsafe-inline’ keyword like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script-src 'unsafe-inline'; style-src 'unsafe-inline';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows Angular to do what it needs to do. But of course, these settings are not limited to Angular scripts and styles &lt;em&gt;only&lt;/em&gt;. These settings allow scripts and styles from &lt;em&gt;any&lt;/em&gt; source, effectively negating the CSP for scripts and styles. Enter the  &lt;strong&gt;nonce&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Nonce
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Nonce&lt;/em&gt; is a shortened form of “number used once”. It is a unique, ephemeral value that must be shared between the server and client. The server generates the value and applies it to the CSP like so (line breaks added for readability):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script-src 'nonce-0136435421e75d07b8128a50b805041d'; 
style-src 'nonce-0136435421e75d07b8128a50b805041d';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then that &lt;em&gt;same&lt;/em&gt; nonce value must be applied to all inline scripts/styles. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script nonce="0136435421e75d07b8128a50b805041d"&amp;gt;
// …
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now any inline script or style that has this nonce value can execute, without having to add ‘unsafe-inline’ to the CSP.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Use a Nonce in Angular
&lt;/h3&gt;

&lt;p&gt;If your Angular application has a CSP and you do not want to use ‘unsafe-inline’ (and you shouldn’t if you can help it), this is the &lt;em&gt;minimum&lt;/em&gt; policy you must have according to Angular (line breaks added for readability):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default-src 'self'; 
style-src 'self' 'nonce-randomNonceGoesHere'; 
script-src 'self' 'nonce-randomNonceGoesHere';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since Angular 16, we can add a nonce value to the application element using the ngCspNonce attribute like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;app ngCspNonce="randomNonceGoesHere"&amp;gt;&amp;lt;/app&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also have the option to provide the nonce using the CSP_NONCE injection token, but this article will demonstrate the ngCspNonce attribute approach.&lt;/p&gt;

&lt;h4&gt;
  
  
  Adding the CSP and Nonce Locally
&lt;/h4&gt;

&lt;p&gt;In the angular.json file, add this under architect.serve(line breaks added for readability):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"options": {
  "headers": {
    "Content-Security-Policy": "default-src 'self'; 
                                script-src 'self'; 
                                style-src 'self';"
  }
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the project and you should see some ugly error messages like these:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AGyg1Ge_j2j4Okqyn3py_QA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AGyg1Ge_j2j4Okqyn3py_QA.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Error message after applying a CSP&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now add the ngCspNonce attribute to the app component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;app ngCspNonce="randomNonceGoesHere"&amp;gt;&amp;lt;/app&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And change the previously added “Content-Security-Policy” in angular.json to this (line breaks added for readability):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"options": {
  "headers": {
    "Content-Security-Policy": "default-src 'self'; 
                                script-src 'self' 'nonce-randomNonceGoesHere';
                                style-src 'self' 'nonce-randomNonceGoesHere';"
  }
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stop and run the application again and see that the errors are gone because the &lt;em&gt;nonce&lt;/em&gt; (randomNonceGoesHere)on the scripts and styles match the &lt;em&gt;nonce&lt;/em&gt; on the CSP. It’s ok that we’re just using randomNonceGoesHere and not replacing it because the CSP we added in angular.json only applies when using ng serve. This is just for testing locally.&lt;/p&gt;

&lt;h4&gt;
  
  
  Adding the CSP and Nonce in Deployed Environments
&lt;/h4&gt;

&lt;p&gt;Now we are fixed up locally, but how will this work in a deployed environment? For the deployed application, we will have to do some work on the server to add the CSP response header.&lt;/p&gt;

&lt;p&gt;I am going to show an example using &lt;a href="https://docs.nginx.com/nginx/admin-guide/web-server/" rel="noopener noreferrer"&gt;Nginx&lt;/a&gt;. I will assume familiarity with Nginx. If you are not familiar with it, take a look at this &lt;a href="https://dev.to/seanbh/how-to-serve-an-angular-application-with-nginx-d9a"&gt;post&lt;/a&gt; to see how to get an Angular application running locally with Nginx.&lt;/p&gt;

&lt;p&gt;In a deployed environment, we need Nginx to substitute an acceptable nonce for randomNonceGoesHere, both in the CSP and in the index.html file where the app component lives. You’ll recall that this is where we added the ngCspNonce attribute.&lt;/p&gt;

&lt;p&gt;I am going to show an example using the $request_id that Nginx generates for each request. Nginx says the $request_id is a “unique request identifier generated from 16 random bytes, in hexadecimal”. To my mind, this is an acceptable nonce value, but your security team should be consulted before implementing in Production to determine if you should &lt;em&gt;also&lt;/em&gt; make it cryptographically secure. But I want to keep this example simple, so I won’t here.&lt;/p&gt;

&lt;p&gt;In the nginx.conf file, add these lines in the server block (which are documented with comments):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# add CSP, using nonce-$request_id ($request_id is unique request identifiery generated from 16 random bytes, in hexadecimal)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-$request_id'; style-src 'self' 'nonce-$request_id';";

# substitute as many values as are found (not just one)
sub_filter_once off;

# substitute randomNonceGoesHere in the index.html file (ngCspNonce="randomNonceGoesHere") with
# the $request_id so that it matches the nonce-$request_id in the CSP
sub_filter randomNonceGoesHere $request_id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now for each request, a Content-Security-Policy header will be added with a unique nonce value for scripts and styles, and the same nonce value will be passed to Angular via the ngCspNonce attribute, and all will be well!&lt;/p&gt;

&lt;h3&gt;
  
  
  Content-Security-Policy-Report-Only
&lt;/h3&gt;

&lt;p&gt;One last thing to mention is the Content-Security-Policy-Report-Only header. This is just like the Content-Security-Policy header, except that it only &lt;em&gt;reports&lt;/em&gt; failures rather than actually blocking execution.&lt;/p&gt;

&lt;p&gt;So, if you have a lot of work to do before you can eliminate ‘unsafe-inline’, you can set up the Content-Security-Policy-Report-Only header to not allow ‘unsafe-inline’ and see what would break if you were to turn it on for real. This could be helpful if you want to eliminate ‘unsafe-inline’ but can’t do it in one fell swoop.&lt;/p&gt;

&lt;p&gt;That’s it! I hope you found this useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/security#content-security-policy" rel="noopener noreferrer"&gt;Angular — Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://content-security-policy.com/unsafe-inline/" rel="noopener noreferrer"&gt;unsafe-inline ⟶ CSP Guide (content-security-policy.com)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP" rel="noopener noreferrer"&gt;Content Security Policy (CSP) — HTTP | MDN (mozilla.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce" rel="noopener noreferrer"&gt;nonce — HTML: HyperText Markup Language | MDN (mozilla.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only" rel="noopener noreferrer"&gt;Content-Security-Policy-Report-Only — HTTP | MDN (mozilla.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_id" rel="noopener noreferrer"&gt;http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_id&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/http/ngx_http_headers_module.html" rel="noopener noreferrer"&gt;Module ngx_http_headers_module (nginx.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/http/ngx_http_sub_module.html" rel="noopener noreferrer"&gt;Module ngx_http_sub_module (nginx.org)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>nonce</category>
      <category>nginx</category>
      <category>csp</category>
      <category>angular</category>
    </item>
    <item>
      <title>How to Serve an Angular Application with Nginx</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Tue, 24 Oct 2023 18:58:19 +0000</pubDate>
      <link>https://dev.to/seanbh/how-to-serve-an-angular-application-with-nginx-d9a</link>
      <guid>https://dev.to/seanbh/how-to-serve-an-angular-application-with-nginx-d9a</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AHT2C3qjBz7gfJb5H" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AHT2C3qjBz7gfJb5H"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Kelvin Ang on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nginx is a popular HTTP and reverse proxy server that runs on Linux and is often used to serve Angular applications. A common way to run Nginx is within a Docker container.&lt;/p&gt;

&lt;p&gt;This article covers the minimum steps required to get this running on a local machine. You will need to have &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; installed on your machine if you want to follow along.&lt;/p&gt;
&lt;h3&gt;
  
  
  Create an Angular Application
&lt;/h3&gt;

&lt;p&gt;Create a new Angular application using 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;ng new nginx-example-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build the angular app by running:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The building of the application can be done inside of the Docker container but we’re going to do it outside of the container for now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Nginx
&lt;/h3&gt;

&lt;p&gt;The Docker image we will use has Nginx installed and ready to go. All we have to do is configure it. To do that we create a file in the root of the solution (where angular.json is) named nginx.conf with this content (which is explained with comments):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# the events block is required
events{}

http {
    # include the default mime.types to map file extensions to MIME types
    include /etc/nginx/mime.types; 

    server {        
        # set the root directory for the server (we need to copy our 
        # application files here)
        root /usr/share/nginx/html;

        # set the default index file for the server (Angular generates the 
        # index.html file for us and it will be in the above directory)
        index index.html;

        # specify the configuration for the '/' location
        location / {
            # try to serve the requested URI. if that fails then try to 
            # serve the URI with a trailing slash. if that fails, then 
            # serve the index.html file; this is needed in order to serve 
            # Angular routes--e.g.,'localhost:8080/customer' will serve 
            # the index.html file
            try_files $uri $uri/ /index.html;
        }
    }
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Docker
&lt;/h3&gt;

&lt;p&gt;Create a file in the root of the solution (where angular.json is) named Dockerfile (no extension) with this content (which is explained line-by-line with comments):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# use the latest version of the official nginx image as the base image
FROM nginx:latest
# copy the custom nginx configuration file to the container in the 
# default location
COPY nginx.conf /etc/nginx/nginx.conf
# copy the built Angular app files to the default nginx html directory
COPY /dist/nginx-example-app /usr/share/nginx/html

# the paths are relative from the Docker file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build the Docker Image
&lt;/h3&gt;

&lt;p&gt;There are two basic entities in docker — images and containers. The container is like a server and the image contains instructions for building that server. To borrow OOP terminology, the image is like the class and the container is like the instantiation of that class.&lt;/p&gt;

&lt;p&gt;VS Code has some helpful tools that allow you to build images and run containers using a GUI, but we’ll use the command line here. First, we build the image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t nginx-example-app-docker-image .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command simply builds the image.&lt;/p&gt;

&lt;p&gt;The -t nginx-example-app-docker-image portion names the  &lt;strong&gt;image&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The period at the end specifies the current directory (where the Docker file is) as the build context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run the Docker Container
&lt;/h3&gt;

&lt;p&gt;Next run the container which will use the image, as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --name nginx-example-app-docker-container -d -p 8080:80 nginx-example-app-docker-image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The --name nginx-example-app-docker-container portion species the name of the &lt;strong&gt;container&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The -d flag tells docker to run in detached mode (in the background).&lt;/p&gt;

&lt;p&gt;The -p 8080:80 flag maps port 8080 to 80. Inside the container, Nginx exposes the website on port 80 which is the default, and we did not have to specify that. Here we are saying that external clients can hit port 8080 on the container to access the website.&lt;/p&gt;

&lt;p&gt;The last argument is the name of the image to run: nginx-example-app-docker-image. Remember, this is what we named the image in the previous section.&lt;/p&gt;

&lt;p&gt;You should now be able to open a browser to &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt; and see the default Angular scaffolding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build the Application in Docker
&lt;/h3&gt;

&lt;p&gt;It’s common to let Docker build the Angular application. We can do that by modifying the Dockerfile with this content (which is explained line-by-line with comments):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# use a node image as the base image and name it 'build' for
# later reference
FROM node:18.18-alpine3.18 as build

# set the working directory to /app
WORKDIR /app
# copy the current directory contents into the container at /app
COPY . .
# install dependencies, matching package-lock.json
RUN npm ci
# build the app
RUN npm run build

# Use the latest version of the official Nginx image as the base image
FROM nginx:latest
# copy the custom nginx configuration file to the container in the default
# location
COPY nginx.conf /etc/nginx/nginx.conf
# copy the built application from the build stage to the nginx html 
# directory
COPY --from=build /app/dist/nginx-example-app /usr/share/nginx/html

# The above commands build the Angular app and then configure and build a 
# Docker image for serving it using the nginx web server.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our Docker file now uses what are called stages. Building the application will be the first stage and we name it build so that we can reference it later.&lt;/p&gt;

&lt;p&gt;Notice that for the build stage we are starting from the node:18.18-alpine3.18 image. How did I choose this image?&lt;/p&gt;

&lt;p&gt;We need an image that has node installed and I decided to use version 18. So, I went to the node page on docker hub and searched for &lt;a href="https://hub.docker.com/_/node/tags?page=1&amp;amp;name=18-alpine" rel="noopener noreferrer"&gt;18-alpine&lt;/a&gt;. The alpine variant uses the Alpine Linux image, which is smaller and contains everything we need.&lt;/p&gt;

&lt;p&gt;The search returned many images, and I chose the newest one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AlMISlcRQEgsEObZjaZTMPA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AlMISlcRQEgsEObZjaZTMPA.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Docker Hub search results for 18-alpine&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The rest of the changes are documented in the updated Docker file.&lt;/p&gt;

&lt;p&gt;There is one last thing to do though. Currently the Docker file is copying &lt;em&gt;all&lt;/em&gt; of our local files into the container, and we don’t need to do that. Let’s create a .dockerignore file in the root (where Dockerfile is) with the files we want to ignore, which will speed things up:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rebuilding and Rerunning
&lt;/h3&gt;

&lt;p&gt;If you still have the container running, you will need to remove the container before rebuilding the image and running a new container. Let’s add some tasks to package.json to make this easier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"build-image": "docker build -t nginx-example-app-docker-image .",
"remove-image": "docker rmi nginx-example-app-docker-image",
"run-container": "docker run --name nginx-example-app-docker-container -d -p 8080:80 nginx-example-app-docker-image",
"remove-container": "docker rm -f nginx-example-app-docker-container",
"containerize": "npm run build-image &amp;amp;&amp;amp; npm run run-container",
"recontainerize": "npm run remove-container &amp;amp;&amp;amp; npm run build-image &amp;amp;&amp;amp; npm run run-container"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these tasks in place, I can now do the following:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This will remove the running container, rebuild the image (which now rebuilds the application), and start a new container using the updated image. Now you can refresh the browser to see the updated running application.&lt;/p&gt;

&lt;p&gt;That’s it! I hope you found this useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/beginners_guide.html" rel="noopener noreferrer"&gt;Beginner’s Guide (nginx.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/_/nginx" rel="noopener noreferrer"&gt;nginx — Official Image | Docker Hub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files" rel="noopener noreferrer"&gt;Module ngx_http_core_module (nginx.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/example.html" rel="noopener noreferrer"&gt;Example nginx configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/ngx_core_module.html#include" rel="noopener noreferrer"&gt;http://nginx.org/en/docs/ngx_core_module.html#include&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/http/ngx_http_index_module.html" rel="noopener noreferrer"&gt;Module ngx_http_index_module (nginx.org)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/get-started/" rel="noopener noreferrer"&gt;Overview of the get started guide | Docker Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/_/node/" rel="noopener noreferrer"&gt;node — Official Image | Docker Hub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/_/alpine" rel="noopener noreferrer"&gt;https://hub.docker.com/_/alpine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>angular</category>
      <category>nginx</category>
    </item>
    <item>
      <title>Do We Still Need Frontend Frameworks in 2024?</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Thu, 19 Oct 2023 13:53:01 +0000</pubDate>
      <link>https://dev.to/seanbh/do-we-still-need-frontend-frameworks-in-2024-2230</link>
      <guid>https://dev.to/seanbh/do-we-still-need-frontend-frameworks-in-2024-2230</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YxKiKjAV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2Aw1h1wd7X4QdcFN1V" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YxKiKjAV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2Aw1h1wd7X4QdcFN1V" alt="" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Jon Tyson on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I recently encountered an argument that new web development should not utilize a frontend framework (Angular, React, Vue, etc.) due to the maintenance burden of keeping up with new versions of dependencies. The argument is that this maintenance burden is not justified because most applications just don’t need frontend frameworks anymore.&lt;/p&gt;

&lt;p&gt;Is this true? Let’s examine this claim in the context of a typical development shop in a med/large size company, which is responsible for many applications — both enterprise and consumer facing. I’ll be using Angular as my framework example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frameworks were Never Required
&lt;/h3&gt;

&lt;p&gt;The crux of the argument is that because of advancements in JavaScript, CSS and browser features, frameworks are no longer required. But I think this overstates the case somewhat. Frameworks were never &lt;em&gt;required&lt;/em&gt; to do anything. Frontend frameworks ship JavaScript (with HTML embedded within the JavaScript) and CSS. So, frameworks never did anything that couldn’t be done with JavaScript/CSS alone. They just made it much easier to do those things and as a result much faster.&lt;/p&gt;

&lt;p&gt;It’s very similar to the .NET framework. When .NET was released, there was nothing that it could do that could not be done with C/C++. The .NET framework just made it a lot easier, and therefore faster to do Windows development. I can remember some pushback when .NET came out from C/C++ developers who argued that you should just bite the bullet and learn C/C++. I remember at first feeling somewhat inferior to those developers since I was using a framework whose stated purpose was to make things easier and that felt like “cheating”.&lt;/p&gt;

&lt;p&gt;But businesses want results fast. As a result, a framework that makes development much easier and faster is going to catch on and that is what happened with .NET. It was hard to justify investing the time to learn and develop with C/C++ when .NET was so much easier and was what companies were looking for.&lt;/p&gt;

&lt;p&gt;I think the situation was (and still is) similar with frontend JavaScript frameworks. Sure, you can do everything with just plain JavaScript/CSS/HTML, but when there are alternatives available that are easier to learn and implement and that allow you to deliver solutions much faster it’s hard not to pursue that path — at least for companies that must deliver many applications with limited resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Framework features
&lt;/h3&gt;

&lt;p&gt;It is true that there have been advancements in JavaScript and browser features and many of those have been &lt;em&gt;driven by&lt;/em&gt; frontend frameworks. ES6 support for classes and modules gives us a way to structure our code in plain JavaScript. The ability to create custom elements that encapsulate functionality and communicate via custom events enables us to create reusable components. These advancements make it easier to develop using vanilla JavaScript than it used to be.&lt;/p&gt;

&lt;p&gt;But I’m not convinced that we are in a place where vanilla JavaScript has parity with frontend frameworks when it comes to building complex web applications quickly.&lt;/p&gt;

&lt;p&gt;For example, let’s look at the custom element example of a counter component. A counter component is one of the simplest reactive components you can implement and is often used for demonstration purposes. On the left is the implementation of a counter component as a custom HTML element using only vanilla JavaScript. On the right is the same implementation using an Angular component (v17).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gudgNnV---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A1_SVdnqKiwehFEBqhl0UpQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gudgNnV---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A1_SVdnqKiwehFEBqhl0UpQ.png" alt="Comparison between custom element and an Angular component" width="800" height="561"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Comparison between a custom element and an Angular component&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Angular component is implemented using fewer than half as many lines as the custom element. In addition, Angular generates the boilerplate of the component so that I only had to write the code in the red boxes. Also, with the Angular solution I have the option to move the template into its own HTML file which I much prefer. If we see this much difference in the implementation of the simplest component, what will it look like for a complex component?&lt;/p&gt;

&lt;p&gt;Another thing to note is that Angular sanitizes values before injecting them into the DOM to guard against XSS vulnerabilities. That’s not necessary for this component, but it is for many other components, and this is an example of functionality that teams would have to implement for themselves in a reusable way.&lt;/p&gt;

&lt;p&gt;Furthermore, JavaScript is not a type-safe language — i.e., type errors are not discovered until runtime, and you get little to no useful intellisense. Whether or not type checking is important is a separate topic, but many believe that it is and that is why Angular uses TypeScript in order to have compile time type checking and provide robust intellisense. Of course, you can use TypeScript without using a frontend framework, but you would have to take care of the transpilation yourself.&lt;/p&gt;

&lt;p&gt;Finally, frameworks like Angular provide more than just an easier way to create custom components. They also provide services and other functionality. To give just one example, in Angular it is easy to create an interceptor that you can use to modify all HTTP requests. Such an interceptor is useful for doing things like adding an authentication header value for API calls. Let’s look at how we might implement something like this ourselves in the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependencies Don’t Go Away — They Just Shift
&lt;/h3&gt;

&lt;p&gt;Let’s go back to the example of an HTTP interceptor that was just mentioned in the last section. How would I accomplish this if I was just using vanilla JavaScript?&lt;/p&gt;

&lt;p&gt;At first, I might duplicate the logic everywhere I make a request. I would quickly realize that I’m violating the DRY principle and would move this logic into a shared module and then import this module everywhere I wanted to use it. But then I would realize that I want other applications in my company to be able to use this functionality, so I would make it into a library so that all applications could use it in a versioned manner.&lt;/p&gt;

&lt;p&gt;Then I would realize that different applications have different use cases so I would need to make the code configurable so that it would work in different scenarios. Then I would realize that it would be nice to be able to do this multiple times for the same request and so I would come up with a way to apply multiple changes to the same request and do it in the order determined by the developer.&lt;/p&gt;

&lt;p&gt;Each time I make changes to the library I must be aware of the different ways in which the library is being used and take care not to break existing implementations. If the native webRequest browser API changes in some fundamental way or is superseded by something else, I will want to take advantage of those changes in the library. Indeed, I may be forced to make those changes and make them quickly if something changes that affects browser support — i.e., if browser updates are going to cause my solution not to work anymore.&lt;/p&gt;

&lt;p&gt;But I may not be able to do that in a 100% backwards compatible way. So, in that case I will have to retain the backwards compatible implementation while also implementing a new solution and figure out a way to migrate the consumers of my library. All of this takes place without any &lt;em&gt;third-party&lt;/em&gt; dependencies. But now the applications in my organization have a dependency on this library which I must maintain &lt;em&gt;myself&lt;/em&gt;. Obviously, this is only one example of shared functionality and there would of course be many others.&lt;/p&gt;

&lt;h3&gt;
  
  
  Embracing Open Standards is Good
&lt;/h3&gt;

&lt;p&gt;But I do take the point that if we are able to do something that is natively supported, we should try and do it natively. I believe Angular agrees with this and they regularly drop their custom implementations as JavaScript, CSS and browsers evolve.&lt;/p&gt;

&lt;p&gt;For example, they deprecated their custom flex box solution in favor of using plain CSS once the custom solution was no longer needed. They have also introduced a way to configure the HttpClient to use the native fetch API. Angular is also moving away from using their own modules now that modules are supported in ES6.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Do we use a solution that someone else has provided or do we roll our own? It’s not a new question. Generally, I think companies opt for using solutions that others have provided to speed up development and because they do not have the resources (in terms of skill or quantity or both) to implement their own solutions.&lt;/p&gt;

&lt;p&gt;However, this does come with the trade-off that you have to keep up with the dependencies you introduce. But I think for many companies implementing enterprise applications, the balance is still in favor of using a frontend framework.&lt;/p&gt;

</description>
      <category>framework</category>
      <category>frontend</category>
      <category>angular</category>
    </item>
    <item>
      <title>How to Test a Functional Interceptor in Angular</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Tue, 03 Oct 2023 21:24:20 +0000</pubDate>
      <link>https://dev.to/seanbh/how-to-test-a-functional-interceptor-in-angular-1bgp</link>
      <guid>https://dev.to/seanbh/how-to-test-a-functional-interceptor-in-angular-1bgp</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VElNONRS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A9sz3FqKaTK_DsTxb" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VElNONRS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A9sz3FqKaTK_DsTxb" alt="" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Ben Mullins on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This post will build upon my previous &lt;a href="https://dev.to/seanbh/how-to-create-a-functional-interceptor-in-angular-2kjp-temp-slug-3756378"&gt;one&lt;/a&gt; and show you how to test the functional interceptor that was implemented there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {
  HttpRequest,
  HttpInterceptorFn,
  HttpHandlerFn,
  HttpEvent,
} from '@angular/common/http';
import { Observable } from 'rxjs';

export const authInterceptor: HttpInterceptorFn = (
  request: HttpRequest&amp;lt;unknown&amp;gt;,
  next: HttpHandlerFn
): Observable&amp;lt;HttpEvent&amp;lt;unknown&amp;gt;&amp;gt; =&amp;gt; {
  const clonedRequest = request.clone({
    setHeaders: {
      Authorization: 'Bearer [the token]',
    },
  });
  return next(clonedRequest);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am going to compare and contrast testing class-based and functional interceptors in this post, but feel free to skip straight to the functional interceptor test if that is all you are interested in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Class-Based Test
&lt;/h3&gt;

&lt;p&gt;A simple class-based test might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { TestBed } from '@angular/core/testing';
import {
  HttpClientTestingModule,
  HttpTestingController,
} from '@angular/common/http/testing';
import { AuthInterceptor } from './auth.interceptor';
import { HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http';

describe('AuthInterceptor', () =&amp;gt; {
  let httpTestingController: HttpTestingController;
  let httpClient: HttpClient;

  beforeEach(() =&amp;gt; {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        AuthInterceptor,
        { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
      ],
    });
    httpTestingController = TestBed.inject(HttpTestingController);
    httpClient = TestBed.inject(HttpClient);
  });

  afterEach(() =&amp;gt; {
    httpTestingController.verify();
  });

  it('should add auth headers ', () =&amp;gt; {
    //arrange
    const url = '/mockendpoint';

    //act
    httpClient.get(url).subscribe();

    // assert
    const req = httpTestingController.expectOne(url);
    expect(req.request.headers.get('Authorization')).toEqual(
      'Bearer [the token]'
    );
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a fair bit of code here and I’ve gone over the details in a previous &lt;a href="https://dev.to/seanbh/how-to-unit-test-an-httpinterceptor-that-relies-on-ngrx-33pi"&gt;post&lt;/a&gt; and won’t repeat them here. The test itself is just making a (fake) HTTP request and then checking the header to verify that the token was added. It is the same regardless of whether the interceptor is class-based or functional. What does change is how we &lt;em&gt;provide&lt;/em&gt; the interceptor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functional Test
&lt;/h3&gt;

&lt;p&gt;Just like we did in the previous &lt;a href="https://dev.to/seanbh/how-to-create-a-functional-interceptor-in-angular-2kjp-temp-slug-3756378"&gt;post&lt;/a&gt;, we need to switch to providing HttpClient using the standalone API, and then we can provide authInterceptor at the same time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// removed the imports[]

providers: [
  provideHttpClient(withInterceptors([authInterceptor])),
  provideHttpClientTesting(),
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we have also included the provideHttpClientTesting function call and removed the imports array that contained HttpClientTestingModule.&lt;/p&gt;

&lt;p&gt;Remember, the shift to standalone includes replacing modules with function calls. Just like provideHttpClient replaced importing the HttpClientModule, provideHttpClientTesting replaces importing the HttpClientTestingModule.&lt;/p&gt;

&lt;p&gt;Here’s the diff between the class-based and functional test:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NsqG9qUx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AXrLy9zb4YyfHBsms_wgzUw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NsqG9qUx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AXrLy9zb4YyfHBsms_wgzUw.png" alt="" width="800" height="306"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The code difference between the class-based and functional tests&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is the test in full:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { TestBed } from '@angular/core/testing';
import {
  HttpTestingController,
  provideHttpClientTesting,
} from '@angular/common/http/testing';
import {
  HttpClient,
  provideHttpClient,
  withInterceptors,
} from '@angular/common/http';
import { authInterceptor } from './auth.interceptor';

describe('AuthInterceptor', () =&amp;gt; {
  let httpTestingController: HttpTestingController;
  let httpClient: HttpClient;

  beforeEach(() =&amp;gt; {
    TestBed.configureTestingModule({
      // here are the KEY changes
      providers: [
        provideHttpClient(withInterceptors([authInterceptor])),
        provideHttpClientTesting(),
      ],
    });
    httpTestingController = TestBed.inject(HttpTestingController);
    httpClient = TestBed.inject(HttpClient);
  });

  afterEach(() =&amp;gt; {
    httpTestingController.verify();
  });

  it('should add auth headers ', () =&amp;gt; {
    //arrange
    const url = '/mockendpoint';

    //act
    httpClient.get(url).subscribe();

    // assert
    const req = httpTestingController.expectOne(url);
    expect(req.request.headers.get('Authorization')).toEqual(
      'Bearer [the token]'
    );
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! I hope you found this useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/provideHttpClient"&gt;Angular — provideHttpClient&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/withInterceptors"&gt;Angular — withInterceptors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/testing/provideHttpClientTesting"&gt;Angular — provideHttpClientTesting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>providehttpclienttes</category>
      <category>interceptors</category>
      <category>unittesting</category>
    </item>
    <item>
      <title>How to Create a Functional Interceptor in Angular</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Tue, 03 Oct 2023 21:21:20 +0000</pubDate>
      <link>https://dev.to/seanbh/how-to-create-a-functional-interceptor-in-angular-kni</link>
      <guid>https://dev.to/seanbh/how-to-create-a-functional-interceptor-in-angular-kni</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2Ar3zV_CHyPnsxpvdP" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2Ar3zV_CHyPnsxpvdP"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Chris Moore on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Angular is moving towards &lt;em&gt;functional&lt;/em&gt; interceptors, rather than class-based ones (the same is true of guards). Note this statement in the docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Prefer…functional interceptors instead, as support for DI-provided interceptors may be phased out in a later release.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What is the difference between a class-based interceptor and a functional one? That is what we are going to explore in this post.&lt;/p&gt;

&lt;p&gt;I am going to compare and contrast class-based and functional interceptors in this post, but feel free to skip straight to the functional implementation if that is all you are interested in.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Interceptor
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Class-Based Version
&lt;/h4&gt;

&lt;p&gt;A simple class-based interceptor that adds an Authorization header to all HTTP requests would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(
    request: HttpRequest&amp;lt;unknown&amp;gt;,
    next: HttpHandler
  ): Observable&amp;lt;HttpEvent&amp;lt;unknown&amp;gt;&amp;gt; {
    const clonedRequest = request.clone({
      setHeaders: {
        Authorization: 'Bearer [the token]',
      },
    });
    return next.handle(clonedRequest);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interceptor is just a class that implements the HttpInterceptor interface and participates in dependency injection. The intercept method is the only method implemented and it takes the intercepted request and the next handler, which allows the request to be passed on through the pipeline.&lt;/p&gt;

&lt;p&gt;This interceptor is simply cloning the request and setting an Authorization header with a &lt;em&gt;fake&lt;/em&gt; Bearer token. It then hands the request off to the next handler (if you want to see a more realistic example of adding an Authorization header you can look at my previous &lt;a href="https://dev.to/seanbh/how-to-add-a-bearer-token-to-api-calls-when-using-ngrx-4jhh"&gt;post&lt;/a&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  Functional Version
&lt;/h4&gt;

&lt;p&gt;A functional version of this simple interceptor would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {
  HttpRequest,
  HttpInterceptorFn,
  HttpHandlerFn,
  HttpEvent,
} from '@angular/common/http';
import { Observable } from 'rxjs';

export const authInterceptor: HttpInterceptorFn = (
  request: HttpRequest&amp;lt;unknown&amp;gt;,
  next: HttpHandlerFn
): Observable&amp;lt;HttpEvent&amp;lt;unknown&amp;gt;&amp;gt; =&amp;gt; {
  const clonedRequest = request.clone({
    setHeaders: {
      Authorization: 'Bearer [the token]',
    },
  });
  return next(clonedRequest);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What changes do we see?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Obviously, the biggest change is that we’ve made the interceptor a constant &lt;em&gt;function&lt;/em&gt; (of type HttpInterceptorFn) rather than an injectable _class — _hence the interceptor is now functional rather than class-based.&lt;/li&gt;
&lt;li&gt;The function still takes the same request parameter, but the next handler is now a &lt;em&gt;function&lt;/em&gt; rather than a &lt;em&gt;class&lt;/em&gt;. As such, there is no handle method on next — rather we just invoke next() and pass in the cloned request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are the differences side by side:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AeKAziBNXf1RWr9oPAdn60g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AeKAziBNXf1RWr9oPAdn60g.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The code difference between the class-based and functional interceptors&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Providing the Interceptor
&lt;/h3&gt;

&lt;p&gt;The differences in the interceptor are pretty minimal in my opinion. What may be a little more challenging at first is understanding the shift in how we &lt;em&gt;provide&lt;/em&gt; the interceptor.&lt;/p&gt;
&lt;h4&gt;
  
  
  Class-Based
&lt;/h4&gt;

&lt;p&gt;We provide a class-based interceptor in the app module like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
...
...
imports: [    
    HttpClientModule,
...
...
providers: [
  { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that I’ve included the import of the HttpClientModule, not because it is required for the interceptor but because it is required to actually make HTTP requests — or at least it used to be. The way we are going to provide the new functional interceptor also changes the way we gain access to HttpClient.&lt;/p&gt;

&lt;p&gt;Note that there is a backwards compatible &lt;a href="https://angular.io/api/common/http/withInterceptorsFromDi" rel="noopener noreferrer"&gt;way&lt;/a&gt; to still use the HttpClientModule with a functional interceptor, but I wouldn’t recommend it unless you just need it for a temporary solution until you’re able to fully migrate.&lt;/p&gt;

&lt;h4&gt;
  
  
  Functional
&lt;/h4&gt;

&lt;p&gt;As part of the shift to standalone, Angular now has so-called standalone APIs that allow for building an application without modules. So, when we provide our new functional interceptor, we are going to remove the HttpClientModule completely, and use the standalone API to provide both the interceptor &lt;em&gt;and&lt;/em&gt; HttpClient:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// HttpClientModule was removed from imports

providers: [provideHttpClient(withInterceptors([authInterceptor]))],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The provideHttpClient function is all we need to make HttpClient available in the application. We pass in the withInterceptors function to provide authInterceptor at the same time.&lt;/p&gt;

&lt;p&gt;Here’s the diff between the module/class and standalone/functional approaches:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A-4viUjiW70IWIhpZWNJLTA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A-4viUjiW70IWIhpZWNJLTA.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The code difference between the module/class and standalone/functional approaches&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s it! I hope you found this useful.&lt;/p&gt;

&lt;p&gt;If you want to see how to unit test the functional interceptor we implemented here, check out this &lt;a href="https://medium.com/@seanhaddock_60973/how-to-test-a-functional-interceptor-in-angular-6c8095c1fb7d" rel="noopener noreferrer"&gt;post&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/provideHttpClient" rel="noopener noreferrer"&gt;Angular — provideHttpClient&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/withInterceptors" rel="noopener noreferrer"&gt;Angular — withInterceptors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/withInterceptorsFromDi#description" rel="noopener noreferrer"&gt;Angular — withInterceptorsFromDi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/HttpInterceptorFn" rel="noopener noreferrer"&gt;Angular — HttpInterceptorFn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>withinterceptors</category>
      <category>providehttpclient</category>
      <category>interceptors</category>
    </item>
    <item>
      <title>How to Unit Test Error Response Handling in Angular</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Wed, 13 Sep 2023 14:44:48 +0000</pubDate>
      <link>https://dev.to/seanbh/how-to-unit-test-error-response-handling-in-angular-c1g</link>
      <guid>https://dev.to/seanbh/how-to-unit-test-error-response-handling-in-angular-c1g</guid>
      <description>&lt;p&gt;In this post we’ll quickly see how to mock an error response in order to test that an HttpInterceptor is redirecting to a login page when a 401 status code is returned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing the Redirect
&lt;/h3&gt;

&lt;p&gt;First, in order to test a redirect, we create a redirect method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;redirect(href: string) {
  // don't redirect if localhost:9876 (for unit tests)
  if (window.location.href.indexOf('http://localhost:9876') === -1) {
    window.location.href = href;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is so that we can monitor when a redirect is requested and also &lt;strong&gt;&lt;em&gt;not&lt;/em&gt;&lt;/strong&gt; actually redirect during the unit test. You would need to change the port to whatever you are using, but 9876 is the default for Karma.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing for the Error Response
&lt;/h3&gt;

&lt;p&gt;Now we need to setup the beforeEach for the tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const redirectFunctionName = 'redirect';
const user = getTestUser();
let httpTestingController: HttpTestingController;
let httpClient: HttpClient;
let appConfig: AppConfig;
let globalErrorHandlerService: GlobalErrorHandlerService;

beforeEach(() =&amp;gt; {
  TestBed.configureTestingModule({
    imports: [HttpClientTestingModule],
    providers: [
      AuthInterceptor,
      { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
      { provide: APP_CONFIG, useValue: { apiHost: 'https://mockhost/api' } },
      provideMockStore({
        initialState: { user: { currentUser: user } },
      }),
    ],
  });
  httpTestingController = TestBed.inject(HttpTestingController);
  httpClient = TestBed.inject(HttpClient);
  appConfig = TestBed.inject(APP_CONFIG);
  globalErrorHandlerService = TestBed.inject(GlobalErrorHandlerService);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ve covered most of this code in detail in a previous &lt;a href="https://dev.to/seanbh/how-to-unit-test-an-httpinterceptor-that-relies-on-ngrx-33pi"&gt;post&lt;/a&gt;. The only significant change here is the injecting of the GlobalErrorHandlerService, which is just the service where I put the redirect method.&lt;/p&gt;

&lt;p&gt;Now we implement the test to see if the redirect method is called when a 401 response is received.&lt;/p&gt;

&lt;p&gt;First we arrange the test by setting the URL and a creating a spy for the GlobalErrorHandlerService, so that we can check whether or not the redirect method was called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should redirect to login when 401 response received', () =&amp;gt; {
  //arrange
  const url = `${appConfig.apiHost}/mockendpoint`;
  const redirectSpy = spyOn(globalErrorHandlerService, redirectFunctionName);

  //act

  //assert
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we perform the action to be tested. We make the call using httpClient.get, but it’s not actually going anywhere across the wire because we imported the HttpClientTestingModule, so that all HTTP requests will hit the HttpClientTestingBackend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//act
httpClient.get(url).subscribe();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now comes the important part and the crux of this post, which is simulating the error response.&lt;/p&gt;

&lt;p&gt;By calling httpTestingController.expectOne(url), we are doing two things. We are getting the mock test request while also setting the expectation that the (mock) call will be made exactly one time. If it is not made exactly one time the test will fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mockRequest = httpTestingController.expectOne(url);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have the mock test request we can simulate a response. This can be done with the flush method or in our case, the error method, since the error is all we are interested in.&lt;/p&gt;

&lt;p&gt;The error method expects a ProgressEvent which takes a type argument which is not important for our purposes. We’re interested in the second argument to the error method which is of type TestRequestOptions. In those options we can specify that the status of the response is 401.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mockRequest.error(new ProgressEvent('error'), { status: 401 });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we assert using our spy that the redirect method was called with the URL to the login page, which is where we want to direct our users when we receive a 401.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// assert
expect(redirectSpy).toHaveBeenCalledWith('/login');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the test in full:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//arrange
const url = `${appConfig.apiHost}/mockendpoint`;
const redirectSpy = spyOn(globalErrorHandlerService, redirectFunctionName);

//act
httpClient.get(url).subscribe();

const mockRequest = httpTestingController.expectOne(url);
mockRequest.error(new ProgressEvent('error'), { status: 401 });

// assert
expect(redirectSpy).toHaveBeenCalledWith('/login');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we add an afterEach function to verify that there are no outstanding requests after each test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;afterEach(() =&amp;gt; {
  httpTestingController.verify();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ll leave as homework adding a test to make sure the redirect method does &lt;strong&gt;not&lt;/strong&gt; get called if the status is &lt;strong&gt;not&lt;/strong&gt;  401.&lt;/p&gt;

&lt;p&gt;That’s it! I hope you found this useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/http-test-requests"&gt;https://angular.io/guide/http-test-requests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/testing/HttpTestingController#httptestingcontroller"&gt;https://angular.io/api/common/http/testing/HttpTestingController#httptestingcontroller&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/HttpBackend"&gt;https://angular.io/api/common/http/HttpBackend&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testrequest</category>
      <category>httptestingcontrolle</category>
      <category>angular</category>
      <category>unittesting</category>
    </item>
    <item>
      <title>How to Implement Angular Universal (SSR/SSG)</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Mon, 28 Aug 2023 15:14:54 +0000</pubDate>
      <link>https://dev.to/seanbh/how-to-implement-angular-universal-ssrssg-3e6e</link>
      <guid>https://dev.to/seanbh/how-to-implement-angular-universal-ssrssg-3e6e</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AoH9mmoI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2As8fNcSDm25-hyVBj" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AoH9mmoI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2As8fNcSDm25-hyVBj" alt="" width="800" height="531"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Guillermo Ferla on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In my previous &lt;a href="https://dev.to/seanbh/csr-ssr-ssg-and-isr-in-angular-52o7"&gt;post&lt;/a&gt; we took a look at CSR, SSR, SSG and ISR in Angular. In this post, I want to walk through how to setup Angular Universal to achieve SSR/SSG.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Starter App
&lt;/h3&gt;

&lt;p&gt;This post is just about setting up Angular Universal, so we want to start with a completed application. We’ll use the standard &lt;strong&gt;Tour of Heroes&lt;/strong&gt; app that you can download &lt;a href="https://angular.io/generated/zips/toh-pt6/toh-pt6.zip"&gt;here&lt;/a&gt;. If you want to follow along, download that app now.&lt;/p&gt;

&lt;p&gt;Once downloaded, run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This will install dependencies and open a browser with the app running. Open the dev tools, go to the Network tab, and do two things to help us test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check ‘Disable cache’&lt;/li&gt;
&lt;li&gt;Change ‘No Throttling’ to ‘Fast 3G’ to simulate a slower connection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refresh the browser. In my test, it took ~20 seconds to load the app, during which time I was presented with a blank white screen. Note that this is the dev build which has not been optimized, and the production build will take significantly less time. But the increased time here helps to emphasize the point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lFK2J01d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A93YjY2nkaIAs7jtLSNcf1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lFK2J01d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A93YjY2nkaIAs7jtLSNcf1g.png" alt="" width="800" height="148"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot of network tab&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The dashboard document, which is just the index.html file with the scripts injected, loaded in less than a second. But that document doesn’t display anything until all of the JavaScript has been loaded. Let’s see what happens when we add Angular Universal.&lt;/p&gt;
&lt;h3&gt;
  
  
  Add Angular Universal
&lt;/h3&gt;

&lt;p&gt;To add Angular Universal, stop the running app and execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng add @nguniversal/express-engine
npm run dev:ssr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that I usually use PowerShell as my terminal but when I execute npm run dev:ssr and make changes to the file, I intermittently receive an error, and I’ve read that other people have the same issue. So for this reason I use a bash shell to run this command.&lt;/p&gt;

&lt;p&gt;Navigate away from the app and then back to it. What is different? Now the page loads in less than a second rather than 20 seconds. Look at the network tab. Again, the dashboard document loads in under a second but now a full page is being delivered rather than just a shell.&lt;/p&gt;

&lt;p&gt;But the page is not interactive at that point. We still have to wait for the JavaScript to load for it to be interactive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Some Code to Help Visualize
&lt;/h3&gt;

&lt;p&gt;Now let’s add some code to help us visualize what is going on.&lt;/p&gt;

&lt;p&gt;Replace the contents of app.component.ts with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { isPlatformBrowser, isPlatformServer } from '@angular/common';
import {
  Component,
  PLATFORM_ID,
  TransferState,
  inject,
  makeStateKey,
} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title = 'Tour of Heroes';

  platformId = inject(PLATFORM_ID);
  transferState = inject(TransferState);

  browserTime?: string;
  serverTime?: string;

  ngOnInit() {
    const serverTimeStateKey = makeStateKey&amp;lt;string&amp;gt;('serverTime');

    if (isPlatformBrowser(this.platformId)) {
      // set the browser time now and every second after
      this.setBrowserTime();
      setInterval(() =&amp;gt; this.setBrowserTime(), 1000);

      // set the serverTime from transfer state
      this.serverTime = this.transferState.get(
        serverTimeStateKey,
        "I don't know, I wasn't generated on the server."
      );
    } else if (isPlatformServer(this.platformId)) {
      // set the serverTime and put in transfer state for the browser to read
      this.serverTime = new Date().toLocaleTimeString('en-US');
      this.transferState.set(serverTimeStateKey, this.serverTime);

      console.log('I am being rendered on the server');
    }
  }

  setBrowserTime() {
    this.browserTime = new Date().toLocaleTimeString('en-US');
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you use Angular Universal, components will &lt;em&gt;always&lt;/em&gt; be rendered in the browser but &lt;em&gt;sometimes&lt;/em&gt; they will &lt;em&gt;first&lt;/em&gt; be rendered on the server. Sometimes you have to know where the component is being rendered when you’re writing code and for that you use isPlatformBrowser and isPlatformServer.&lt;/p&gt;

&lt;p&gt;What we are doing here is simply setting the time of render for demonstration purposes. We set the time the component is rendered on the server and the time the component is rendered on the browser. We also log a message to the console to track when the component is being rendered on the server.&lt;/p&gt;

&lt;p&gt;When the component is rendered in the browser, it replaces what was there previously. So in order to preserve the server render time, we have to use TransferState. With TransferStatewe can remember and transfer data between the server and browser renders.&lt;/p&gt;

&lt;p&gt;Add the following in app.component.html, just above the router-outlet, so that we can see the browser and server times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div style="margin-top: 25px"&amp;gt;
  Time from the
  &amp;lt;span style="font-weight: 900; color: red; margin-right: 15px"&amp;gt;BROWSER:&amp;lt;/span&amp;gt;
  {{ browserTime }}
&amp;lt;/div&amp;gt;
&amp;lt;div style="margin-top: 25px"&amp;gt;
  Time from the
  &amp;lt;span style="font-weight: 900; color: red; margin-right: 15px"&amp;gt;SERVER:&amp;lt;/span&amp;gt;
  {{ serverTime }}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now refresh the page. The server time shows up as soon as the page loads and reflects the time when the full page was rendered on the server. The browser time however, does not appear until the JavaScript is loaded. It reflects the time the page was rendered by JavaScript in the browser. Now that we have JavaScript, we can continually update it like a clock.&lt;/p&gt;

&lt;p&gt;What happens if we refresh the page? Will the server time update or stay the same? The server time updates because every time you refresh, the full page is regenerated on the server:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vCwNxhTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/832/1%2Avy5VHSm3OV9AUu08UH8yfA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vCwNxhTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/832/1%2Avy5VHSm3OV9AUu08UH8yfA.png" alt="" width="800" height="247"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot showing browser and server times&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every time you refresh the page, you will observe the same behavior. But note that as you navigate to different routes, there is no console message and no server activity (aside from the favorite icon and that’s only because we have disabled the cache). Once the JavaScript loads, the application is a SPA just like normal. Click the ‘Heroes’ button to navigate to the heroes route to see for yourself.&lt;/p&gt;

&lt;p&gt;But if you enter the path to a different route in the address bar, it will request the fully rendered page for that route from the server. Enter: &lt;a href="http://localhost:4200/heroes"&gt;http://localhost:4200/heroes&lt;/a&gt; to confirm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5y5jC55--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/930/1%2AUGxxAE1zNzmYP23mElKgXQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5y5jC55--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/930/1%2AUGxxAE1zNzmYP23mElKgXQ.png" alt="" width="800" height="126"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot showing console message that component was rendered on the server&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerendering
&lt;/h3&gt;

&lt;p&gt;Angular Universal comes with prerendering built-in. Prerendering means generating full static HTML pages for routes at &lt;em&gt;build&lt;/em&gt; time. This reduces the initial load time even more since the browser does not have to wait for the server to generate the page when it requests it.&lt;/p&gt;

&lt;p&gt;The downside is that in order to update the page you have to do another build. And of course, if you need data from the request in order to generate the page (like a userId) prerendering would not be an option.&lt;/p&gt;

&lt;p&gt;By default, Angular Universal will try to guess all of the non-dynamic routes and generate pages for them. But you can turn this off and instead specify routes explicitly in a route.txt file or in the angular.json file. This is essentially hybrid SSR/SSG.&lt;/p&gt;

&lt;p&gt;To prerender, stop the running app and execute:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Note that the console message telling us that the component is being rendered on the server displayed three times — once for each route (/, /dashboard, /heroes) .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TefxrP_z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/943/1%2ACdaxsAa2MF_MQj0rciBvfA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TefxrP_z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/943/1%2ACdaxsAa2MF_MQj0rciBvfA.png" alt="" width="800" height="64"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Console message showing three routes prerendered&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Take a look in the dist/angular.io-example/browser folder and you will see three index.html files — again, one for each route:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--svXWbYjd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/345/1%2ACsbA5AFlrD5ki7Yc09I9GQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--svXWbYjd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/345/1%2ACsbA5AFlrD5ki7Yc09I9GQ.png" alt="" width="345" height="208"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot showing 3 HTML files&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Our browser/server time display is in the app component and so the HTML displaying the times got duplicated on all three pages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lFsZWRN5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1002/1%2AhH6gJP_ey4JBXjd41ps0Sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lFsZWRN5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1002/1%2AhH6gJP_ey4JBXjd41ps0Sw.png" alt="" width="800" height="98"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot showing duplicated HTML&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run serve:ssr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app is now running on port 4000, so navigate to &lt;a href="http://localhost:4000/"&gt;http://localhost:4000/&lt;/a&gt;. Note that we did not get a console message telling us that the component is being rendered on the server when the page was requested and delivered.&lt;/p&gt;

&lt;p&gt;Now what will happen when we refresh the page? Will the server time update or remain the same? It remains the same. The page is only generated on the server once at build time so the server time does not update.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9f6Z39xr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/597/1%2AHMSRcaGtQWkUHcL_w5GMnQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9f6Z39xr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/597/1%2AHMSRcaGtQWkUHcL_w5GMnQ.png" alt="" width="597" height="254"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot showing that the server time does not update when you refresh the page&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now we have an Angular application where we can generate full HTML pages for routes at build time, which is essentially SSG.&lt;/p&gt;

&lt;h3&gt;
  
  
  Potential Gotchas
&lt;/h3&gt;

&lt;p&gt;Before we leave, I want to highlight one of the potential gotchas with SSG. If you click on a specific hero, that will take you to a dynamic detail route and there is no server activity since the app is behaving as a SPA. But if you enter one of those detail routes (e.g., &lt;a href="http://localhost:4000/detail/13"&gt;http://localhost:4000/detail/13&lt;/a&gt;) in the address bar, the page will get generated on the server since that is a dynamic route that was not generated by default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_si3B_vZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/603/1%2AVYdQM0jC0ZPrQ2GIm9Z-1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_si3B_vZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/603/1%2AVYdQM0jC0ZPrQ2GIm9Z-1A.png" alt="" width="603" height="241"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot showing that the server time is updated if you request a detail route page&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now click the ‘Dashboard’ button. The server time still shows as 9:05 but this is not the time that the ‘Dashboard’ page was prerendered on the server — it’s the time the detail route was generated on the server.&lt;/p&gt;

&lt;p&gt;Now refresh the page. The server time reverts back to the correct prerendered value for the dashboard route.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qkfL9cBa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/564/1%2AoLASEBjvA_J1_cPaV6WqNA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qkfL9cBa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/564/1%2AoLASEBjvA_J1_cPaV6WqNA.png" alt="" width="564" height="246"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screen shot showing that the server time reverts to the prerendered value on page refresh&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This trivial example highlights one of the challenges that come with SSG and that is data consistency. If you are implementing SSG for an application that has dynamic data, you have to be careful and really think through how you are retrieving and displaying data. This is one of the reasons that you generally do not want to implement SSG unless your application needs it.&lt;/p&gt;

&lt;p&gt;Of course, it’s not all or nothing. You can choose SSG for static pages and SSR for pages that have dynamic data.&lt;/p&gt;

&lt;p&gt;That’s it. In this post we walked through how to implement SSR and SSG for an Angular application. Hope you found this useful — happy coding!&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/universal"&gt;https://angular.io/guide/universal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/prerendering"&gt;https://angular.io/guide/prerendering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/core/TransferState"&gt;https://angular.io/api/core/TransferState&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angularuniversal</category>
      <category>angularssr</category>
      <category>ssg</category>
      <category>prerender</category>
    </item>
    <item>
      <title>CSR, SSR, SSG and ISR in Angular</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Tue, 22 Aug 2023 19:49:05 +0000</pubDate>
      <link>https://dev.to/seanbh/csr-ssr-ssg-and-isr-in-angular-52o7</link>
      <guid>https://dev.to/seanbh/csr-ssr-ssg-and-isr-in-angular-52o7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XoyB2I6j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AGmDei3b4L_HmhZ6o" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XoyB2I6j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AGmDei3b4L_HmhZ6o" alt="" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Minku Kang on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-Side Rendering (CSR)
&lt;/h3&gt;

&lt;p&gt;With the rise of SPAs in the 2010s, CSR or Client-Side Rendering, became a popular rendering model for shops wanting to build modern web &lt;em&gt;applications&lt;/em&gt;. Instead of the browser making a request to the server for &lt;em&gt;each page&lt;/em&gt; of the website, a single HTML page (which is really just a shell) is sent to the browser when the site loads.&lt;/p&gt;

&lt;p&gt;Also sent to the browser at this time, is all of the JavaScript needed for the entire application, which then renders all of the subsequent HTML, &lt;em&gt;on the client&lt;/em&gt; (we’re setting aside lazy-loaded modules and code-splitting here, for simplicity sake).&lt;/p&gt;

&lt;p&gt;Since everything is loaded up front, there are no additional trips to the server needed except to load data from APIs. So user interaction/navigation is instantaneous, making a website behave almost like a desktop application.&lt;/p&gt;

&lt;p&gt;But this is not ideal for website crawlers because they have to wait on that initial load and execute JavaScript to see page content. Therefore, CSR apps &lt;em&gt;might&lt;/em&gt; receive a lower ranking from search engines. For websites that need the best possible SEO and are not behind a login wall (in which case there are no pages that can be indexed anyway), this might not be acceptable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I find that SEO is usually discussed in the abstract and it’s hard to find solid data — I think because there are so many variables. As a developer, you can test your local site for SEO using Litehouse in dev tools and with the &lt;a href="https://github.com/GoogleChrome/web-vitals-extension"&gt;Web Vitals&lt;/a&gt; chrome extension. Again, there are many variables to consider, so you can’t assume that just because you get a 100 SEO score in Litehouse that you’re good to go. I also don’t think that you can assume your CSR application cannot achieve good SEO, especially as crawlers evolve.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Additionally, while loading everything up front as CSR does is great for interaction/navigation once the first (and only) page is loaded, it may increase the load time of that first page. One important measure of this is First Contentful Paint (FCP), which is the time it takes for the first text or image to be rendered in the browser. A time of 1.8 seconds or less is considered fast (by Google). You probably don’t have to worry too much about this if your users have good internet connections. But this could become an issue for users with poor internet connections, such as you might experience on mobile devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server-Side Rendering (SSR)
&lt;/h3&gt;

&lt;p&gt;To improve SEO and initial page load time, SSR or Server-Side Rendering, was introduced. SSR requires a server which runs the necessary JavaScript and makes the necessary API calls to construct and deliver a full HTML page on the first request, which may improve the initial load time and SEO since it allows the crawler to see page content without executing JavaScript.&lt;/p&gt;

&lt;p&gt;One trade-off is that this increases the server load for very high traffic websites. Additionally, while the data for the page is being retrieved, the user will not see &lt;em&gt;anything&lt;/em&gt;, which is one of reasons why CSR became popular. If it takes a fairly long time to retrieve the data for a page, then CSR will deliver the content of a page to the user faster that SSR, even if it’s not the complete page.&lt;/p&gt;

&lt;p&gt;With SSR, we’re back to where we were in the pre-SPA days for the initial page load. For websites that need the best SEO and aren’t behind a login-wall, the trade-off is considered worth it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Static Site Generation (SSG)
&lt;/h3&gt;

&lt;p&gt;Wanting to improve the initial page load time even more, SSG or Static Site Generation, was introduced. With SSG the entire website, including all of the data needed, is constructed at build time and deployed out to a CDN. This drastically increases the &lt;em&gt;build&lt;/em&gt; time, but the result is that everything is prebuilt and ready to go, resulting in the fastest possible initial page load.&lt;/p&gt;

&lt;p&gt;Additionally, websites that have a global reach can deploy to CDN’s around the world, dropping the load time a little more for users in different parts of the world. This is good for static sites whose content does not change very often (like documentation or blog sites) because you have to rebuild the entire site when the content changes. Crucially, the page data cannot be in any way dependent upon the request (or the user making the request), since the page is populated with data long before the user or the request comes along.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incremental Static Regeneration (ISR)
&lt;/h3&gt;

&lt;p&gt;About a year ago, Next.js introduced something called ISR or Incremental Static Regeneration. With ISR, a page can be static like with SSG, but you can specify a revalidation interval so that a user will always receive a static page, but if the revalidation interval has passed, the page will be regenerated in the background and the &lt;em&gt;next&lt;/em&gt; user will receive with the updated (static) page.&lt;/p&gt;

&lt;p&gt;So it is still the case that the first user will receive a stale page — but only that first user. This eliminates the need to rebuild the entire site when the content changes. It is still the case that the page data cannot be dependent upon the request or the user.&lt;/p&gt;

&lt;p&gt;Next.js was created specifically to address these rendering optimization techniques which most impact websites that have very large traffic, a global reach, and need good SEO, such as Netflix, Hulu, Target, etc. As such, Next.js has focused more on SSR/SSG/ISR than have frameworks like Angular, but I think that is starting to change.&lt;/p&gt;

&lt;h3&gt;
  
  
  SSR, SSG and ISR in Angular
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/angular/universal"&gt;Angular Universal&lt;/a&gt; is the official SSR library for Angular and has been around since 2017. It has been announced recently that it will be moved into the core framework in the future. The team has been working on improving SSR, and non-destructive hydration (which doesn’t destroy and rebuild the DOM) was released in developer preview in v16.&lt;/p&gt;

&lt;p&gt;SSG has been possible for Angular since around 2019, with the standalone tool &lt;a href="https://scully.io/"&gt;Scully&lt;/a&gt;. Since early 2021, SSG and hybrid SSR/SSG has been possible with Angular Universal alone using &lt;a href="https://angular.io/guide/prerendering"&gt;prerender&lt;/a&gt;. Recently, a new meta-framework has been developed that I think seeks to be to Angular what Next.js is to React — &lt;a href="https://analogjs.org/"&gt;Analog&lt;/a&gt;. It will be very interesting to see how it develops alongside the core framework.&lt;/p&gt;

&lt;p&gt;For ISR, a library has surfaced called &lt;a href="https://github.com/eneajaho/ngx-isr"&gt;ngx-isr&lt;/a&gt;. It makes it very easy to implement ISR on top of Angular Universal. However, to be accurate, I think it differs slightly from ISR in Next.js in that the &lt;em&gt;first&lt;/em&gt; serve will always be SSR, as opposed to Next.js where the first serve is always SSG. It is possible to implement the Next.js flavor of ISR by combining Angular Universal’s prerender capability with serverless or edge functions, there just is no built-in way or tool to do this for you — yet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Serverless functions are code that executes without the developer worrying about where it runs. It still runs on a server, of course, it’s just that it’s a cloud server that the developer doesn’t have to mess with.&lt;/p&gt;

&lt;p&gt;Edge functions are basically the same thing, except that they execute at the edge of the network, closer to the user, thereby reducing latency a bit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;While CSR works just as well or is preferred for many websites (and I would say most websites where Angular tends to find itself), there are situations where SSR/SSG/ISR are needed. Although frameworks like Next.js have led the way with these techniques, you can still achieve SSR, SSG or hybrid SSR/SSG easily with Angular. It may not be quite as easy to achieve ISR (the Next.js version) in Angular as it is in some other frameworks yet, but I would expect that to change soon.&lt;/p&gt;

&lt;p&gt;It’s exciting to see that the Angular community is focusing more on SSR/SSG/ISR and I look forward to seeing the changes that are coming soon — from the core team’s focus on SSR/SSG, to the new meta-framework, Analog.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.angular.io/whats-next-for-server-side-rendering-in-angular-2a6f27662b67"&gt;https://blog.angular.io/whats-next-for-server-side-rendering-in-angular-2a6f27662b67&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=TXhZ1Hs5MoE"&gt;https://www.youtube.com/watch?v=TXhZ1Hs5MoE&lt;/a&gt; (rangle.io webinar on Analog)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics"&gt;https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/learn-core-web-vitals/?utm_source=lighthouse&amp;amp;utm_medium=devtools"&gt;https://web.dev/learn-core-web-vitals/?utm_source=lighthouse&amp;amp;utm_medium=devtools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/vitals-measurement-getting-started/"&gt;https://web.dev/vitals-measurement-getting-started/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mgechev/hybrid-rendering"&gt;https://github.com/mgechev/hybrid-rendering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/universal"&gt;https://angular.io/guide/universal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/docs/lighthouse/performance/first-contentful-paint/"&gt;https://developer.chrome.com/docs/lighthouse/performance/first-contentful-paint/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>staticsitegeneration</category>
      <category>angular</category>
      <category>angularuniversal</category>
      <category>clientsiderendering</category>
    </item>
    <item>
      <title>How to Unit Test an HttpInterceptor that Relies on NgRx</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Thu, 20 Jul 2023 14:06:30 +0000</pubDate>
      <link>https://dev.to/seanbh/how-to-unit-test-an-httpinterceptor-that-relies-on-ngrx-33pi</link>
      <guid>https://dev.to/seanbh/how-to-unit-test-an-httpinterceptor-that-relies-on-ngrx-33pi</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BIshwgAN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AJnW_vmHjDMcIe5Ce" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BIshwgAN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AJnW_vmHjDMcIe5Ce" alt="" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Nguyen Dang Hoang Nhu on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a &lt;a href="https://dev.to/seanbh/how-to-add-a-bearer-token-to-api-calls-when-using-ngrx-4jhh"&gt;previous post&lt;/a&gt;, we looked at how to setup an &lt;strong&gt;HttpInterceptor&lt;/strong&gt; to add the Bearer token to the HTTP Authorization Header, when that token is stored in state with NgRx. In this post, we’ll look at how to unit test that interceptor with Jasmine/Karma.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up beforeEach
&lt;/h3&gt;

&lt;p&gt;Modify the beforeEach method of the test file as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let httpTestingController: HttpTestingController;
let httpClient: HttpClient;
let appConfig: AppConfig;

beforeEach(() =&amp;gt; {
  TestBed.configureTestingModule({
    imports: [HttpClientTestingModule],
    providers: [
      AuthInterceptor,
      { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },      
      { provide: APP_CONFIG, useValue: { apiHost: '' } },      
      provideMockStore({
          initialState: { user: { currentUser: user } },
      }),
    ],
  });
  httpTestingController = TestBed.inject(HttpTestingController);
  httpClient = TestBed.inject(HttpClient);
  appConfig = TestBed.inject(APP_CONFIG);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unsurprisingly, the beforeEach method executes before each test runs. The first thing we do is configure the testing module. Tests run in isolation, so the setup we provide in the AppModule (or any other module) does not get applied here. So we have to configure the testing module, just like we have to configure the AppModule for our application. Let’s break this down.&lt;/p&gt;

&lt;p&gt;We import the HttpClientTestingModule, so that all HTTP requests will hit the HttpClientTestingBackend, &lt;strong&gt;instead of our real API&lt;/strong&gt;. We don’t want to make actual requests to a real API in a unit test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;imports: [HttpClientTestingModule],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we provide the AuthInterceptor to our testing module and specify that it should be used in the request pipeline by providing it for the HTTP_INTERCEPTORS injection token. This means that any HTTP request (even our fake ones) will go through our interceptor. My implementation also depends on an APP_CONFIG token so I have to provide a value for that, which contains the apiHost. This is not a real API host — we just need a constant value we can compare against.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AuthInterceptor,
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },      
{ provide: APP_CONFIG, useValue: { apiHost: 'https://mockhost/api' } },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last thing we need to do in the providers array is call a helper method that NgRx supplies, which adds all of the providers necessary to mock the NgRx Store: provideMockStore(). If you have initial state that needs to be set for every test, you can provide that initial state to this method, as we’ve done in the code snippet above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provideMockStore({
    initialState: { user: { currentUser: user } },
}),
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can set/modify state in the test itself, by injecting the MockStore class and calling setState(). We don’t need to do that here, but this is what that would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
store = TestBed.inject(MockStore);
...
store.setState({ user: { currentUser: user } });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, we inject the dependencies that we need, to make them available for each test. Importing the HttpClientTestingModule is enough to make HTTP requests go to a fake backend, but the HttpTestingController class is needed to &lt;em&gt;inspect&lt;/em&gt; those request and to return mock data, if needed.&lt;/p&gt;

&lt;p&gt;The HttpClient is still needed and used, just like it is in the real application. The difference here is that we’ve told Angular to use a test HttpBackend, by importing the HttpClientTestingModule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;httpTestingController = TestBed.inject(HttpTestingController);
httpClient = TestBed.inject(HttpClient);
appConfig = TestBed.inject(APP_CONFIG);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Test
&lt;/h3&gt;

&lt;p&gt;Create the following test to verify that the Authorization header will be added to any HTTP request made to the &lt;em&gt;appConfig.apiHost&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should add auth headers for calls to appConfig.apiHost', () =&amp;gt; {
  //arrange
  const url = `${appConfig.apiHost}/mockendpoint`;

  //act
  httpClient.get(url).subscribe();

  // assert
  const req = httpTestingController.expectOne(url);
  expect(req.request.headers.get('Authorization'))
                            .toEqual(`Bearer ${user.authToken}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First we arrange the test, just by specifying a URL to call. The only important piece here is the appConfig.apiHost. The rest can be anything and does not actually exist anywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const url = `${appConfig.apiHost}/mockendpoint`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we make the call to that URL, but remember it’s not actually going anywhere across the wire.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;httpClient.get(url).subscribe();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we get the fake request, using the HttpTestingController, and verify that the Authorization Header has been set with the user’s Bearer auth token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const req = httpTestingController.expectOne(url);
expect(req.request.headers.get('Authorization'))
                          .toEqual(`Bearer ${user.authToken}`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have a test to ensure that our Authorization Header will be added to every HTTP request to the appConfig.apiHost, and that the value of the Header will be ‘Bearer’ plus the user’s Bearer token.&lt;/p&gt;

&lt;p&gt;We would also want to add a test to make sure that the opposite is true — that calls &lt;em&gt;not&lt;/em&gt; to appConfig.apiHost do &lt;em&gt;not&lt;/em&gt; have the Header added. I’ll include that test here for reference, but I don’t think it requires any additional explanation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should not add auth headers for calls that are not to appConfig.apiHost', () =&amp;gt; {
  //arrange
  const url = `https://someotherurl/mockendpoint`;

  //act
  httpClient.get(url).subscribe();

  // assert
  const req = httpTestingController.expectOne(url);
  expect(req.request.headers.has('Authorization')).toBe(false); 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it for this one. Hope you find it useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/seanbh/how-to-add-a-bearer-token-to-api-calls-when-using-ngrx-4jhh"&gt;https://medium.com/@seanhaddock_60973/how-to-add-a-bearer-token-to-api-calls-when-using-ngrx-317f35fbb6f2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/testing/HttpClientTestingModule"&gt;https://angular.io/api/common/http/testing/HttpClientTestingModule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ngrx.io/api/store/testing/provideMockStore"&gt;https://ngrx.io/api/store/testing/provideMockStore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ngrx.io/api/store/testing/MockStore"&gt;https://ngrx.io/api/store/testing/MockStore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/testing/HttpTestingController"&gt;https://angular.io/api/common/http/testing/HttpTestingController&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/api/common/http/HttpBackend"&gt;https://angular.io/api/common/http/HttpBackend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/http-test-requests"&gt;https://angular.io/guide/http-test-requests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ngrx</category>
      <category>angularhttpintercept</category>
      <category>angular</category>
      <category>unittesting</category>
    </item>
    <item>
      <title>How to Add a Bearer Token to API calls when Using NgRx</title>
      <dc:creator>seanbh</dc:creator>
      <pubDate>Mon, 17 Jul 2023 21:00:38 +0000</pubDate>
      <link>https://dev.to/seanbh/how-to-add-a-bearer-token-to-api-calls-when-using-ngrx-4jhh</link>
      <guid>https://dev.to/seanbh/how-to-add-a-bearer-token-to-api-calls-when-using-ngrx-4jhh</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EE9QTUp3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AwHbJYXk8pRvoUGzl" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EE9QTUp3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AwHbJYXk8pRvoUGzl" alt="" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by Simon Hurry on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With Angular, you don’t have to add the Bearer authorization token to the header of every API call manually. Instead you can use an &lt;strong&gt;HttpInterceptor&lt;/strong&gt; , which allows you to &lt;em&gt;intercept&lt;/em&gt; every HTTP request and modify it before passing it through to the rest of the pipeline. Let’s take a look.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adding an HttpInterceptor
&lt;/h3&gt;

&lt;p&gt;You can use the CLI to create an interceptor with 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;ng g interceptor auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates an auth.interceptor.ts file with a single method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(request: HttpRequest&amp;lt;unknown&amp;gt;, next: HttpHandler): Observable&amp;lt;HttpEvent&amp;lt;unknown&amp;gt;&amp;gt; {
    return next.handle(request);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’re meant to modify the HTTP request as needed, and then pass it through to the next handler in the pipeline. We’ll come back to this in a moment. For now just note that it returns an &lt;em&gt;Observable&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Next we need to let Angular know to plug our interceptor into the request pipeline. In app.module.ts, add this new interceptor class to the providers array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;providers: [
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the intercept method of AuthInterceptor will be called on &lt;em&gt;every&lt;/em&gt; HTTP request. But it doesn’t yet do anything — let’s fix that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding the User’s Bearer Token to the HTTP Request Header
&lt;/h3&gt;

&lt;p&gt;We want to add an Authorization header that contains the Bearer token of the currently logged in User. If you use NgRx in your application, then there’s a good chance that token is stored in NgRx state. Since the intercept method returns an Observable, we can use the mergeMap operator to get the token from state and then modify the request to add it as an HTTP header. Change the intercept method to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intercept(req: HttpRequest&amp;lt;unknown&amp;gt;, next: HttpHandler): Observable&amp;lt;HttpEvent&amp;lt;unknown&amp;gt;&amp;gt; {
    if (this.appConfig.apiHost &amp;amp;&amp;amp; 
        req.url.startsWith(this.appConfig.apiHost)) {
      return this.store.select(userFeature.selectCurrentUser).pipe(
        first(),
        mergeMap((currentUser) =&amp;gt; {
          if (currentUser) {
            const authReq = req.clone({
              setHeaders: {
                Authorization: `Bearer ${currentUser.authToken}`
              },
            });
            return next.handle(authReq);
          }
          return next.handle(req);
        })
      );
    }
    return next.handle(req);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s break this down.&lt;/p&gt;

&lt;p&gt;First, we want to make sure that this request is going to our API host. Otherwise, not only is the token not needed, but we don’t &lt;em&gt;want&lt;/em&gt; to send the Bearer token anywhere other than our API. So if the request URL does not start with our API host, we just pass it through unchanged.&lt;/p&gt;

&lt;p&gt;Next we select the current User from state with this.store.select. Note the return keyword. Recall that we need to return an &lt;em&gt;Observable&lt;/em&gt;, so we’ll project the Observable returned by this.store.select into the Observable that this method returns.&lt;/p&gt;

&lt;p&gt;We use the first operator because we only need the first value.&lt;/p&gt;

&lt;p&gt;Next we use the mergeMap operator to project (and flatten) the Observable that gives us currentUser, into the Observable returned by next.handle(req).&lt;/p&gt;

&lt;p&gt;Inside mergeMap, if we don’t have the User in state for some reason, we just pass the request through unchanged. Otherwise, we clone the request and add the Authorization header to it. Then we pass the &lt;em&gt;cloned&lt;/em&gt; request on to the next handler in the pipeline.&lt;/p&gt;

&lt;p&gt;Now every call to our API will have the User’s bearer token added to the HTTP Authorization header.&lt;/p&gt;

&lt;p&gt;In a future post, we’ll look at how we can unit test this interceptor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/http-intercept-requests-and-responses"&gt;https://angular.io/guide/http-intercept-requests-and-responses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/http-interceptor-use-cases"&gt;https://angular.io/guide/http-interceptor-use-cases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rxjs.dev/api/operators/mergeMap"&gt;https://rxjs.dev/api/operators/mergeMap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ngrx.io/docs"&gt;https://ngrx.io/docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>ngrx</category>
      <category>authorization</category>
      <category>httpinterceptors</category>
    </item>
  </channel>
</rss>
