<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Angular Notes]]></title><description><![CDATA[A personal blog dedicated to Angular development.

I write about Angular concepts, best practices, tips, and real-world solutions based on my professional exper]]></description><link>https://blog.jonandonicastelo.org</link><generator>RSS for Node</generator><lastBuildDate>Thu, 30 Apr 2026 01:56:28 GMT</lastBuildDate><atom:link href="https://blog.jonandonicastelo.org/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The event loop]]></title><description><![CDATA[What is its purpose?
It schedules callbacks to be able to be executed.
Topics involved

The call stack: When a function is executed (synchronous code or callbacks), it enters the call stack. The call stack contains all the current executing functions...]]></description><link>https://blog.jonandonicastelo.org/the-event-loop</link><guid isPermaLink="true">https://blog.jonandonicastelo.org/the-event-loop</guid><category><![CDATA[Event Loop]]></category><category><![CDATA[EventLoop]]></category><category><![CDATA[event loop in js]]></category><category><![CDATA[Event Loop Explained]]></category><dc:creator><![CDATA[Jon Andoni Castelo Meléndez]]></dc:creator><pubDate>Wed, 19 Feb 2025 15:26:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1739978684145/b1942b18-567e-42bf-892d-01dc229b8cf3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>What is its purpose?</strong></p>
<p>It schedules callbacks to be able to be executed.</p>
<p><strong>Topics involved</strong></p>
<ul>
<li><p>The <em>call stack</em>: When a function is executed (synchronous code or callbacks), it enters the call stack. The <em>call stack</em> contains all the current executing functions, starting for the root (anonymous).</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739975531274/1f4bb04e-d4c1-4b25-8725-83d6b8ad102a.png" alt class="image--center mx-auto" /></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739975451658/ffbcbcf1-2f62-418c-a862-95003c156009.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>The <em>task queue</em>: Its a queue where asynchronous tasks are queued when they are completed.</p>
</li>
<li><p>The <em>microtask queue</em>: It’s a queue where asynchronous microtasks are queued when they are completed.</p>
</li>
</ul>
<p><strong>How <em>event loop</em> works?</strong></p>
<p>The <em>event loop</em> checks continuosly the <em>call stack.</em> If it is empty, it will check if any microtask is in the <em>microtasks queue</em>. If any, it will execute the callback and as soon as executed, it will enter the <em>call stack</em>. Then, it will check the <em>task queue</em> and if there is any task, it will execute the callback and as and as soon as executed, it will enter the <em>call stack</em>. This is a process that happens continuously as the name suggests.</p>
<p><strong>Small diagram</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739978366089/26393d96-1311-4878-a87d-08b73d5ffbdb.png" alt class="image--center mx-auto" /></p>
<p><strong>Small example</strong></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Synchronous code</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-number">1</span>);

<span class="hljs-comment">// Microtask</span>
<span class="hljs-built_in">Promise</span>.resolve().then(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-number">2</span>);
});

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

<span class="hljs-comment">// Task</span>
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-number">4</span>);
}, <span class="hljs-number">0</span>);

<span class="hljs-built_in">Promise</span>.resolve().then(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-number">5</span>);
});

<span class="hljs-built_in">console</span>.log(<span class="hljs-number">6</span>);
</code></pre>
<p><strong>Example output</strong></p>
<p>1<br />3<br />6<br />2<br />5<br />4</p>
]]></content:encoded></item><item><title><![CDATA[Angular Signals]]></title><description><![CDATA[The next explanations are based on this project. To get the most of this article it is recommended to not only read it, but to practice creating a similar project.
This is a demo of the application functionality:


With the arrival of Angular Signals...]]></description><link>https://blog.jonandonicastelo.org/angular-signals</link><guid isPermaLink="true">https://blog.jonandonicastelo.org/angular-signals</guid><category><![CDATA[Angular]]></category><category><![CDATA[Angular Signals]]></category><dc:creator><![CDATA[Jon Andoni Castelo Meléndez]]></dc:creator><pubDate>Sun, 08 Dec 2024 14:27:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733669190325/a84f29d0-b491-4ae5-9a22-dab23a49592e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The next explanations are based on <a target="_blank" href="https://github.com/fullstackdeveloperbilbao/angular-signals-example.git"><strong>this project</strong>.</a> To get the most of this article it is recommended to not only read it, but to practice creating a similar project.</p>
<p>This is a demo of the application functionality:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/J2T21W7V32k?si=CgOY5B1OtMeGYK8b"></iframe>

<p>With the arrival of Angular Signals, achieving reactivity and handling change detection have become much simpler than when using Zone.js.</p>
<p>To explore this assertion, we will configure our application to run without Zone.js—thereby removing its automatic change detection mechanism—and rely solely on Signals for reactivity:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> {
  ApplicationConfig,
  provideExperimentalZonelessChangeDetection,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> appConfig: ApplicationConfig = {
  providers: [provideExperimentalZonelessChangeDetection()],
};
</code></pre>
<p>Then, we will create the interface for our fetched data:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Data {
  imageUrl: <span class="hljs-built_in">string</span>;
  title: <span class="hljs-built_in">string</span>;
}
</code></pre>
<p>Next, the we will create the service that fetches and modifies the data. We have asigned 1 second delay in fetchData method to simulate a request and we have added a reverseData method to modify data and see how the modification is shown instantly in the app, showing the reactive capabilities of signals (switching effect of images and titles, as shown in the video):</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable, signal } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { Data } <span class="hljs-keyword">from</span> <span class="hljs-string">'../models/data.interface'</span>;

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DataService {
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> data = signal&lt;Data[]&gt;([]);

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

  <span class="hljs-comment">// request simulation</span>
  fetchData() {
    <span class="hljs-keyword">const</span> newData: Data[] = [
      {
        imageUrl:
          <span class="hljs-string">'https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/a97cc6bd-3b7b-44aa-b03d-90717569e29b/dxnwwo-95a4dba9-a6a5-4c73-a567-4c3f00c24607.jpg/v1/fill/w_1024,h_768,q_75,strp/pupy_dogs__3_by_little_drunk_jesus_dxnwwo-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9NzY4IiwicGF0aCI6IlwvZlwvYTk3Y2M2YmQtM2I3Yi00NGFhLWIwM2QtOTA3MTc1NjllMjliXC9keG53d28tOTVhNGRiYTktYTZhNS00YzczLWE1NjctNGMzZjAwYzI0NjA3LmpwZyIsIndpZHRoIjoiPD0xMDI0In1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmltYWdlLm9wZXJhdGlvbnMiXX0.ShrBRJlt9X27CrEkj8EZr1s6tkjqhIAIMvV1fN8Kdwk'</span>,
        title: <span class="hljs-string">'Brown pupy'</span>,
      },
      {
        imageUrl:
          <span class="hljs-string">'https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/a97cc6bd-3b7b-44aa-b03d-90717569e29b/dxnwso-a8ad02ba-f373-470f-baeb-bebfda554aaa.jpg/v1/fill/w_1024,h_768,q_75,strp/pupy_dogs__2_by_little_drunk_jesus_dxnwso-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9NzY4IiwicGF0aCI6IlwvZlwvYTk3Y2M2YmQtM2I3Yi00NGFhLWIwM2QtOTA3MTc1NjllMjliXC9keG53c28tYThhZDAyYmEtZjM3My00NzBmLWJhZWItYmViZmRhNTU0YWFhLmpwZyIsIndpZHRoIjoiPD0xMDI0In1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmltYWdlLm9wZXJhdGlvbnMiXX0.xHFQ2oacJqg1pyqs9Ax4bQw7CtIt0f0Af3zxWWyUi1U'</span>,
        title: <span class="hljs-string">'2 pupies'</span>,
      },
    ];
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.data.set(newData);
    }, <span class="hljs-number">1000</span>);
  }

  reverseData() {
    <span class="hljs-built_in">this</span>.data.update(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> reversedData = data.reverse();
      <span class="hljs-keyword">return</span> reversedData.slice();
    });
  }
}
</code></pre>
<p>And then we will create 2 components to reflect the changes in the UI</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, computed, inject, Signal } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { DataService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/data.service'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-image'</span>,
  standalone: <span class="hljs-literal">true</span>,
  imports: [],
  templateUrl: <span class="hljs-string">'./image.component.html'</span>,
  styleUrl: <span class="hljs-string">'./image.component.sass'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ImageComponent {
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> dataService = inject(DataService);

  <span class="hljs-keyword">readonly</span> imageUrls!: Signal&lt;<span class="hljs-built_in">string</span>[]&gt;;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.imageUrls = computed(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.dataService.dataSignal().map(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> item.imageUrl);
    });
  }
}
</code></pre>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>IMAGE<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  @for (url of imageUrls(); track url) {

  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> [<span class="hljs-attr">src</span>]=<span class="hljs-string">"url"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"200"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  }
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, computed, inject, Signal } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { DataService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../services/data.service'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-list'</span>,
  standalone: <span class="hljs-literal">true</span>,
  imports: [],
  templateUrl: <span class="hljs-string">'./list.component.html'</span>,
  styleUrl: <span class="hljs-string">'./list.component.sass'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ListComponent {
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> dataService = inject(DataService);

  <span class="hljs-keyword">readonly</span> titles!: Signal&lt;<span class="hljs-built_in">string</span>[]&gt;;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.titles = computed(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.dataService.dataSignal().map(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> item.title);
    });
  }
}
</code></pre>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>LIST<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  @for (title of titles(); track title) {

  <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>{{ title }}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  }
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>As you can see using “root” services and Signals together, we can maintain a Signal holding the fetched data and create multiple computed Signals, each serving its own purpose in its respective component.</p>
]]></content:encoded></item><item><title><![CDATA[Angular Elements]]></title><description><![CDATA[The next explanations are based on this project. To get the most of this article it is recommended to not only read it, but to practice creating a similar project.
This is a demo of the application functionality:


Angular elements package, allows tr...]]></description><link>https://blog.jonandonicastelo.org/angular-elements</link><guid isPermaLink="true">https://blog.jonandonicastelo.org/angular-elements</guid><category><![CDATA[Angular]]></category><category><![CDATA[angular-elements]]></category><category><![CDATA[dynamic component]]></category><category><![CDATA[runtime component]]></category><dc:creator><![CDATA[Jon Andoni Castelo Meléndez]]></dc:creator><pubDate>Sat, 07 Oct 2023 15:17:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1696698303704/ff4a0b55-3991-41b4-ae26-c5ae01fc4a63.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The next explanations are based on <a target="_blank" href="https://github.com/fullstackdeveloperbilbao/angular-elements"><strong>this project</strong></a>. To get the most of this article it is recommended to not only read it, but to practice creating a similar project.</p>
<p>This is a demo of the application functionality:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/TO0WKXUjcJQ?si=ZfCTRIm0Hmbewwvf"></iframe>

<p>Angular elements package, allows transforming angular components into custom elements. This transformation automatically maps the components view change detection and data binding with the corresponding HTML built-in equivalents.</p>
<p>Custom elements bootstrap themselves when are added to the DOM and are automatically destroyed when removed from the DOM. <em>On the demo video you can see on logs that dynamic component is initialized and destroyed when tooltip is shown or hidden.</em></p>
<p>The component is transformed into a custom element, then is registered in the <em>CustomElementRegistry</em> and then we can use it when needed.</p>
<p>The mapping between the component and the custom element takes care of:</p>
<ul>
<li><p>Input properties: Defines corresponding attributes in the custom element. Transforms the property names to attributes using dash separated lower case, because custom elements don't recognize case distinctions.</p>
<p>  <code>E.g. @Input('myInputName') inputName =&gt; my-input-name</code></p>
</li>
<li><p>Output properties are dispatched as HTML custom events with the name of the custom event matching the output name.<br />  <code>E.g. @Output('myEventName') myEvent =&gt; myEventName</code></p>
</li>
</ul>
<p>Previously to create a dynamic component you need to take care of <a target="_blank" href="https://angular.io/guide/elements#example-a-popup-service">multiple steps</a> that now are not necessary anymore with angular elements.</p>
<p>Angular advises against using the component selector as the custom element tag name.</p>
<p>To add the package to your project run the command:</p>
<p><code>npm install @angular/elements --save</code></p>
<p>The <em>AppComponent</em> imports <em>ProductComponent</em> and instantiates it in the template:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// app.component.ts</span>
<span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { ProductComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./product/product.component'</span>;
<span class="hljs-keyword">import</span> { CommonModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/common'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-root'</span>,
  templateUrl: <span class="hljs-string">'./app.component.html'</span>,
  standalone: <span class="hljs-literal">true</span>,
  imports: [CommonModule, ProductComponent],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppComponent {}
</code></pre>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- app.component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">app-product</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-product</span>&gt;</span>
</code></pre>
<p><em>ProductComponent</em> shows an image of the product and the real time price. It adds the <em>DynamicPriceComponent</em> to the <em>CustomElementsRegistry</em> and passes an instance of it to the <em>MatTooltipTemplateDirective</em>.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// product.component.ts</span>
<span class="hljs-keyword">import</span> {
  Component,
  EnvironmentInjector,
  OnDestroy,
  OnInit,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { MatTooltipModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/material/tooltip'</span>;
<span class="hljs-keyword">import</span> { matTooltipComponentText } <span class="hljs-keyword">from</span> <span class="hljs-string">'../constants/constants'</span>;
<span class="hljs-keyword">import</span> { FormsModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/forms'</span>;
<span class="hljs-keyword">import</span> { CommonModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/common'</span>;
<span class="hljs-keyword">import</span> {
  NgElement,
  WithProperties,
  createCustomElement,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/elements'</span>;
<span class="hljs-keyword">import</span> { DynamicPriceComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/dynamic-price/dynamic-price.component'</span>;
<span class="hljs-keyword">import</span> { BehaviorSubject, Subject, interval, noop, takeUntil, tap } <span class="hljs-keyword">from</span> <span class="hljs-string">'rxjs'</span>;
<span class="hljs-keyword">import</span> { MatTooltipTemplateDirective } <span class="hljs-keyword">from</span> <span class="hljs-string">'../directives/mat-tooltip-template.directive'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-product'</span>,
  standalone: <span class="hljs-literal">true</span>,
  templateUrl: <span class="hljs-string">'./product.component.html'</span>,
  styleUrls: [<span class="hljs-string">'./product.component.scss'</span>],
  imports: [
    CommonModule,
    FormsModule,
    <span class="hljs-comment">// We input MatTooltipModule </span>
    MatTooltipModule,
    <span class="hljs-comment">// We input MatTooltipTemplateDirective </span>
    MatTooltipTemplateDirective,
  ],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ProductComponent <span class="hljs-keyword">implements</span> OnInit, OnDestroy {
  matTooltipComponentText = matTooltipComponentText;

  <span class="hljs-comment">// We define price as a BehaviorSubject to get a reactive behavior</span>
  <span class="hljs-comment">// and see real time changes on template.</span>
  price = <span class="hljs-keyword">new</span> BehaviorSubject&lt;<span class="hljs-built_in">number</span>&gt;(<span class="hljs-number">20</span>);

  <span class="hljs-keyword">private</span> _destroyed = <span class="hljs-keyword">new</span> Subject&lt;<span class="hljs-built_in">void</span>&gt;();

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> injector: EnvironmentInjector</span>) {
    <span class="hljs-comment">// Here we add the DyanicPriceComponent to the CustomElementRegistry</span>
    <span class="hljs-comment">// using the tag name 'dynamic-price-element'</span>
    <span class="hljs-built_in">this</span>.defineCustomElement();
  }

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-comment">// We update the price every second to see price changes on real time</span>
    interval(<span class="hljs-number">1000</span>)
      .pipe(
        tap(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.makeOffer()),
        takeUntil(<span class="hljs-built_in">this</span>._destroyed)
      )
      .subscribe(noop);
  }

  ngOnDestroy(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>._destroyed.next();
    <span class="hljs-built_in">this</span>._destroyed.complete();
  }

  <span class="hljs-keyword">private</span> defineCustomElement() {
    <span class="hljs-keyword">const</span> dynamicPriceElement = createCustomElement(DynamicPriceComponent, {
      injector: <span class="hljs-built_in">this</span>.injector,
    });
    <span class="hljs-comment">// We check if component has been added previously to the registry</span>
    <span class="hljs-keyword">if</span> (!customElements.get(<span class="hljs-string">'dynamic-price-element'</span>)) {
      customElements.define(<span class="hljs-string">'dynamic-price-element'</span>, dynamicPriceElement);
    }
  }

  createCustomElement() {
    <span class="hljs-keyword">const</span> dynamicPriceEl: NgElement &amp; WithProperties&lt;DynamicPriceComponent&gt; =
      <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'dynamic-price-element'</span>) <span class="hljs-keyword">as</span> <span class="hljs-built_in">any</span>;

    <span class="hljs-comment">// We assign input properties of 'DynamicPriceComponent'</span>
    dynamicPriceEl.dynamicPrice$ = <span class="hljs-built_in">this</span>.price;
    <span class="hljs-keyword">return</span> dynamicPriceEl;
  }

  <span class="hljs-keyword">private</span> makeOffer() {
    <span class="hljs-keyword">const</span> newPrice = <span class="hljs-built_in">this</span>.price.value + <span class="hljs-built_in">this</span>.generateRandomNumber(<span class="hljs-number">-10</span>, <span class="hljs-number">10</span>);
    <span class="hljs-keyword">if</span> (newPrice &lt; <span class="hljs-number">0</span>) {
      <span class="hljs-built_in">this</span>.price.next(<span class="hljs-built_in">this</span>.generateRandomNumber(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>));
    }
    <span class="hljs-built_in">this</span>.price.next(newPrice);
  }

  <span class="hljs-keyword">private</span> generateRandomNumber(min: <span class="hljs-built_in">number</span>, max: <span class="hljs-built_in">number</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * (max - min + <span class="hljs-number">1</span>) + min);
  }
}
</code></pre>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- product.component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product"</span>&gt;</span>
<span class="hljs-comment">&lt;!-- In this div we set the matTooltip value because is required. we will 
remove it in the 'MatToolipTemplateDirective'. We also ad the matToolipTemplate,
and we pass to it the 'templateGenerator' function that returns the instance
of the real time generated component --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
    <span class="hljs-attr">class</span>=<span class="hljs-string">"product-img"</span>
    <span class="hljs-attr">matTooltip</span>=<span class="hljs-string">"{{ matTooltipComponentText }}"</span>
    <span class="hljs-attr">matToolipTemplate</span>
    [<span class="hljs-attr">templateGenerator</span>]=<span class="hljs-string">"createCustomElement.bind(this)"</span>
  &gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-title"</span>&gt;</span>Dog biscuits<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"assets/img/biscuit.jpeg"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"product-price"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Real time price: {{ price.asObservable() | async }} $<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>The <em>MatTooltipTemplateDirective</em> appends the dynamically created component to the tooltip, after removing textContent:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// mat-tooltip-template.directive.ts</span>
<span class="hljs-keyword">import</span> {
  AfterViewInit,
  Directive,
  ElementRef,
  Input,
  OnDestroy,
  OnInit,
  Renderer2,
  ViewChild,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { MatTooltip } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/material/tooltip'</span>;
<span class="hljs-keyword">import</span> { Subject, delay, fromEvent, noop, takeUntil, tap } <span class="hljs-keyword">from</span> <span class="hljs-string">'rxjs'</span>;

<span class="hljs-meta">@Directive</span>({
  selector: <span class="hljs-string">'[matToolipTemplate]'</span>,
  standalone: <span class="hljs-literal">true</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> MatTooltipTemplateDirective <span class="hljs-keyword">implements</span> OnInit, OnDestroy {
  <span class="hljs-meta">@Input</span>() templateGenerator!: <span class="hljs-function">() =&gt;</span> Node;

  <span class="hljs-keyword">private</span> _destroyed = <span class="hljs-keyword">new</span> Subject&lt;<span class="hljs-built_in">void</span>&gt;();

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

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-comment">// We need to be aware of when the tooltip is shown to add the</span>
    <span class="hljs-comment">// dynamically created component to it.</span>
    <span class="hljs-built_in">this</span>.listenToTooltipVisibility();
  }

  ngOnDestroy(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>._destroyed.next();
    <span class="hljs-built_in">this</span>._destroyed.complete();
  }

  <span class="hljs-keyword">private</span> listenToTooltipVisibility() {
    <span class="hljs-comment">// When the mouse enter into the div that has the 'MatTooltipDirective'</span>
    fromEvent(<span class="hljs-built_in">this</span>.el.nativeElement, <span class="hljs-string">'mouseenter'</span>)
      .pipe(
        <span class="hljs-comment">// This delay is required to allow 'MatTooltipDirective' to show the </span>
        <span class="hljs-comment">// tooltip first.</span>
        delay(<span class="hljs-number">0</span>),
        tap(<span class="hljs-function">() =&gt;</span> {
          <span class="hljs-built_in">this</span>.addTemplate();
        }),
        takeUntil(<span class="hljs-built_in">this</span>._destroyed)
      )
      .subscribe(noop);
  }

  <span class="hljs-comment">// We get the dynamically created component, we remove the 'MatTooltipDirective' </span>
  <span class="hljs-comment">// required text. and append the dynamic component as child to the deepest </span>
  <span class="hljs-comment">// div inside the tooltip. </span>
  <span class="hljs-keyword">private</span> addTemplate() {
    <span class="hljs-keyword">const</span> nodes =
      <span class="hljs-built_in">this</span>.matTooltip._tooltipInstance?._tooltip.nativeElement.querySelectorAll(
        <span class="hljs-string">'div'</span>
      );
    <span class="hljs-keyword">const</span> mostDeep = nodes?.item(nodes.length - <span class="hljs-number">1</span>);
    <span class="hljs-keyword">if</span> (!!mostDeep) {
      mostDeep.textContent = <span class="hljs-literal">null</span>;
      <span class="hljs-built_in">this</span>.renderer.setStyle(mostDeep, <span class="hljs-string">'max-width'</span>, <span class="hljs-string">'unset'</span>);
      <span class="hljs-built_in">this</span>.renderer.appendChild(mostDeep, <span class="hljs-built_in">this</span>.templateGenerator());
    }
  }
}
</code></pre>
<p>The <em>DynamicPriceComponent</em> shows the real time price:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// dynamic-price.component.ts</span>
<span class="hljs-keyword">import</span> { CommonModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/common'</span>;
<span class="hljs-keyword">import</span> { Component, Input, OnDestroy, OnInit } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-keyword">import</span> { FormsModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/forms'</span>;
<span class="hljs-keyword">import</span> { Observable, finalize, noop, tap } <span class="hljs-keyword">from</span> <span class="hljs-string">'rxjs'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-product'</span>,
  standalone: <span class="hljs-literal">true</span>,
  templateUrl: <span class="hljs-string">'./dynamic-price.component.html'</span>,
  styleUrls: [<span class="hljs-string">'./dynamic-price.component.scss'</span>],
  imports: [CommonModule],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DynamicPriceComponent <span class="hljs-keyword">implements</span> OnInit, OnDestroy {
  <span class="hljs-meta">@Input</span>() dynamicPrice$!: Observable&lt;<span class="hljs-built_in">number</span>&gt;;

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'DYNAMIC PRICE ONINIT'</span>);
  }

  ngOnDestroy(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'DYNAMIC PRICE ONDESTROY'</span>);
  }
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- dynamic-price.component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dynamic-price"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"assets/img/weim.jpeg"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dynamic-price-img"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dynamic-price-title"</span>&gt;</span>
    Welcome, the real time price is {{ dynamicPrice$ | async }} $. We hope that
    you like it!
  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Bibliography:</p>
<ul>
<li><a target="_blank" href="https://angular.io/guide/elements">https://angular.io/guide/elements</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Add Source Maps locally]]></title><description><![CDATA[The next explanations are based on this project. To get the most of this article it is recommended to not only read it, but to practice creating a similar project.
This is a demo of the application functionality:


Sometimes we will find that our pro...]]></description><link>https://blog.jonandonicastelo.org/add-source-maps-locally</link><guid isPermaLink="true">https://blog.jonandonicastelo.org/add-source-maps-locally</guid><category><![CDATA[Angular]]></category><category><![CDATA[sourcemaps]]></category><dc:creator><![CDATA[Jon Andoni Castelo Meléndez]]></dc:creator><pubDate>Mon, 22 Aug 2022 12:30:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1661171336891/ZYg-0-Yq1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The next explanations are based on <a target="_blank" href="https://github.com/fullstackdeveloperbilbao/source-maps.git">this project</a>. To get the most of this article it is recommended to not only read it, but to practice creating a similar project.</p>
<p>This is a demo of the application functionality:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/E74rK6Q7nRI"></iframe>

<p>Sometimes we will find that our production application doesn't behave as we expect despite doing well in the development environment.</p>
<p>If we try to debug code using a debugger line in code, the production build will delete that line, the same with comments, etc. This is due to the process of minification and uglification. 
Furthermore, if we try to inspect our code inspecting the bundle we will see that the code differs from our original code, and sometimes will be hard to find what we want.
The solution to this problem is the use of source maps. In the end, what source maps do is give us access to the original files and allow us to debug them.</p>
<pre><code><span class="hljs-comment">// This is the source map that belongs to the bundle of the team component</span>
{
  <span class="hljs-attr">"version"</span>: <span class="hljs-number">3</span>,
  <span class="hljs-attr">"file"</span>: <span class="hljs-string">"972.d5590aab453d0da7.js"</span>,
  <span class="hljs-attr">"mappings"</span>: <span class="hljs-string">"wKAIA,MAAMA,EAAiB,CACrB,CACEC,KAAM,GACNC,UCAJ,MAAM,MAAOC,EAGXC,cAAgB,CAEhBC,WACEC,KAAKC,OAAS,CAAC,6BAA8B,6BAC7CD,KAAKE,MAAQF,KAAKC,OAAO,EAC1B,CAEDE,gBACEH,KAAKE,MAAQF,KAAKC,OAAOG,KAAMF,GAAUA,GAASF,KAAKE,MACxD,+CAZUL,EAAa,0BAAbA,EAAaQ,0FCP1BC,cAAIA,SAAWA,QACfA,oBAAQA,gCAASC,iBAAe,GAAED,wBAAYA,eAD1CA,4BDOST,CAAb,MDEE,CACEF,KAAM,KACNa,UAAW,OACXC,WAAY,KAQT,IAAMC,EAAb,MAAM,MAAOA,kDAAiB,0BAAjBA,gCAHDC,cAAsBjB,GACtBiB,QAECD,CAAb,KGJaE,EAAb,MAAM,MAAOA,kDAAU,0BAAVA,gCAJTC,KACAH,KAGSE,CAAb"</span>,
  <span class="hljs-attr">"names"</span>: [
    <span class="hljs-string">"routes"</span>,
    <span class="hljs-string">"path"</span>,
    <span class="hljs-string">"component"</span>,
    <span class="hljs-string">"TeamComponent"</span>,
    <span class="hljs-string">"constructor"</span>,
    <span class="hljs-string">"ngOnInit"</span>,
    <span class="hljs-string">"this"</span>,
    <span class="hljs-string">"titles"</span>,
    <span class="hljs-string">"title"</span>,
    <span class="hljs-string">"onChangeTitle"</span>,
    <span class="hljs-string">"find"</span>,
    <span class="hljs-string">"selectors"</span>,
    <span class="hljs-string">"i0"</span>,
    <span class="hljs-string">"ctx"</span>,
    <span class="hljs-string">"pathMatch"</span>,
    <span class="hljs-string">"redirectTo"</span>,
    <span class="hljs-string">"TeamRoutingModule"</span>,
    <span class="hljs-string">"RouterModule"</span>,
    <span class="hljs-string">"TeamModule"</span>,
    <span class="hljs-string">"CommonModule"</span>
  ],
  <span class="hljs-attr">"sourceRoot"</span>: <span class="hljs-string">"webpack:///"</span>,
  <span class="hljs-attr">"sources"</span>: [
    <span class="hljs-string">"./src/app/team/team-routing.module.ts"</span>,
    <span class="hljs-string">"./src/app/team/team.component.ts"</span>,
    <span class="hljs-string">"./src/app/team/team.component.html"</span>,
    <span class="hljs-string">"./src/app/team/team.module.ts"</span>
  ],
  <span class="hljs-attr">"sourcesContent"</span>: [
    <span class="hljs-string">"import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\nimport { TeamComponent } from './team.component';\n\nconst routes: Routes = [\n  {\n    path: '',\n    component: TeamComponent,\n  },\n  {\n    path: '**',\n    pathMatch: 'full',\n    redirectTo: '',\n  },\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(routes)],\n  exports: [RouterModule],\n})\nexport class TeamRoutingModule {}\n"</span>,
    <span class="hljs-string">"import { Component, OnInit } from '@angular/core';\n\n@Component({\n  selector: 'app-team',\n  templateUrl: './team.component.html',\n  styleUrls: ['./team.component.scss'],\n})\nexport class TeamComponent implements OnInit {\n  title: string | undefined;\n  titles: string[];\n  constructor() {}\n\n  ngOnInit(): void {\n    this.titles = ['Teams Component - Original', 'Teams Component - Changed'];\n    this.title = this.titles[0];\n  }\n\n  onChangeTitle() {\n    this.title = this.titles.find((title) =&gt; title != this.title);\n  }\n}\n"</span>,
    <span class="hljs-string">"&lt;h1&gt;{{ title }}&lt;/h1&gt;\n&lt;button (click)=\"onChangeTitle()\"&gt;Change title&lt;/button&gt;\n"</span>,
    <span class="hljs-string">"import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nimport { TeamRoutingModule } from './team-routing.module';\nimport { TeamComponent } from './team.component';\n\n\n@NgModule({\n  declarations: [\n    TeamComponent\n  ],\n  imports: [\n    CommonModule,\n    TeamRoutingModule\n  ]\n})\nexport class TeamModule { }\n"</span>
  ],
  <span class="hljs-attr">"x_google_ignoreList"</span>: [<span class="hljs-string">"import { NgModule }"</span>]
}
</code></pre><p>A source map is represented by a .map file and it is an object that contains the next properties:</p>
<ul>
<li>version: File version (always the first entry in the object) and must be a positive integer.</li>
<li>file: An optional name of the generated code that this source map is associated with.</li>
<li>mappings: A string with the encoded mapping data</li>
<li>names: A list of symbol names used by the “mappings” entry</li>
<li>sourceRoot: An optional source root, useful for relocating source files on a server or removing repeated values in the “sources” entry.  This value is prepended to the individual entries in the “source” field</li>
<li>sources: A list of original sources used by the “mappings” entry</li>
<li>sourcesContent: An optional list of source content, useful when the “source” can’t be hosted. The contents are listed in the same order as the sources in line 5. “null” may be used if some original sources should be retrieved by name</li>
<li>x_google_ignoreList: An optional list of user-specified ignore list regular expressions, as well as source map hints.</li>
</ul>
<p>To run this example we need to follow the next steps:</p>
<ol>
<li>npm run start:prod</li>
<li>Go to chrome browser, open DevTools, and open the Sources tab</li>
<li>Under localhost:4200 cloud, open the file we want to add the source map to.</li>
<li>Right-click on the code and click on "Add source map..."</li>
<li>Enter the source map URL as "file://myAbsolutePathToMatchingSourcemap"</li>
</ol>
<pre><code><span class="hljs-comment">// package.json</span>
{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"source-maps"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"0.0.0"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"ng"</span>: <span class="hljs-string">"ng"</span>,
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"ng serve"</span>,
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"ng build"</span>,
    <span class="hljs-attr">"build:prod"</span>: <span class="hljs-string">"ng build --configuration=production"</span>,
    <span class="hljs-attr">"delete:sourcemaps:prod"</span>: <span class="hljs-string">"rimraf ./dist/*.map"</span>,
    <span class="hljs-attr">"build:sourcemaps"</span>: <span class="hljs-string">"ng build --configuration=production --output-path=localSourceMaps"</span>,
    <span class="hljs-attr">"serve:prod"</span>: <span class="hljs-string">"http-server ./dist --proxy http://localhost:4200? -a localhost -p 4200"</span>,
    <span class="hljs-attr">"start:prod"</span>: <span class="hljs-string">"run-s build:prod delete:sourcemaps:prod build:sourcemaps serve:prod"</span>,
    <span class="hljs-attr">"watch"</span>: <span class="hljs-string">"ng build --watch --configuration development"</span>,
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"ng test"</span>
  },
  <span class="hljs-attr">"private"</span>: <span class="hljs-literal">true</span>,
</code></pre><p>We see that "npm run start:prod" uses <a target="_blank" href="https://www.npmjs.com/package/npm-run-all">npm-run-all</a> library to run secuentially the production build process, the deletion of generated source maps, a new production build process with a new output path to have the source maps locally and finally exposes the built application on a local server with the <a target="_blank" href="https://www.npmjs.com/package/http-server">http-server</a> library.</p>
<p>Bibliography:</p>
<ul>
<li>https://developer.chrome.com/blog/sourcemaps/</li>
<li>https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.djovrt4kdvga</li>
<li>https://docs.google.com/document/d/1xi12LrcqjqIHTtZzrzZKmQ3lbTv9mKrN076UB-j3UZQ/edit?hl=en_US</li>
<li>https://chromium.googlesource.com/devtools/devtools-frontend/+/41804897510b880826cdf051ffcc1e37845a23e2</li>
<li>https://medium.com/angular-in-depth/debug-angular-apps-in-production-without-revealing-source-maps-ab4a235edd85</li>
<li>https://medium.com/swlh/optimizations-by-angular-54cb80add6d4</li>
<li>https://angular.io/guide/workspace-config</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Route guards]]></title><description><![CDATA[The next explanations are based on this project. To get the most of this article it is recommended to not only read it, but to practice creating a similar project.
This is a demo of the application functionality:


On chrome devtools Console tab, we ...]]></description><link>https://blog.jonandonicastelo.org/route-guards</link><guid isPermaLink="true">https://blog.jonandonicastelo.org/route-guards</guid><category><![CDATA[Angular]]></category><category><![CDATA[resolver]]></category><category><![CDATA[guards]]></category><dc:creator><![CDATA[Jon Andoni Castelo Meléndez]]></dc:creator><pubDate>Mon, 08 Aug 2022 16:06:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1659974715633/ueXg97udR.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The next explanations are based on <a target="_blank" href="https://github.com/fullstackdeveloperbilbao/angular-guards.git">this project</a>. To get the most of this article it is recommended to not only read it, but to practice creating a similar project.</p>
<p>This is a demo of the application functionality:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Gmy7M1dbmc4"></iframe>

<p>On chrome devtools Console tab, we can see when the guards are being called thanks to the logs. </p>
<p>Guards allow or disallow routing. All of them are services that implement an interface as we will see. There are some available route guards in angular:</p>
<ul>
<li><strong>CanActivate</strong>: Allows or disallows reaching a component.</li>
<li><strong>CanActivateChild</strong>: Allows or disallows reaching a child component.</li>
<li><strong>CanDeactivate</strong>: Allows or disallows leaving a component.</li>
<li><strong>CanLoad</strong>: Allows or disallows fetching a module.</li>
<li><strong>Resolve</strong>: Ensures that some data is gathered before route activation. If used with guards, guards will be executed first. If resolves an error we can navigate to an error page.</li>
</ul>
<h3 id="heading-canactivate">CanActivate:</h3>
<p>We create a guard with the CanActivate interface using the command:</p>
<pre><code>ng generate guard profile<span class="hljs-operator">/</span>can<span class="hljs-operator">-</span>activate
</code></pre><p>or</p>
<pre><code>ng g g profile<span class="hljs-operator">/</span>can<span class="hljs-operator">-</span>activate
</code></pre><p>We add a console.log to be aware of when we are using the guard:</p>
<pre><code><span class="hljs-comment">// can-activate.guard.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">Injectable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> {
  <span class="hljs-title">ActivatedRouteSnapshot</span>,
  <span class="hljs-title">CanActivate</span>,
  <span class="hljs-title">RouterStateSnapshot</span>,
  <span class="hljs-title">UrlTree</span>,
} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">Observable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'rxjs'</span>;

@Injectable()
export class CanActivateGuard implements CanActivate {
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    <span class="hljs-operator">|</span> Observable<span class="hljs-operator">&lt;</span>boolean <span class="hljs-operator">|</span> UrlTree<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">|</span> Promise<span class="hljs-operator">&lt;</span>boolean <span class="hljs-operator">|</span> UrlTree<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">|</span> boolean
    <span class="hljs-operator">|</span> UrlTree {
    console.log(<span class="hljs-string">'CanActivate'</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
}
</code></pre><p>As we told earlier the class implements the CanActivate interface which has the canActivate method. We can return a boolean, a Promise, an Observable or a UrlTree.
If the boolean is true we allow the navigation to the requested route, if it is false we disallow it. If we return UrlTree we will be redirected to the specified URL. We can also define the constructor and inject a service. </p>
<p>We then provide (as a service) the guard in the module that imports the RoutingModule that uses the guard, in this case, ProfileModule:</p>
<pre><code><span class="hljs-comment">// profile.module.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CommonModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/common'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProfileComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./profile.component'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProfileRoutingModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./profile-routing.module'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanActivateGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-activate.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanActivateChildGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-activate-child.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">PhotoModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./photo/photo.module'</span>;

@NgModule({
  declarations: [ProfileComponent],
  imports: [CommonModule, PhotoModule, ProfileRoutingModule],
  providers: [CanActivateGuard, CanActivateChildGuard],
})
export class ProfileModule {}
</code></pre><p>And then we use it in the RoutingModule:</p>
<pre><code><span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">RouterModule</span>, <span class="hljs-title">Routes</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanActivateChildGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-activate-child.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanActivateGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-activate.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">PhotoComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./photo/photo.component'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProfileComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./profile.component'</span>;

const routes: Routes <span class="hljs-operator">=</span> [
  {
    path: <span class="hljs-string">''</span>,
    component: ProfileComponent,
    canActivate: [CanActivateGuard],
    canActivateChild: [CanActivateChildGuard],
    children: [{ path: <span class="hljs-string">'photo'</span>, component: PhotoComponent }],
  },
  {
    path: <span class="hljs-string">'**'</span>,
    redirectTo: <span class="hljs-string">''</span>,
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class ProfileRoutingModule {}
</code></pre><p>Here we are using also CanActivateChild guard but we will discuss it later.</p>
<p>The result is the first shown in the demo video. If we change the return boolean of the guard to false the result is this:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/xPNRsrWn7sM"></iframe>

<p>As we see on the log each time we click on Profile menu option we are using the CanActivate guard but the view is not rendered. This is the result we expected.</p>
<p>A possible real use case for this guard is disallowing the access to a part of the navigation based on a role (e.g. if the user is not an admin is not allowed to navigate to the "files" URL. In this practical example we simply set a true allowing always the navigation but you can clone the code and make changes to see how it works.</p>
<h3 id="heading-canactivatechild">CanActivateChild:</h3>
<p>We create a guard with the CanActivateChild interface using the command:</p>
<pre><code>ng generate guard profile<span class="hljs-operator">/</span>can<span class="hljs-operator">-</span>activate<span class="hljs-operator">-</span>child
</code></pre><p>or</p>
<pre><code>ng g g profile<span class="hljs-operator">/</span>can<span class="hljs-operator">-</span>activate<span class="hljs-operator">-</span>child
</code></pre><p>We add a console.log to be aware of when we are using the guard:</p>
<pre><code><span class="hljs-comment">// can-activate-child.guard.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">Injectable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> {
  <span class="hljs-title">ActivatedRouteSnapshot</span>,
  <span class="hljs-title">CanActivate</span>,
  <span class="hljs-title">CanActivateChild</span>,
  <span class="hljs-title">RouterStateSnapshot</span>,
  <span class="hljs-title">UrlTree</span>,
} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">Observable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'rxjs'</span>;

@Injectable()
export class CanActivateChildGuard implements CanActivateChild {
  canActivateChild(
    childRoute: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    <span class="hljs-operator">|</span> boolean
    <span class="hljs-operator">|</span> UrlTree
    <span class="hljs-operator">|</span> Observable<span class="hljs-operator">&lt;</span>boolean <span class="hljs-operator">|</span> UrlTree<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">|</span> Promise<span class="hljs-operator">&lt;</span>boolean <span class="hljs-operator">|</span> UrlTree<span class="hljs-operator">&gt;</span> {
    console.log(<span class="hljs-string">'CanActivateChild'</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
}
</code></pre><p>As in the previous guard, the class implements an interface, in this case the CanActivateChild interface which has the canActivateChild method. We can return a boolean, a Promise, an Observable or a UrlTree.
Again if the boolean is true we allow the navigation to the requested route, if it is false we disallow it. If we return UrlTree we will be redirected to the specified URL. We can also define the constructor and inject a service. </p>
<p>We then provide (as a service) the guard in the module that imports the RoutingModule that uses the guard, in this case, ProfileModule:</p>
<pre><code><span class="hljs-comment">// profile.module.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CommonModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/common'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProfileComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./profile.component'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProfileRoutingModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./profile-routing.module'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanActivateGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-activate.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanActivateChildGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-activate-child.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">PhotoModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./photo/photo.module'</span>;

@NgModule({
  declarations: [ProfileComponent],
  imports: [CommonModule, PhotoModule, ProfileRoutingModule],
  providers: [CanActivateGuard, CanActivateChildGuard],
})
export class ProfileModule {}
</code></pre><p>And then we use it in the RoutingModule:</p>
<pre><code><span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">RouterModule</span>, <span class="hljs-title">Routes</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanActivateChildGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-activate-child.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanActivateGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-activate.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">PhotoComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./photo/photo.component'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProfileComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./profile.component'</span>;

const routes: Routes <span class="hljs-operator">=</span> [
  {
    path: <span class="hljs-string">''</span>,
    component: ProfileComponent,
    canActivate: [CanActivateGuard],
    canActivateChild: [CanActivateChildGuard],
    children: [{ path: <span class="hljs-string">'photo'</span>, component: PhotoComponent }],
  },
  {
    path: <span class="hljs-string">'**'</span>,
    redirectTo: <span class="hljs-string">''</span>,
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class ProfileRoutingModule {}
</code></pre><p>The result again is the first shown in the demo video. If we change the return boolean of the guard to false the result is this:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/L3p76Q5LjGk"></iframe>

<p>As we see on the log each time we click on Show photo button we are using the CanActivateChild guard but the view is not rendered. This is the result we expected.</p>
<p>Again, a possible real use case for this guard is disallowing access to a part of the navigation based on a role (e.g. if the user is not an admin is not allowed to navigate to the users creation URL. In this practical example, we simply set a true allowing always the navigation but you can clone the code and make changes to see how it works.</p>
<h3 id="heading-candeactivate">CanDeactivate:</h3>
<p>We create a guard with the CanDeactivate interface using the command:</p>
<pre><code>ng generate guard faq<span class="hljs-operator">/</span>can<span class="hljs-operator">-</span>deactivate
</code></pre><p>or</p>
<pre><code>ng g g faq<span class="hljs-operator">/</span>can<span class="hljs-operator">-</span>deactivate
</code></pre><p>We add a console.log to be aware of when we are using the guard:</p>
<pre><code><span class="hljs-comment">// can-deactivate.guard.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">Injectable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> {
  <span class="hljs-title">ActivatedRouteSnapshot</span>,
  <span class="hljs-title">CanDeactivate</span>,
  <span class="hljs-title">RouterStateSnapshot</span>,
  <span class="hljs-title">UrlTree</span>,
} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">Observable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'rxjs'</span>;

@Injectable()
export class CanDeactivateGuard implements CanDeactivate<span class="hljs-operator">&lt;</span>any<span class="hljs-operator">&gt;</span> {
  canDeactivate(
    component: any,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState: RouterStateSnapshot
  ):
    <span class="hljs-operator">|</span> Observable<span class="hljs-operator">&lt;</span>boolean <span class="hljs-operator">|</span> UrlTree<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">|</span> Promise<span class="hljs-operator">&lt;</span>boolean <span class="hljs-operator">|</span> UrlTree<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">|</span> boolean
    <span class="hljs-operator">|</span> UrlTree {
    console.log(<span class="hljs-string">'CanDeactivate'</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
}
</code></pre><p>As in the previous guard, the class implements an interface, in this case the CanDeactivate interface which has the canDeactivate method. We can return a boolean, a Promise, an Observable or a UrlTree.
Again if the boolean is true we allow the navigation to the requested route, if it is false we disallow it. If we return UrlTree we will be redirected to the specified URL. We can also define the constructor and inject a service. </p>
<p>We then provide (as a service) the guard in the module that imports the RoutingModule that uses the guard, in this case, FaqModule:</p>
<pre><code><span class="hljs-comment">// faq.module.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CommonModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/common'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">FaqComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./faq.component'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">FaqRoutingModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./faq-routing.module'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanDeactivateGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-deactivate.guard'</span>;



@NgModule({
  declarations: [FaqComponent],
  imports: [
    CommonModule,
    FaqRoutingModule
  ],
  providers: [CanDeactivateGuard]
})
export class FaqModule { }
</code></pre><p>And then we use it in the RoutingModule:</p>
<pre><code><span class="hljs-comment">// faq-routing.module.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">RouterModule</span>, <span class="hljs-title">Routes</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanDeactivateGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-deactivate.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">FaqComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./faq.component'</span>;

const routes: Routes <span class="hljs-operator">=</span> [
  {
    path: <span class="hljs-string">''</span>,
    component: FaqComponent,
    canDeactivate: [CanDeactivateGuard],
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class FaqRoutingModule {}
</code></pre><p>The result again is the first shown in the demo video. If we change the return boolean of the guard to false the result is this:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/38VFyAFo4RY"></iframe>

<p>As we see once we visit the faq view, we cannot visit any other view and each time we click on any other menu option we are using the CanDeactivate guard as we see on the logs. This is the result we expected.</p>
<p>Again, a possible real use case for this guard is making a question to an user about if is secure of navigating to other page because there is some data in the current view that has not been persisted. If the users clicks yes we return true and the navigation happens and if clicks no the navigation will not happen. In this practical example, we simply set a true allowing always the navigation but you can clone the code and make changes to see how it works.</p>
<h3 id="heading-canload">CanLoad:</h3>
<p>We create a guard with the CanLoad interface using the command:</p>
<pre><code>ng generate guard catalog<span class="hljs-operator">/</span>can<span class="hljs-operator">-</span>load
</code></pre><p>or</p>
<pre><code>ng g g catalog<span class="hljs-operator">/</span>can<span class="hljs-operator">-</span>load
</code></pre><p>We add a console.log to be aware of when we are using the guard:</p>
<pre><code><span class="hljs-comment">// can-load.guard.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">Injectable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> {
  <span class="hljs-title">ActivatedRouteSnapshot</span>,
  <span class="hljs-title">CanActivate</span>,
  <span class="hljs-title">CanLoad</span>,
  <span class="hljs-title">Route</span>,
  <span class="hljs-title">RouterStateSnapshot</span>,
  <span class="hljs-title">UrlSegment</span>,
  <span class="hljs-title">UrlTree</span>,
} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">Observable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'rxjs'</span>;

@Injectable()
export class CanLoadGuard implements CanLoad {
  canLoad(
    route: Route,
    segments: UrlSegment[]
  ):
    <span class="hljs-operator">|</span> Observable<span class="hljs-operator">&lt;</span>boolean <span class="hljs-operator">|</span> UrlTree<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">|</span> Promise<span class="hljs-operator">&lt;</span>boolean <span class="hljs-operator">|</span> UrlTree<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">|</span> boolean
    <span class="hljs-operator">|</span> UrlTree {
    console.log(<span class="hljs-string">'CanLoad'</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
}
</code></pre><p>As in the previous guard, the class implements an interface, in this case the CanLoad interface which has the canLoad method. We can return a boolean, a Promise, an Observable or a UrlTree.
In this case if the boolean is true we allow requesting the module of the requested route, if it is false we disallow it. If we return UrlTree we will be redirected to the specified URL. We can also define the constructor and inject a service. </p>
<p>We then provide (as a service) the guard in the module that imports the RoutingModule that uses the guard, in this case, CatalogModule:</p>
<pre><code><span class="hljs-comment">// catalog.module.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CommonModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/common'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CatalogComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./catalog.component'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CatalogRoutingModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./catalog-routing.module'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanLoadGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-load.guard'</span>;

@NgModule({
  declarations: [CatalogComponent],
  imports: [CommonModule, CatalogRoutingModule],
  providers: [CanLoadGuard],
})
export class CatalogModule {}
</code></pre><p>And then we use it in the RoutingModule:</p>
<pre><code><span class="hljs-comment">// catalog-routing.module.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">RouterModule</span>, <span class="hljs-title">Routes</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CanLoadGuard</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./can-load.guard'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CatalogComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./catalog.component'</span>;

const routes: Routes <span class="hljs-operator">=</span> [
  {
    path: <span class="hljs-string">''</span>,
    component: CatalogComponent,
  },
  {
    path: <span class="hljs-string">'product'</span>,
    loadChildren: () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span>
      <span class="hljs-keyword">import</span>(<span class="hljs-string">'./product/product.module'</span>).<span class="hljs-title">then</span>(
        (<span class="hljs-title">m</span>) <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> <span class="hljs-title">m</span>.<span class="hljs-title">ProductModule</span>
      ),
    <span class="hljs-title">canLoad</span>: [<span class="hljs-title">CanLoadGuard</span>],
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class CatalogRoutingModule {}
</code></pre><p>The result again is the first shown in the demo video. We will see two different videos, in one of them we will see how the module is requested and arrives and in the second one how this will not happen. To make the example more visible on chrome devtools I will select the network tab and in the NO throttling select I will select Slow 3G (You can see how I do this on the video):</p>
<p>Allowing the request and getting the response:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/KfXw8aLIz50"></iframe>

<p>You can see as when I click the button info to navigate to the catalog/product URL the module is requested, the spinner starts showing and when the module arrives, the spinner hides and the view is rendered.</p>
<p>If we don't allow the request this is the result:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/ihHbZL1ICPw"></iframe>

<p>No request is being done because we are returning false on the CanLoad guard.</p>
<p>Again, a possible real use case for this guard is disallowing modules requests depending on the user role, this way the bundle size is minimal and the application will start sooner. In this practical example, we simply set a true allowing always the request but you can clone the code and make changes to see how it works.</p>
<h3 id="heading-resolve">Resolve:</h3>
<p>We create a resolver with the Resolve interface using the command:</p>
<pre><code><span class="hljs-attribute">ng</span> generate resolver catalog/product
</code></pre><p>or</p>
<pre><code><span class="hljs-attribute">ng</span> g r catalog/product
</code></pre><p>We add a console.log to be aware of when we are using the resolver. We also create a dummy method that returns a product depending on the id we pass in the URL and some dummy data (in a real case this could be a request to an backend API to get a product based on the id):</p>
<pre><code><span class="hljs-comment">// product.resolver.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">Injectable</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> {
  <span class="hljs-title">Resolve</span>,
  <span class="hljs-title">RouterStateSnapshot</span>,
  <span class="hljs-title">ActivatedRouteSnapshot</span>,
} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">Observable</span>, <span class="hljs-title">of</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'rxjs'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">Product</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./product.model'</span>;

@Injectable()
export class ProductResolver implements Resolve<span class="hljs-operator">&lt;</span>Product<span class="hljs-operator">&gt;</span> {
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<span class="hljs-operator">&lt;</span>Product<span class="hljs-operator">&gt;</span> {
    console.log(<span class="hljs-string">'Resolver'</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.createProduct(route.paramMap.get(<span class="hljs-string">'id'</span>));
  }

  createProduct(id: any) {
    const description <span class="hljs-operator">=</span>
      <span class="hljs-string">'Lorem Ipsum is simply dummy text of the printing and typesetting industry.'</span>;
    const product <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Product(id, description, <span class="hljs-string">'assets/images/cloud.png'</span>);
    <span class="hljs-keyword">return</span> of(product);
  }
}
</code></pre><p>As in the previous guards, the class implements an interface, in this case the Resolve interface which has the resolve method. We can return an Observable (Instead of product we can return the model we choose). We can also define the constructor and inject a service. </p>
<p>We then provide (as a service) the resolver in the module that imports the RoutingModule that uses the resolver, in this case, ProductModule:</p>
<pre><code><span class="hljs-comment">// product.module.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">CommonModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/common'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProductRoutingModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./product-routing.module'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProductComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./product.component'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProductResolver</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./product.resolver'</span>;

@NgModule({
  declarations: [ProductComponent],
  imports: [CommonModule, ProductRoutingModule],
  providers: [ProductResolver],
})
export class ProductModule {}
</code></pre><p>And then we use it in the RoutingModule:</p>
<pre><code><span class="hljs-comment">// product-routing.module.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">NgModule</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">RouterModule</span>, <span class="hljs-title">Routes</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProductComponent</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./product.component'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ProductResolver</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./product.resolver'</span>;

const routes: Routes <span class="hljs-operator">=</span> [
  {
    path: <span class="hljs-string">':id'</span>,
    component: ProductComponent,
    resolve: { product: ProductResolver },
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class ProductRoutingModule {}
</code></pre><p>To get the returning data from the resolver on the component we are navigating to we do it instantiating the ActivatedRoute class in the constructor of the component:</p>
<pre><code><span class="hljs-keyword">import</span> { <span class="hljs-title">Component</span>, <span class="hljs-title">OnInit</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">ActivatedRoute</span>, <span class="hljs-title">Router</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/router'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">BehaviorSubject</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'rxjs'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">Product</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./product.model'</span>;

@Component({
  selector: <span class="hljs-string">'app-product'</span>,
  templateUrl: <span class="hljs-string">'./product.component.html'</span>,
  styleUrls: [<span class="hljs-string">'./product.component.scss'</span>],
})
export class ProductComponent implements OnInit {
  actualProduct: Product;
  <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> activatedRoute: ActivatedRoute</span>) </span>{
    <span class="hljs-built_in">this</span>.actualProduct <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Product(<span class="hljs-string">''</span>, <span class="hljs-string">''</span>, <span class="hljs-string">''</span>);
  }

  ngOnInit(): void {
    <span class="hljs-built_in">this</span>.activatedRoute.data.subscribe((data) <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
      <span class="hljs-built_in">this</span>.actualProduct <span class="hljs-operator">=</span> data[<span class="hljs-string">"product"</span>];
    });
  }
}
</code></pre><p>If we get an error for example if we are requesting an endpoint that is not available to get some data, we can handle the error and return  EMPTY observable and we can navigate to an error page for example using the router:</p>
<pre><code><span class="hljs-keyword">this</span>.router.navigate([<span class="hljs-string">"/error"</span>]);
<span class="hljs-keyword">return</span> EMPTY;
</code></pre><p>Again, a possible real use case for the resolver is when we want to guarantee to access a view with displaying data previously preloaded.</p>
<p>Bibliography:</p>
<ul>
<li>https://angular.io/guide/router#preventing-unauthorized-access </li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Reactive forms & Template-driven forms]]></title><description><![CDATA[The next explanations are based on this project
Angular handles forms in two ways:

Reactive forms: Allow us to manipulate the form object on ts files.
Template-driven forms:  There is no explicit form object, instead there is an implicit one manipul...]]></description><link>https://blog.jonandonicastelo.org/reactive-forms-template-driven-forms</link><guid isPermaLink="true">https://blog.jonandonicastelo.org/reactive-forms-template-driven-forms</guid><category><![CDATA[Angular]]></category><category><![CDATA[reactive forms]]></category><category><![CDATA[template-driven-forms]]></category><dc:creator><![CDATA[Jon Andoni Castelo Meléndez]]></dc:creator><pubDate>Mon, 25 Jul 2022 16:32:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1658766602194/JigvBQSUw.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The next explanations are based on <a target="_blank" href="https://github.com/fullstackdeveloperbilbao/angular-forms.git">this project</a></p>
<p>Angular handles forms in two ways:</p>
<ol>
<li>Reactive forms: Allow us to manipulate the form object on ts files.</li>
<li>Template-driven forms:  There is no explicit form object, instead there is an implicit one manipulable with directives.</li>
</ol>
<p>We will add some bootstrap classes that we will use to show alert styles in validation message boxes. So in the index.html we add the bootstrap cdn and it will be applied to the entire app:</p>
<pre><code><span class="hljs-comment">// index.html</span>
<span class="hljs-operator">&lt;</span><span class="hljs-operator">!</span>doctype html<span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span>html lang<span class="hljs-operator">=</span><span class="hljs-string">"en"</span><span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span>head<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>meta charset<span class="hljs-operator">=</span><span class="hljs-string">"utf-8"</span><span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>title<span class="hljs-operator">&gt;</span>AngularForms<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>title<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>base href<span class="hljs-operator">=</span><span class="hljs-string">"/"</span><span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>meta name<span class="hljs-operator">=</span><span class="hljs-string">"viewport"</span> content<span class="hljs-operator">=</span><span class="hljs-string">"width=device-width, initial-scale=1"</span><span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>link rel<span class="hljs-operator">=</span><span class="hljs-string">"icon"</span> <span class="hljs-keyword">type</span><span class="hljs-operator">=</span><span class="hljs-string">"image/x-icon"</span> href<span class="hljs-operator">=</span><span class="hljs-string">"favicon.ico"</span><span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>link rel<span class="hljs-operator">=</span><span class="hljs-string">"stylesheet"</span> href<span class="hljs-operator">=</span><span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"</span> integrity<span class="hljs-operator">=</span><span class="hljs-string">"sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"</span> crossorigin<span class="hljs-operator">=</span><span class="hljs-string">"anonymous"</span><span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>head<span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span>body<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>app<span class="hljs-operator">-</span>root<span class="hljs-operator">&gt;</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>app<span class="hljs-operator">-</span>root<span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>body<span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>html<span class="hljs-operator">&gt;</span>
</code></pre><p>Angular applies some classes to form elements that describe their state: ng-touched (or ng-untouched if the control hasn't been visited), ng-dirty(or ng-pristine if the control's value hasn't changed), ng-valid ( or ng-invalid if the control's value isn't valid) and ng-submitted if the form has been submitted.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658758147697/0zlvUHU-9.png" alt="Captura de pantalla de 2022-07-25 16-08-49.png" /></p>
<p>To add some styles to these angular-specific classes we will do it in the styles.scss file that applies styles to the entire app:</p>
<pre><code><span class="hljs-comment">// styles.scss</span>
<span class="hljs-comment">/* You can add global styles to this file, and also import other style files */</span>
.form-control {
  border<span class="hljs-operator">-</span>width: 2px;
  <span class="hljs-operator">&amp;</span>.ng-touched {
    border<span class="hljs-operator">-</span>color: rgba(<span class="hljs-number">30</span>, <span class="hljs-number">110</span>, <span class="hljs-number">214</span>, <span class="hljs-number">1</span>);
  }
  <span class="hljs-operator">&amp;</span>.ng-dirty {
    border<span class="hljs-operator">-</span>color: rgba(<span class="hljs-number">162</span>, <span class="hljs-number">143</span>, <span class="hljs-number">56</span>, <span class="hljs-number">1</span>);
  }
  <span class="hljs-operator">&amp;</span>.ng-invalid {
    border<span class="hljs-operator">-</span>color: rgba(<span class="hljs-number">214</span>, <span class="hljs-number">30</span>, <span class="hljs-number">30</span>, <span class="hljs-number">1</span>);
  }
}
</code></pre><p><strong>Reactive forms:</strong>
The first thing we will do is to add ReactiveFormsModule on the module that will declare the component that uses the form to use reactive form controls:</p>
<pre><code><span class="hljs-regexp">//</span> users-reactive.<span class="hljs-built_in">module</span>.ts
<span class="hljs-keyword">import</span> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { ReactiveFormsModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/forms'</span>;
<span class="hljs-keyword">import</span> { UsersReactiveComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./users-reactive.component'</span>;
<span class="hljs-keyword">import</span> { SharedModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'../shared/shared.module'</span>;



@NgModule({
  declarations: [UsersReactiveComponent],
  imports: [
    ReactiveFormsModule,
    SharedModule
  ]
})
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UsersReactiveModule</span> { }</span>
</code></pre><p>Second, we create a FormGroup in the ts file to associate with the form in the html file:</p>
<pre><code><span class="hljs-comment">// users-reactive.component.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">Component</span>, <span class="hljs-title">OnInit</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">FormControl</span>, <span class="hljs-title">FormGroup</span>, <span class="hljs-title">Validators</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/forms'</span>;

@Component({
  selector: <span class="hljs-string">'app-users-reactive'</span>,
  templateUrl: <span class="hljs-string">'./users-reactive.component.html'</span>,
  styleUrls: [<span class="hljs-string">'./users-reactive.component.scss'</span>],
})
export class UsersReactiveComponent implements OnInit {
  userForm: FormGroup;
  videogames: <span class="hljs-keyword">string</span>[];
  <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">this</span>.userForm <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> FormGroup({
      name: <span class="hljs-keyword">new</span> FormControl(<span class="hljs-string">'Juanjo'</span>, Validators.required),
      father: <span class="hljs-keyword">new</span> FormControl(<span class="hljs-string">'Manolo'</span>),
      videogames: <span class="hljs-keyword">new</span> FormControl(
        [<span class="hljs-string">'Metroid Prime'</span>, <span class="hljs-string">'Animal Crossing'</span>],
        Validators.required
      ),
    });
    <span class="hljs-built_in">this</span>.videogames <span class="hljs-operator">=</span> [
      <span class="hljs-string">'Metroid Prime'</span>,
      <span class="hljs-string">'Super Mario'</span>,
      <span class="hljs-string">'Animal Crossing'</span>,
      <span class="hljs-string">'Assasins Creed'</span>,
    ];
  }

  ngOnInit(): void {}

  onSubmit() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.userForm.valid) {
      console.log(<span class="hljs-built_in">this</span>.userForm.<span class="hljs-built_in">value</span>);
    }
  }

  onClear() {
    <span class="hljs-built_in">this</span>.userForm.reset();
  }

  findControl(controlName: <span class="hljs-keyword">string</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.userForm.get(controlName) <span class="hljs-keyword">as</span> FormControl;
  }
}
</code></pre><ul>
<li>The videogames variable contains the videogames displayed as options on a select element. </li>
<li>On the FormGroup variable (userForm) we have defined some FormControls and on each one, we defined a default value and in two of them a required validator. </li>
<li>The onSubmit  function simply displays the form value if the form is valid (validation requirements are met).</li>
<li>The onClear funtions resets the form. </li>
<li>We also define a findControl method that takes a  controlName and gives us the control itself. This allows us to access control statuses on the html to make conditions.</li>
</ul>
<p>The html is as follows:</p>
<pre><code><span class="hljs-comment">// users-reactive.component.html</span>
<span class="hljs-operator">&lt;</span>h1<span class="hljs-operator">&gt;</span>Reactive form<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>h1<span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span>form [formGroup]<span class="hljs-operator">=</span><span class="hljs-string">"userForm"</span> (ngSubmit)<span class="hljs-operator">=</span><span class="hljs-string">"onSubmit()"</span><span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>div class<span class="hljs-operator">=</span><span class="hljs-string">"form-group"</span><span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>label <span class="hljs-keyword">for</span><span class="hljs-operator">=</span><span class="hljs-string">"name"</span><span class="hljs-operator">&gt;</span>User name<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>label<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>input class<span class="hljs-operator">=</span><span class="hljs-string">"form-control"</span> <span class="hljs-keyword">type</span><span class="hljs-operator">=</span><span class="hljs-string">"text"</span> id<span class="hljs-operator">=</span><span class="hljs-string">"name"</span> formControlName<span class="hljs-operator">=</span><span class="hljs-string">"name"</span> <span class="hljs-operator">/</span><span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>app<span class="hljs-operator">-</span>validation<span class="hljs-operator">-</span>message
      [message]<span class="hljs-operator">=</span><span class="hljs-string">"'User name is required'"</span>
      [hidden]<span class="hljs-operator">=</span><span class="hljs-string">"findControl('name').valid"</span>
    <span class="hljs-operator">&gt;</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>app<span class="hljs-operator">-</span>validation<span class="hljs-operator">-</span>message<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>div<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>div class<span class="hljs-operator">=</span><span class="hljs-string">"form-group"</span><span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>label <span class="hljs-keyword">for</span><span class="hljs-operator">=</span><span class="hljs-string">"father"</span><span class="hljs-operator">&gt;</span>User Father<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>label<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>input
      class<span class="hljs-operator">=</span><span class="hljs-string">"form-control"</span>
      <span class="hljs-keyword">type</span><span class="hljs-operator">=</span><span class="hljs-string">"text"</span>
      id<span class="hljs-operator">=</span><span class="hljs-string">"father"</span>
      formControlName<span class="hljs-operator">=</span><span class="hljs-string">"father"</span>
    <span class="hljs-operator">/</span><span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>div<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>div class<span class="hljs-operator">=</span><span class="hljs-string">"form-group"</span><span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>label <span class="hljs-keyword">for</span><span class="hljs-operator">=</span><span class="hljs-string">"toys"</span><span class="hljs-operator">&gt;</span>Videogames<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>label<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>select
      class<span class="hljs-operator">=</span><span class="hljs-string">"form-control"</span>
      id<span class="hljs-operator">=</span><span class="hljs-string">"videogames"</span>
      formControlName<span class="hljs-operator">=</span><span class="hljs-string">"videogames"</span>
      multiple
    <span class="hljs-operator">&gt;</span>
      <span class="hljs-operator">&lt;</span>option <span class="hljs-operator">*</span>ngFor<span class="hljs-operator">=</span><span class="hljs-string">"let videogame of videogames"</span> [value]<span class="hljs-operator">=</span><span class="hljs-string">"videogame"</span><span class="hljs-operator">&gt;</span>
        {{ videogame }}
      <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>option<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>select<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>app<span class="hljs-operator">-</span>validation<span class="hljs-operator">-</span>message
      [message]<span class="hljs-operator">=</span><span class="hljs-string">"'Videogame is required'"</span>
      [hidden]<span class="hljs-operator">=</span><span class="hljs-string">"findControl('videogames').valid"</span>
    <span class="hljs-operator">&gt;</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>app<span class="hljs-operator">-</span>validation<span class="hljs-operator">-</span>message<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>div<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span>div class<span class="hljs-operator">=</span><span class="hljs-string">"form-group row mt-3"</span><span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>div class<span class="hljs-operator">=</span><span class="hljs-string">"col-sm-1"</span><span class="hljs-operator">&gt;</span>
      <span class="hljs-operator">&lt;</span>button <span class="hljs-keyword">type</span><span class="hljs-operator">=</span><span class="hljs-string">"button"</span> class<span class="hljs-operator">=</span><span class="hljs-string">"btn btn-primary"</span> (click)<span class="hljs-operator">=</span><span class="hljs-string">"onClear()"</span><span class="hljs-operator">&gt;</span>
        Clear
      <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>button<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>div<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>div class<span class="hljs-operator">=</span><span class="hljs-string">"col-sm-1"</span><span class="hljs-operator">&gt;</span>
      <span class="hljs-operator">&lt;</span>button <span class="hljs-keyword">type</span><span class="hljs-operator">=</span><span class="hljs-string">"submit"</span> class<span class="hljs-operator">=</span><span class="hljs-string">"btn btn-primary"</span><span class="hljs-operator">&gt;</span>Submit<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>button<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>div<span class="hljs-operator">&gt;</span>
  <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>div<span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>form<span class="hljs-operator">&gt;</span>
</code></pre><ul>
<li>We assing the FormGroup variable (userForm) to the [formGroup] one-way data binding available from ReactiveFormsModule. With this, we tell input elements the control name they have to use to asssign themselves the apropiated control. </li>
<li>The formControlName directive value must coincide with the FormGroup name defined in the FormGroup object in the ts file (name, father, and videogames).</li>
<li>We also see that app-validation-message component is shown if the control is invalid.</li>
<li>Clear button calls the onClear functions that resets the form as we see earlier.</li>
<li>Submit button triggers ngSubmit event and this calls the obSubmit functions which logs the form value.</li>
</ul>
<p>This is the form shown by default:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658765598047/1-W08qJSU.png" alt="Captura de pantalla de 2022-07-25 18-12-55.png" /></p>
<p>This is the form if some of the fields are touched (blue color on borders):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658765643285/ffE-YzjfM.png" alt="Captura de pantalla de 2022-07-25 18-13-41.png" /></p>
<p>This is the form if some of the fields are modified:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658765686484/Hf-dSFSI9.png" alt="Captura de pantalla de 2022-07-25 18-14-31.png" /></p>
<p>This is the form if some of the required fields are empty:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658765798649/mjB8KbMA_.png" alt="Captura de pantalla de 2022-07-25 18-16-17.png" /></p>
<p>And this is the result of submitting the form on console:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658765850167/pgCii6u8O.png" alt="Captura de pantalla de 2022-07-25 18-17-07.png" /></p>
<p><strong>Template-driven forms:</strong></p>
<p>These forms rely on directives defined in the FormsModule: NgModel, NgForm and NgModelGroup. The first thing we will do is import FormsModule on the module that will declare the component that uses the form, this way we will be able to use mentioned directives:</p>
<pre><code><span class="hljs-regexp">//</span> pets-template-driven.<span class="hljs-built_in">module</span>.ts
<span class="hljs-keyword">import</span> { NgModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { FormsModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/forms'</span>;
<span class="hljs-keyword">import</span> { PetsTemplateDrivenComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./pets-template-driven.component'</span>;
<span class="hljs-keyword">import</span> { SharedModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'../shared/shared.module'</span>;



@NgModule({
  declarations: [PetsTemplateDrivenComponent],
  imports: [
    FormsModule,
    SharedModule
  ]
})
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PetsTemplateDrivenModule</span> { }</span>
</code></pre><p>With all the needed styles in place we create the template-driven form html file:</p>
<pre><code>// pets-template-driven.component.html
<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Template-driven form<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">form</span> #<span class="hljs-attr">petForm</span>=<span class="hljs-string">"ngForm"</span> (<span class="hljs-attr">ngSubmit</span>)=<span class="hljs-string">"onSubmit(petForm.form)"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Pet name<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
      <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span>
      <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
      <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span>
      <span class="hljs-attr">name</span>=<span class="hljs-string">"passedName"</span>
      [(<span class="hljs-attr">ngModel</span>)]=<span class="hljs-string">"actualPet.name"</span>
      #<span class="hljs-attr">nameModel</span>=<span class="hljs-string">"ngModel"</span>
      <span class="hljs-attr">required</span>
    /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">app-validation-message</span>
      [<span class="hljs-attr">message</span>]=<span class="hljs-string">"'Pet name is required'"</span>
      [<span class="hljs-attr">hidden</span>]=<span class="hljs-string">"nameModel.valid"</span>
    &gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-validation-message</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"owner"</span>&gt;</span>Pet owner<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
      <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span>
      <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
      <span class="hljs-attr">id</span>=<span class="hljs-string">"owner"</span>
      <span class="hljs-attr">name</span>=<span class="hljs-string">"owner"</span>
      [(<span class="hljs-attr">ngModel</span>)]=<span class="hljs-string">"actualPet.owner"</span>
    /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"toys"</span>&gt;</span>Pet toys<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">select</span>
      <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span>
      <span class="hljs-attr">id</span>=<span class="hljs-string">"toys"</span>
      <span class="hljs-attr">name</span>=<span class="hljs-string">"toys"</span>
      [(<span class="hljs-attr">ngModel</span>)]=<span class="hljs-string">"actualPet.toys"</span>
      #<span class="hljs-attr">toysModel</span>=<span class="hljs-string">"ngModel"</span>
      <span class="hljs-attr">multiple</span>
      <span class="hljs-attr">required</span>
    &gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">option</span> *<span class="hljs-attr">ngFor</span>=<span class="hljs-string">"let toy of toys"</span> [<span class="hljs-attr">value</span>]=<span class="hljs-string">"toy"</span>&gt;</span>{{ toy }}<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">app-validation-message</span>
      [<span class="hljs-attr">message</span>]=<span class="hljs-string">"'Pet toy is required'"</span>
      [<span class="hljs-attr">hidden</span>]=<span class="hljs-string">"toysModel.valid"</span>
    &gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app-validation-message</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group row mt-3"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-1"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span> (<span class="hljs-attr">click</span>)=<span class="hljs-string">"petForm.reset()"</span>&gt;</span>
        Clear
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-1"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre><p>We are going to examine the form directives, attributes, bindings, and events. </p>
<ul>
<li>The form tag:<ul>
<li>It has a template reference variable called #petForm assigned to the ngForm directive, this way we can access the form from the template. <ul>
<li>We are using it on (ngSubmit) event to pass the FormGroup to the onSubmit function when the user submits the form. </li>
<li>We also use it in the clear button to allow resetting the form when clicking it.</li>
</ul>
</li>
</ul>
</li>
<li>Two input tags:<ul>
<li>First one:<ul>
<li>Has id attribute related to for attribute from the label tag.</li>
<li>Has name attribute that must be defined when we use [(ngModel)] with and element. When we submit our form value on onSubmit function, the value property name will coincide with the value set on this attribute.</li>
<li>[(ngModel)] two-way data binding allows us to have an object on ts file bound directly to our form, so we can not access the form value only from the petForm template reference variable but also from this object. In this case, the previously mentioned name attribute won't have an effect on the form value property name because it will be defined on the object itself as we will see.</li>
<li>nameModel template reference variable assigned to the ngModel directive so we can access the implicit input-control.<ul>
<li>We use it to display the app-validation-message component or not depending on if the control value is valid (nameModel.valid).</li>
</ul>
</li>
<li>required attribute tells angular that this field is required so when the field is empty the ng-invalid class will be attached to the field and the defined classed on the styles.scss file will be shown. As we define the app-validation-message component it will be shown also if this control is empty.</li>
<li>app-validation-message component that shows the passed message when one of the mentioned conditions is met. </li>
</ul>
</li>
<li>The second is similar to the first. Don't have anything special.</li>
</ul>
</li>
<li>The select tag:<ul>
<li>It has the multiple attribute that allows selecting multiple values at a time.</li>
</ul>
</li>
<li>Clear button previously explained.</li>
<li>Submit button that when is clicked it triggers the ngSubmit event and the form calls onSubmit function where we pass the form.value.</li>
</ul>
<p>This is the result if the name control is empty (red color on input border and the app-validation-message component visible):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658761511567/ggmy4TUFE.png" alt="Captura de pantalla de 2022-07-25 17-04-43.png" /></p>
<p>This is the result if any form-control value has changed (brown color on input border):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658761558738/hT8vZBxna.png" alt="Captura de pantalla de 2022-07-25 17-05-47.png" /></p>
<p>This is the result if the control has been visited (blue color on the input border):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658761690508/1zKwJtDnj.png" alt="Captura de pantalla de 2022-07-25 17-07-10.png" /></p>
<p>The ts file related to this html file is the next:</p>
<pre><code><span class="hljs-comment">// pets-template-driven.component.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">Component</span>, <span class="hljs-title">OnInit</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title">Pet</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'./pet.model'</span>;

@Component({
  selector: <span class="hljs-string">'app-pets-template-driven'</span>,
  templateUrl: <span class="hljs-string">'./pets-template-driven.component.html'</span>,
  styleUrls: [<span class="hljs-string">'./pets-template-driven.component.scss'</span>],
})
export class PetsTemplateDrivenComponent implements OnInit {
  actualPet: Pet;
  toys: <span class="hljs-keyword">string</span>[];
  <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
    const pet <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Pet(<span class="hljs-string">'Toby'</span>, [<span class="hljs-string">'ball'</span>, <span class="hljs-string">'teddy'</span>], <span class="hljs-string">'Tom'</span>);
    <span class="hljs-built_in">this</span>.actualPet <span class="hljs-operator">=</span> pet;
    <span class="hljs-built_in">this</span>.toys <span class="hljs-operator">=</span> [<span class="hljs-string">'ball'</span>, <span class="hljs-string">'teddy'</span>, <span class="hljs-string">'cord'</span>, <span class="hljs-string">'bone'</span>]
  }

  ngOnInit(): void {}

  onSubmit(petForm: FormGroup) {
    <span class="hljs-keyword">if</span> (petForm.valid) {
      <span class="hljs-comment">// Two ways of getting form values</span>

      <span class="hljs-comment">// First one passing as parameter from html. Property names coincide with name attribute of html tags.</span>
      <span class="hljs-comment">// Check that name property name appears as passedName con console</span>
      console.log(petForm.<span class="hljs-built_in">value</span>);

      <span class="hljs-comment">// Second one getting the binded model to the form</span>
      console.log(<span class="hljs-built_in">this</span>.actualPet)

      <span class="hljs-comment">// Property values must coincide but property names can vary depending on the name attributes</span>
    }
  }
}
</code></pre><p>On the constructor we define the select available options (toys) and a default pet to be displayed when the application is started based on a defined model:</p>
<p> We also see the onSubmit function that will be called when the user clicks the submit button. Here we are accessing the form value in two ways, with the [(ngModel)] two way data binding access (actualPet object) and the value passed on the function as we mentioned earlier. We can use the one we prefer depending on what is our purpose. The only difference will be that two way data bound object won't show the name attribute value as the property name of the form value and the form value passed on the onSubmit function yes. The console.log will be shown when the form validations are met. </p>
<p>This is the result of clicking the submit button:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1658762115455/1lSdmeJ-sK.png" alt="Captura de pantalla de 2022-07-25 17-14-56.png" /></p>
<p>Bibliography:</p>
<ul>
<li>https://angular.io/guide/forms-overview</li>
<li>https://angular.io/guide/reactive-forms</li>
<li>https://angular.io/guide/forms</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Application Environments]]></title><description><![CDATA[The next explanations are based on this project
Angular applications can be launched in multiple environments. Most commons are development and production.
When we want to launch our application in the development environment we have to type on our c...]]></description><link>https://blog.jonandonicastelo.org/application-environments</link><guid isPermaLink="true">https://blog.jonandonicastelo.org/application-environments</guid><category><![CDATA[Angular]]></category><category><![CDATA[Environment]]></category><category><![CDATA[environments]]></category><dc:creator><![CDATA[Jon Andoni Castelo Meléndez]]></dc:creator><pubDate>Sun, 03 Jul 2022 11:51:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1656848943866/Pu-ubYf5Y.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The next explanations are based on <a target="_blank" href="https://github.com/fullstackdeveloperbilbao/application-environment.git">this project</a></p>
<p>Angular applications can be launched in multiple environments. Most commons are <strong>development</strong> and <strong>production</strong>.
When we want to launch our application in the development environment we have to type on our console:</p>
<blockquote>
<p>ng serve</p>
</blockquote>
<p>or </p>
<blockquote>
<p>ng serve --configuration=development</p>
</blockquote>
<p>If we want to launch it in the production environment we can do it in two ways:</p>
<blockquote>
<p>ng build</p>
</blockquote>
<p>or </p>
<blockquote>
<p>ng build --configuration=production</p>
</blockquote>
<p>Angular offers us the customizable scripts object in the package.json file. We can execute previously commented commands running others shorter. When we execute these commands placed in the package.json file, angular looks into the angular.json file to know what has to do with each command.</p>
<pre><code>// This <span class="hljs-keyword">is</span> package.json file
{
  <span class="hljs-string">"name"</span>: <span class="hljs-string">"application-environment"</span>,
  <span class="hljs-string">"version"</span>: <span class="hljs-string">"0.0.0"</span>,
  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"ng"</span>: <span class="hljs-string">"ng"</span>,
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"ng serve"</span>,
    <span class="hljs-string">"start:prod"</span>: <span class="hljs-string">"ng serve --configuration=production"</span>,
    <span class="hljs-string">"build:serve:prod"</span>: <span class="hljs-string">"ng build --configuration=production; http-server -p 4200 ./dist/application-environment"</span>,
    <span class="hljs-string">"build:serve:pre"</span>: <span class="hljs-string">"ng build --configuration=preproduction; http-server -p 4200 ./dist/application-environment"</span>,
    <span class="hljs-string">"build"</span>: <span class="hljs-string">"ng build"</span>,
    <span class="hljs-string">"watch"</span>: <span class="hljs-string">"ng build --watch --configuration development"</span>,
    <span class="hljs-string">"test"</span>: <span class="hljs-string">"ng test"</span>
  },
...
</code></pre><p>So let's start with<em> npm run start</em>. On the above piece of code, we see that <em>npm run start</em> executes the command <em>ng serve</em>.</p>
<pre><code><span class="hljs-comment">// This is the angular.json file</span>
...
<span class="hljs-string">"architect"</span>: {
        ...
        <span class="hljs-string">"serve"</span>: {
          <span class="hljs-string">"builder"</span>: <span class="hljs-string">"@angular-devkit/build-angular:dev-server"</span>,
          <span class="hljs-string">"configurations"</span>: {
            <span class="hljs-string">"production"</span>: {
              <span class="hljs-string">"browserTarget"</span>: <span class="hljs-string">"application-environment:build:production"</span>
            },
            <span class="hljs-string">"development"</span>: {
              <span class="hljs-string">"browserTarget"</span>: <span class="hljs-string">"application-environment:build:development"</span>
            }
          },
          <span class="hljs-string">"defaultConfiguration"</span>: <span class="hljs-string">"development"</span>
        },
...
</code></pre><p>The builder property targets <a target="_blank" href="https://www.npmjs.com/package/@angular-devkit/build-angular">a development server</a> that provides live reloading. We have two configurations: production and development. Each one has a browserTarget property that points to the architect/build/configurations property of the angular.json file. The default configuration is <em>development</em> so this will be the configuration used. We can use the <em>production</em> configuration by changing the defaultConfiguration property to <em>production</em> or by using the package.json command <em>npm run build:serve:prod</em>.</p>
<p>Next is the architect property of the angular.json file:</p>
<pre><code><span class="hljs-comment">// This is angular.json file</span>
...
<span class="hljs-string">"architect"</span>: {
        <span class="hljs-string">"build"</span>: {
          ...
          <span class="hljs-string">"configurations"</span>: {
            <span class="hljs-string">"production"</span>: {
              ...
              ],
              <span class="hljs-string">"fileReplacements"</span>: [
                {
                  <span class="hljs-string">"replace"</span>: <span class="hljs-string">"src/environments/environment.ts"</span>,
                  <span class="hljs-string">"with"</span>: <span class="hljs-string">"src/environments/environment.prod.ts"</span>
                }
              ],
              ...
            },
            <span class="hljs-string">"development"</span>: {
              <span class="hljs-string">"buildOptimizer"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-string">"optimization"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-string">"vendorChunk"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-string">"extractLicenses"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-string">"sourceMap"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-string">"namedChunks"</span>: <span class="hljs-literal">true</span>
            },
            <span class="hljs-string">"preproduction"</span>: {
              ...
              <span class="hljs-string">"fileReplacements"</span>: [
                {
                  <span class="hljs-string">"replace"</span>: <span class="hljs-string">"src/environments/environment.ts"</span>,
                  <span class="hljs-string">"with"</span>: <span class="hljs-string">"src/environments/environment.pre.ts"</span>
                }
              ],
              ...
            }
          },
          <span class="hljs-string">"defaultConfiguration"</span>: <span class="hljs-string">"production"</span>
        },
</code></pre><p>When we select the development environment, there is no fileReplacements property in its configuration so by default angular will take the enviroments.ts file located at src/enviroments folder and launch the development server. If we launch the application with production configuration, the command will find the fileReplacements property and instead of using the default environment file it will use the enviroment.prod.ts file.</p>
<pre><code><span class="hljs-comment">// This is enviroment.ts file</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> environment = {
  <span class="hljs-keyword">type</span>: <span class="hljs-string">"DEVELOPMENT"</span>,
  url: <span class="hljs-string">"https://swapi.dev/api/people/1"</span>
};
</code></pre><pre><code><span class="hljs-comment">// This is enviroment.prod.ts file</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> environment = {
  <span class="hljs-keyword">type</span>: <span class="hljs-string">"PRODUCTION"</span>,
  url: <span class="hljs-string">"https://swapi.dev/api/people/2"</span>
};
</code></pre><p>Now if we analyze "npm run build:serve:prod" we see that it executes the command "ng build --configuration=production; http-server -p 4200 ./dist/application-environment". These are two separate commands that will be executed one after each other. The first to execute is "ng build --configuration=production". As with the "npm run start" command let's look into the angular.json file to know what this command does:</p>
<pre><code><span class="hljs-comment">// This is angular.json file</span>
...
<span class="hljs-string">"architect"</span>: {
        <span class="hljs-string">"build"</span>: {
          <span class="hljs-string">"builder"</span>: <span class="hljs-string">"@angular-devkit/build-angular:browser"</span>,
          ...
          },
          <span class="hljs-string">"configurations"</span>: {
            <span class="hljs-string">"production"</span>: {
              ...
              <span class="hljs-string">"fileReplacements"</span>: [
                {
                  <span class="hljs-string">"replace"</span>: <span class="hljs-string">"src/environments/environment.ts"</span>,
                  <span class="hljs-string">"with"</span>: <span class="hljs-string">"src/environments/environment.prod.ts"</span>
                }
              ],
              ...
            },
            <span class="hljs-string">"development"</span>: {
              <span class="hljs-string">"buildOptimizer"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-string">"optimization"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-string">"vendorChunk"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-string">"extractLicenses"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-string">"sourceMap"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-string">"namedChunks"</span>: <span class="hljs-literal">true</span>
            },
            <span class="hljs-string">"preproduction"</span>: {
              ...
              <span class="hljs-string">"fileReplacements"</span>: [
                {
                  <span class="hljs-string">"replace"</span>: <span class="hljs-string">"src/environments/environment.ts"</span>,
                  <span class="hljs-string">"with"</span>: <span class="hljs-string">"src/environments/environment.pre.ts"</span>
                }
              ],
              ...
            }
          },
          <span class="hljs-string">"defaultConfiguration"</span>: <span class="hljs-string">"production"</span>
        },
...
</code></pre><p>Now instead of looking into the <em>serve</em> property, we look into the <em>build</em> property. In this case the <em>builder</em> property targets [the browser value](Build an Angular application targeting a browser environment) that builds an Angular application targeting a browser environment. As we used the <em>--configuration=production</em>, production will be the configuration used from the angular.json file, and as we see there will be a file replacement with the environment.prod.ts file. The same would occur if we use the <em>--configuration=preproduction</em> but angular would replace the default file with environment.pre.ts file.</p>
<p>The second part of the command is "http-server -p 4200 ./dist/application-environment". This serves the built application in a development server.</p>
<p>Next are some different results depending on the command executed,  try yourself:</p>
<blockquote>
<p>npm run start</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1656848269530/3P6pJR4Cz.png" alt="Captura de Pantalla 2022-07-03 a las 12.37.36.png" /></p>
<blockquote>
<p>npm run start:prod</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1656848316697/6beHv-ZN-.png" alt="Captura de Pantalla 2022-07-03 a las 12.38.27.png" /></p>
<blockquote>
<p>npm run build:serve:prod</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1656848519185/2Pw7FgVCx.png" alt="Captura de Pantalla 2022-07-03 a las 12.41.51.png" /></p>
<blockquote>
<p>npm run build:serve:pre</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1656848572753/80e-01LGV.png" alt="Captura de Pantalla 2022-07-03 a las 12.42.42.png" /></p>
<p>Bibliography:</p>
<ul>
<li>https://angular.io/guide/build</li>
<li>https://www.npmjs.com/package/@angular-devkit/build-angular</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Blog presentation]]></title><description><![CDATA[This blog is a helping tool to be able to check solutions when doubting how to implement some solutions with Angular.]]></description><link>https://blog.jonandonicastelo.org/blog-presentation</link><guid isPermaLink="true">https://blog.jonandonicastelo.org/blog-presentation</guid><category><![CDATA[presentations]]></category><dc:creator><![CDATA[Jon Andoni Castelo Meléndez]]></dc:creator><pubDate>Sun, 19 Jun 2022 18:31:25 GMT</pubDate><content:encoded><![CDATA[<p>This blog is a helping tool to be able to check solutions when doubting how to implement some solutions with Angular.</p>
]]></content:encoded></item></channel></rss>