<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Angular Blog &#8212; onthecode</title>
	<atom:link href="https://onthecode.co.uk/blog/category/angular/feed" rel="self" type="application/rss+xml" />
	<link>https://onthecode.co.uk/blog/category/angular</link>
	<description>onthecode blog</description>
	<lastBuildDate>Mon, 13 Feb 2023 22:36:00 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.3</generator>

<image>
	<url>https://onthecode.co.uk/wp-content/uploads/2019/02/onthecode-icon-1-100x100.png</url>
	<title>Angular Blog &#8212; onthecode</title>
	<link>https://onthecode.co.uk/blog/category/angular</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Change Detection in Angular: Default vs OnPush</title>
		<link>https://onthecode.co.uk/blog/change-detection-in-angular-default-vs-onpush</link>
					<comments>https://onthecode.co.uk/blog/change-detection-in-angular-default-vs-onpush#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Sun, 12 Feb 2023 22:07:26 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=5611</guid>

					<description><![CDATA[<p>One of the most loved features of Angular is its ability to automatically update the view whenever data changes. This is thanks to the default Angular&#8217;s change detection mechanism, which constantly checks for changes in data and updates the view accordingly. While this is great for most use cases, it is possible to manually detect changes for performance optimisation. Let&#8217;s explore change detection strategies in Angular. What is a change detection strategy? A change detection strategy is a mechanism that decides when Angular should update the view of a component. Angular offers the following change detection strategies: Any newly generated component uses the default strategy. ChangeDetectionStrategy.Default Default strategy triggers change detection for DOM events, timers, promises, XHR, observables etc. Therefore, every time something changes in our application, a change detection will run on all components to update the view. Angular achieves this by creating a change detector, which is responsible for listening to changes and updating the view of the component. ChangeDetectionStrategy.OnPush The OnPush strategy can be used to optimise the performance of an Angular application. With OnPush strategy, Angular only performs a change detection cycle on a component and its children, if there is a change in the component&#8217;s input properties or if an event is triggered. OnPush triggers change detection when: If the component&#8217;s data model is updated outside of Angular&#8217;s change detection mechanism, Angular will not update the view. This may sound like a drawback, but it&#8217;s actually a useful feature when used correctly. The OnPush strategy is designed to reduce the number of unnecessary change detection cycles. This is especially important in complex applications, where change detection can become a bottleneck and degrading overall performance of the application. How to use onPush strategy To use the OnPush strategy, you simply need to set the changeDetection property of the component&#8217;s @Component decorator to ChangeDetectionStrategy.OnPush. Here&#8217;s an example: It&#8217;s important to note that when using the OnPush strategy, you need to make sure that Angular is aware of any changes in the component&#8217;s data model. This can be done by using the markForCheck method from the ChangeDetectorRef class. The ChangeDetectorRef class provides a way to interact with the change detection mechanism and manually trigger change detection. You can mark a component or its ancestors for checking using the markForCheck method. Next time change detection runs, the view will reflect the new state of data. markForCheck() vs detectChanges() Another method available on the change detector is detectChanges. You might be wondering, what is the difference between markForCheck and detectChanges. The key difference between these is that&#160;detectChanges()&#160;triggers change detection, while&#160;markForCheck()&#160;doesn&#8217;t trigger change detection. With detectChanges(), the change detection will run for the current component and all its children. This is a common fix to the infamous error Expression has changed after it was checked. On the other hand, markForCheck() simply goes upwards from the current component to the root component and updates their view state to&#160;ChecksEnabled. The change detection for the component will happen in the future either as part of the current or next change detection cycle. The parent component views will also be checked even if they had detached change detectors.&#160; Should I use onPush strategy? If change detection is a bottle-neck in your component, go ahead and try onPush change detection strategy. This is a great way to fine-tune the performance of your application. However, premature optimisation can have an adverse effect on your application. If you use onPush strategy without a valid reason, the component code will be more complex, harder to test and more difficult to maintain. Based on my experience, the default strategy will work just fine for most small to medium sized applications. Conclusion In this post, we&#8217;ve looked at the different change detection strategies available in Angular. Default strategy automatically updates view when there is a change in the data model. OnPush strategy allows us to optimise performance by giving us the freedom to choose when to check for changes.</p>
<p>The post <a href="https://onthecode.co.uk/blog/change-detection-in-angular-default-vs-onpush">Change Detection in Angular: Default vs OnPush</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>One of the most loved features of <a href="/blog/category/angular" target="_blank" rel="noreferrer noopener">Angular</a> is its ability to automatically update the view whenever data changes.</p>



<p>This is thanks to the default Angular&#8217;s change detection mechanism, which constantly checks for changes in data and updates the view accordingly. While this is great for most use cases, it is possible to manually detect changes for performance optimisation.</p>



<p>Let&#8217;s explore change detection strategies in Angular.</p>



<h2 class="wp-block-heading">What is a change detection strategy?</h2>



<p>A change detection strategy is a mechanism that decides when Angular should update the view of a component.</p>



<p>Angular <a href="https://angular.io/api/core/ChangeDetectionStrategy" target="_blank" rel="noreferrer noopener">offers</a> the following change detection strategies:</p>



<ul class="wp-block-list">
<li>ChangeDetectionStrategy.<strong>Default</strong></li>



<li>ChangeDetectionStrategy.<strong>OnPush</strong></li>
</ul>



<p>Any newly generated component uses the default strategy. </p>



<h2 class="wp-block-heading">ChangeDetectionStrategy.Default</h2>



<p>Default strategy triggers change detection for DOM events, timers, promises, XHR, observables etc. Therefore, every time something changes in our application, a change detection will run on all components to update the view.</p>



<p>Angular achieves this by creating a change detector, which is responsible for listening to changes and updating the view of the component.</p>



<h2 class="wp-block-heading">ChangeDetectionStrategy.OnPush</h2>



<p>The <code>OnPush</code> strategy can be used to optimise the performance of an Angular application.</p>



<p>With OnPush strategy, Angular only performs a change detection cycle on a component and its children, if there is a change in the component&#8217;s input properties or if an event is triggered.</p>



<p>OnPush triggers change detection when:</p>



<ul class="wp-block-list">
<li>DOM events listened by the component emit</li>



<li><code>async</code>&nbsp;pipe receives a new event</li>



<li><code>@Input()</code>&nbsp;property updates by change detection</li>



<li>Explicitly registration using&nbsp;<code>ChangeDetectorRef::markForCheck</code></li>
</ul>



<p>If the component&#8217;s data model is updated outside of Angular&#8217;s change detection mechanism, Angular will not update the view.</p>



<p>This may sound like a drawback, but it&#8217;s actually a useful feature when used correctly. </p>



<p>The <code>OnPush</code> strategy is designed to reduce the number of unnecessary change detection cycles. This is especially important in complex applications, where change detection can become a bottleneck and degrading overall performance of the application.</p>



<h2 class="wp-block-heading">How to use onPush strategy</h2>



<p>To use the <code>OnPush</code> strategy, you simply need to set the <code>changeDetection</code> property of the component&#8217;s <code>@Component</code> decorator to <code>ChangeDetectionStrategy.OnPush</code>. </p>



<p>Here&#8217;s an example:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { ChangeDetectionStrategy, Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">'app-hello-world'</span>,
</span></span><span class='shcb-loc'><span>  template: <span class="hljs-string">`</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">    &lt;p&gt;{{ message }}&lt;/p&gt;</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">  `</span>,
</span></span><mark class='shcb-loc'><span>  changeDetection: ChangeDetectionStrategy.OnPush
</span></mark><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> HelloWorldComponent {
</span></span><span class='shcb-loc'><span>  message = <span class="hljs-string">'Hello, World!'</span>;
</span></span><span class='shcb-loc'><span>}
</span></span></code></span></pre>


<p>It&#8217;s important to note that when using the <code>OnPush</code> strategy, you need to make sure that Angular is aware of any changes in the component&#8217;s data model.</p>



<p>This can be done by using the  <code>markForCheck</code> method from the <code>ChangeDetectorRef</code> class.</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { ChangeDetectorRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> cd: ChangeDetectorRef</span>) { }
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span>ngOnInit() {
</span></span><span class='shcb-loc'><span>  <span class="hljs-comment">// Do some work that changes data</span>
</span></span><mark class='shcb-loc'><span>  <span class="hljs-keyword">this</span>.cd.markForCheck();
</span></mark><span class='shcb-loc'><span>}
</span></span></code></span></pre>


<p>The <code>ChangeDetectorRef</code> class provides a way to interact with the change detection mechanism and manually trigger change detection. </p>



<p>You can mark a component or its ancestors for checking using the <code>markForCheck </code>method. Next time change detection runs, the view will reflect the new state of data.</p>



<h2 class="wp-block-heading">markForCheck() vs detectChanges()</h2>



<p>Another method available on the change detector is <code>detectChanges</code>. You might be wondering, what is the difference between markForCheck and detectChanges.</p>



<p>The key difference between these is that&nbsp;<code>detectChanges()</code>&nbsp;triggers change detection, while&nbsp;<code>markForCheck()</code>&nbsp;doesn&#8217;t trigger change detection.</p>



<p>With <code>detectChanges</code>(), the change detection will run for the current component and all its children. This is a common fix to the infamous error <strong>Expression has changed after it was checked</strong>.</p>



<p>On the other hand, <code>markForCheck()</code> simply goes upwards from the current component to the root component and updates their view state to&nbsp;<code>ChecksEnabled</code>. The change detection for the component will happen in the future either as part of the current or next change detection cycle. The parent component views will also be checked even if they had detached change detectors.&nbsp;</p>



<h2 class="wp-block-heading">Should I use onPush strategy?</h2>



<p>If change detection is a bottle-neck in your component, go ahead and try <code>onPush</code> change detection strategy. This is a great way to fine-tune the performance of your application.</p>



<p>However, premature optimisation can have an adverse effect on your application.</p>



<p>If you use <code>onPush</code> strategy without a valid reason, the component code will be more complex, harder to test and more difficult to maintain.</p>



<p>Based on my experience, the default strategy will work just fine for most small to medium sized applications.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>In this post, we&#8217;ve looked at the different change detection strategies available in Angular. Default strategy automatically updates view when there is a change in the data model. OnPush strategy allows us to optimise performance by giving us the freedom to choose when to check for changes.</p>
<p>The post <a href="https://onthecode.co.uk/blog/change-detection-in-angular-default-vs-onpush">Change Detection in Angular: Default vs OnPush</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/change-detection-in-angular-default-vs-onpush/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Set Page Title Based on Route in Angular</title>
		<link>https://onthecode.co.uk/blog/how-to-set-page-title-based-on-route-in-angular</link>
					<comments>https://onthecode.co.uk/blog/how-to-set-page-title-based-on-route-in-angular#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Sun, 29 Jan 2023 17:44:05 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=4557</guid>

					<description><![CDATA[<p>In this post, I will show you how to set page title based on route in Angular. Angular provides a built-in Title service that we can use to set the title of the web page dynamically from code. We will use the title service in combination with router events to change page title for all routes. Setting page title in Angular Firstly, import the Title service in the component you want to set the title: Inject the Title service in the constructor of the component: Then you can use the setTitle method of the Title service to set the title of the web page. For example, you can set the title based on the data received from a service or from the component&#8217;s properties: As you can see, it is pretty straightforward to use set the title in Angular. Setting the title for all routes Instead of setting the title in every component that&#8217;s associated with a route, we&#8217;ll take it a step further and dynamically set the title from the routes table. DRY (don&#8217;t repeat yourself) is a principle in software development that recommends to do something once, and only once. The first step is to update routes table in every feature module to hold page titles. You should now go through all routes of your app and make sure there is a title associated with every route! Next, generate a service to get data from the current route: Implement the service with below code: This service allows us to pull out the data object we defined in our routes earlier. Like any other singleton service, we can inject it into any component to set the title. Since we want to set the title for every page, we need to subscribe to router events in the root component app.component.ts. Let&#8217;s to update app.component.ts to read the title every time navigation occurs: By using this method, you can set the title of the web page dynamically based on the data from the router events, which will update the title of the window in real-time. Conclusion In summary, we learned how to set the page title in Angular. Through DRY principle, we implemented a feature that sets the page title based on Angular router events. Let me know what you think by dropping a comment below!</p>
<p>The post <a href="https://onthecode.co.uk/blog/how-to-set-page-title-based-on-route-in-angular">How to Set Page Title Based on Route in Angular</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In this post, I will show you how to set page title based on route in Angular.</p>



<p><a href="/blog/category/angular">Angular</a> provides a built-in <a href="https://angular.io/api/platform-browser/Title" target="_blank" rel="noreferrer noopener">Title</a> service that we can use to set the title of the web page dynamically from code. We will use the title service in combination with router events to change page title for all routes. </p>



<h2 class="wp-block-heading">Setting page title in Angular</h2>



<p>Firstly, import the Title service in the component you want to set the title:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">import</span> { Title } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser'</span>;</code></span></pre>


<p>Inject the <code>Title</code> service in the constructor of the component:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> titleService: Title</span>) {}</code></span></pre>


<p>Then you can use the <code>setTitle</code> method of the <code>Title</code> service to set the title of the web page. </p>



<p>For example, you can set the title based on the data received from a service or from the component&#8217;s properties:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">this</span>.title.setTitle(<span class="hljs-string">`My Awesome App - <span class="hljs-subst">${data.title}</span>`</span>);</code></span></pre>


<p>As you can see, it is pretty straightforward to use set the title in Angular.</p>



<h2 class="wp-block-heading">Setting the title for all routes</h2>



<p>Instead of setting the title in every component that&#8217;s associated with a route, we&#8217;ll take it a step further and dynamically set the title from the routes table.</p>



<p class="info-block">DRY (don&#8217;t repeat yourself) is a principle in software development that recommends to do something once, and only once.</p>



<p>The first step is to update routes table in every feature module to hold page titles.</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">const</span> routes: Routes = &#91;
</span></span><span class='shcb-loc'><span>  {
</span></span><span class='shcb-loc'><span>    path: <span class="hljs-string">""</span>,
</span></span><span class='shcb-loc'><span>    component: HomePageComponent,
</span></span><span class='shcb-loc'><span>    data: {
</span></span><mark class='shcb-loc'><span>      title: <span class="hljs-string">"Home"</span>
</span></mark><span class='shcb-loc'><span>    }
</span></span><span class='shcb-loc'><span>  },
</span></span><span class='shcb-loc'><span>  {
</span></span><span class='shcb-loc'><span>    path: <span class="hljs-string">"blog"</span>,
</span></span><span class='shcb-loc'><span>    component: BlogPageComponent,
</span></span><span class='shcb-loc'><span>    data: {
</span></span><mark class='shcb-loc'><span>      title: <span class="hljs-string">"Blog"</span>
</span></mark><span class='shcb-loc'><span>    }
</span></span><span class='shcb-loc'><span>  },
</span></span><span class='shcb-loc'><span>  {
</span></span><span class='shcb-loc'><span>    path: <span class="hljs-string">"**"</span>,
</span></span><span class='shcb-loc'><span>    component: NotFoundPageComponent,
</span></span><span class='shcb-loc'><span>    data: {
</span></span><mark class='shcb-loc'><span>      title: <span class="hljs-string">"Not Found"</span>
</span></mark><span class='shcb-loc'><span>    }
</span></span><span class='shcb-loc'><span>  }
</span></span><span class='shcb-loc'><span>];
</span></span></code></span></pre>


<p>You should now go through all routes of your app and make sure there is a title associated with every route!</p>



<p>Next, generate a service to get <code>data</code> from the current route:</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">ng generate service route-data</code></span></pre>


<p>Implement the service with below code:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/core"</span>;
<span class="hljs-keyword">import</span> { ActivatedRoute, ActivatedRouteSnapshot, Data } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/router"</span>;

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">"root"</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> RouteDataService {

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

  <span class="hljs-keyword">get</span>(): Data {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.getRouteSnapshot().data;
  }

  <span class="hljs-keyword">private</span> getRouteSnapshot(): ActivatedRouteSnapshot {
    <span class="hljs-keyword">let</span> route = <span class="hljs-keyword">this</span>.route;

    <span class="hljs-keyword">while</span> (route.firstChild) {
      route = route.firstChild;
    }

    <span class="hljs-keyword">return</span> route.snapshot;
  }
}
</code></span></pre>


<p>This service allows us to pull out the <code>data</code> object we defined in our routes earlier.</p>



<p>Like any other singleton service, we can inject it into any component to set the title.</p>



<p>Since we want to set the title for every page, we need to subscribe to router events in the root component <code>app.component.ts</code>.</p>



<p>Let&#8217;s to update <code>app.component.ts</code> to read the title every time navigation occurs:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { filter } <span class="hljs-keyword">from</span> <span class="hljs-string">'rxjs'</span>;
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { Component, OnInit } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { Title } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser'</span>;
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { NavigationEnd, Router } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { RouteDataService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./route-data.service'</span>;
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">'app-root'</span>,
</span></span><span class='shcb-loc'><span>  templateUrl: <span class="hljs-string">'./app.component.html'</span>,
</span></span><span class='shcb-loc'><span>  styleUrls: &#91;<span class="hljs-string">'./app.component.scss'</span>]
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppComponent <span class="hljs-keyword">implements</span> OnInit {
</span></span><span class='shcb-loc'><span>  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> router: Router,</span>
</span></span><span class='shcb-loc'><span><span class="hljs-params">    <span class="hljs-keyword">private</span> routeDataService: RouteDataService,</span>
</span></span><span class='shcb-loc'><span><span class="hljs-params">    <span class="hljs-keyword">private</span> title: Title</span>) {
</span></span><span class='shcb-loc'><span>  }
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span>  ngOnInit(): <span class="hljs-built_in">void</span> {
</span></span><span class='shcb-loc'><span>    <span class="hljs-keyword">this</span>.router.events
</span></span><span class='shcb-loc'><span>      .pipe(filter(<span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> event <span class="hljs-keyword">instanceof</span> NavigationEnd))
</span></span><span class='shcb-loc'><span>      .subscribe(_ =&gt;
</span></span><mark class='shcb-loc'><span>        <span class="hljs-keyword">this</span>.title.setTitle(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-keyword">this</span>.routeDataService.<span class="hljs-keyword">get</span>()&#91;<span class="hljs-string">"title"</span>]}</span> - Umut Esen`</span>)
</span></mark><span class='shcb-loc'><span>      );
</span></span><span class='shcb-loc'><span>  }
</span></span><span class='shcb-loc'><span>}
</span></span><span class='shcb-loc'><span>
</span></span></code></span></pre>


<p>By using this method, you can set the title of the web page dynamically based on the data from the router events, which will update the title of the window in real-time.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>In summary, we learned how to set the page title in Angular. Through DRY principle, we implemented a feature that sets the page title based on Angular router events.</p>



<p>Let me know what you think by dropping a comment below!</p>
<p>The post <a href="https://onthecode.co.uk/blog/how-to-set-page-title-based-on-route-in-angular">How to Set Page Title Based on Route in Angular</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/how-to-set-page-title-based-on-route-in-angular/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Generating Routes File for Angular Universal Prerender</title>
		<link>https://onthecode.co.uk/blog/generating-routes-file-for-angular-universal-prerender</link>
					<comments>https://onthecode.co.uk/blog/generating-routes-file-for-angular-universal-prerender#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Sat, 07 Jan 2023 19:38:45 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=5561</guid>

					<description><![CDATA[<p>In this blog post, I will show you how to generate a routes file for prerendering an Angular Universal application. We will create a basic routes file and append routes dynamically from an XML sitemap ahead of running npm run prerender command when building the application. Pre-requisites This post assumes you already have an Angular Universal application. If this is not the case, add server-side rendering (SSR) capability to your Angular application by following this guide. Once you add SSR, you can use npm run prerender command to prerender your application. Benefits of prerendering Prerendering with Angular Universal refers to the process of rendering an application&#8217;s content on the server side before sending it to the client. This can help improve the performance of an Angular application, especially for users with slow internet connections or on devices with limited resources. By pre-rendering the application&#8217;s initial state on the server and then serving the fully rendered HTML to the client, the client&#8217;s web browser can start rendering the page immediately, rather than having to wait for all of the necessary JavaScript to download and execute before the content is displayed. This can lead to a faster time to first paint and a better user experience overall. Prerender options There are a few build options available to use with prerender command as outlined by official documentation. These options are: A sitemap is likely to have a large number of URLs so we&#8217;ll provide routes using a file. Modify prerender command Open up package.json and update prerender command to use a routes file: There is no need to manually create a routes.txt file because the script we&#8217;re about to write will automatically create it. Generate routes file We will retrieve urls from an XML sitemap using xml-sitemap-url-scraper package. Install this package as a dev dependency so it does not ship with production bundle: Using this package to retrieve URLs is pretty simple, just provide a direct link to your sitemap as shown below. What you&#8217;ll get in return is a promise containing all of the URLs found in the sitemap. Since prerender command expects relative URL separated by a line break in the routes file, we&#8217;re post-processing the results before creating the file routes.txt. You&#8217;ll want to save this script to the root of your project and run using node in the command line: You would ideally run this script as part of your continuous delivery pipeline, before prerendering the application. Your routes.txt will be populated with all the links specified in your sitemap. Conclusion Hopefully this post helped you with prerendering the pages of your Angular application using a routes file. What do you think? Let me know in the comments below!</p>
<p>The post <a href="https://onthecode.co.uk/blog/generating-routes-file-for-angular-universal-prerender">Generating Routes File for Angular Universal Prerender</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In this blog post, I will show you how to generate a routes file for prerendering an Angular Universal application. </p>



<p>We will create a basic routes file and append routes dynamically from an XML sitemap ahead of running <code>npm run prerender</code> command when building the application. </p>



<h2 class="wp-block-heading">Pre-requisites </h2>



<p>This post assumes you already have an Angular Universal application. If this is not the case, add server-side rendering (SSR) capability to your Angular application by following this <a href="http://To prerender a static page make sure to add Server-Side Rendering (SSR) capabilities to your application. For more information see the universal guide. Once SSR is added, run the following command:" target="_blank" rel="noreferrer noopener">guide</a>.</p>



<p>Once you add SSR, you can use <code>npm run prerender</code> command to prerender your application.</p>



<h2 class="wp-block-heading">Benefits of prerendering</h2>



<p>Prerendering with Angular Universal refers to the process of rendering an application&#8217;s content on the server side before sending it to the client. </p>



<p>This can help improve the performance of an Angular application, especially for users with slow internet connections or on devices with limited resources.</p>



<p>By pre-rendering the application&#8217;s initial state on the server and then serving the fully rendered HTML to the client, the client&#8217;s web browser can start rendering the page immediately, rather than having to wait for all of the necessary JavaScript to download and execute before the content is displayed. </p>



<p>This can lead to a faster time to first paint and a better user experience overall.</p>



<h2 class="wp-block-heading">Prerender options</h2>



<p>There are a few build options available to use with <code>prerender</code> command as outlined by <a href="https://angular.io/guide/prerendering#build-options-for-prerendering" target="_blank" rel="noreferrer noopener">official documentation</a>.</p>



<p>These options are:</p>



<ul class="wp-block-list">
<li>Provide extra routes in the command line</li>



<li>Provide routes using a file</li>



<li>Prerender specific routes</li>
</ul>



<p>A sitemap is likely to have a large number of URLs so we&#8217;ll provide routes using a file.</p>



<h2 class="wp-block-heading">Modify prerender command</h2>



<p>Open up <code>package.json</code> and update prerender command to use a routes file:</p>


<pre class="wp-block-code"><span><code class="hljs language-json"><span class="hljs-string">"prerender"</span>: <span class="hljs-string">"ng run myapp:prerender --routes-file routes.txt"</span></code></span></pre>


<p>There is no need to manually create a routes.txt file because the script we&#8217;re about to write will automatically create it.</p>



<h2 class="wp-block-heading">Generate routes file</h2>



<p>We will retrieve urls from an XML sitemap using <code>xml-sitemap-url-scraper</code> package.</p>



<p>Install this package as a dev dependency so it does not ship with production bundle:</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">npm install xml-sitemap-url-scraper --save-dev</code></span></pre>


<p>Using this package to retrieve URLs is pretty simple, just provide a direct link to your sitemap as shown below. </p>



<p>What you&#8217;ll get in return is a promise containing all of the URLs found in the sitemap.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">const</span> { sitemapUrlScraper } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"xml-sitemap-url-scraper"</span>);
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">const</span> url = <span class="hljs-string">"https://mysite.com/sitemap_index.xml"</span>;
</span></span><span class='shcb-loc'><span>
</span></span><mark class='shcb-loc'><span>sitemapUrlScraper(&#91;url])
</span></mark><span class='shcb-loc'><span>    .then(<span class="hljs-function"><span class="hljs-params">urls</span> =&gt;</span> {
</span></span><span class='shcb-loc'><span>        <span class="hljs-keyword">const</span> routes = urls
</span></span><mark class='shcb-loc'><span>            .map(<span class="hljs-function"><span class="hljs-params">url</span> =&gt;</span> url.replace(<span class="hljs-keyword">new</span> URL(url).origin, <span class="hljs-string">""</span>))
</span></mark><mark class='shcb-loc'><span>            .join(<span class="hljs-string">'\r\n'</span>);
</span></mark><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span>        fs.writeFile(<span class="hljs-string">'routes.txt'</span>, <span class="hljs-string">'\r\n'</span> + routes, err =&gt; {
</span></span><span class='shcb-loc'><span>            <span class="hljs-keyword">if</span> (err) {
</span></span><span class='shcb-loc'><span>                <span class="hljs-built_in">console</span>.error(err);
</span></span><span class='shcb-loc'><span>            }
</span></span><span class='shcb-loc'><span>        });
</span></span><span class='shcb-loc'><span>    })
</span></span><span class='shcb-loc'><span>    .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> { <span class="hljs-built_in">console</span>.log(err); })
</span></span></code></span></pre>


<p>Since <code>prerender</code> command expects relative URL separated by a line break in the routes file, we&#8217;re post-processing the results before creating the file <code>routes.txt</code>.</p>



<p>You&#8217;ll want to save this script to the root of your project and run using node in the command line:</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">node route-fetcher.js

Processing XML Sitemap:  https://mysite.com/sitemap_index.xml
Processing XML Sitemap:  https://mysite.com/post-sitemap.xml
Processing XML Sitemap:  https://mysite.com/page-sitemap.xml
Processing XML Sitemap:  https://mysite.com/category-sitemap.xml</code></span></pre>


<p>You would ideally run this script as part of your continuous delivery pipeline, <strong>before</strong> prerendering the application.</p>



<p>Your routes.txt will be populated with all the links specified in your sitemap.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Hopefully this post helped you with prerendering the pages of your Angular application using a routes file. </p>



<p>What do you think? Let me know in the comments below!</p>
<p>The post <a href="https://onthecode.co.uk/blog/generating-routes-file-for-angular-universal-prerender">Generating Routes File for Angular Universal Prerender</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/generating-routes-file-for-angular-universal-prerender/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Fixing Angular Unit Tests: Cannot read property &#8216;range&#8217; of undefined</title>
		<link>https://onthecode.co.uk/blog/fixing-angular-unit-tests-cannot-read-property-range-of-undefined</link>
					<comments>https://onthecode.co.uk/blog/fixing-angular-unit-tests-cannot-read-property-range-of-undefined#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Mon, 19 Dec 2022 15:22:27 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=5483</guid>

					<description><![CDATA[<p>While upgrading Node from v12 to v16, I came across a problem with Angular unit tests where an exception would stop the test run with error Cannot read property 'range' of undefined. In this post, I&#8217;ll explain the steps I took to identify the root cause of issue and propose potential solutions. Identifying the root cause The exception stack trace hints at the root cause of this issue: Let&#8217;s dig deeper and find out what&#8217;s going on the line of code throwing this exception: It looks like webpack-dev-middleware is handling requests as part of the test run. When it comes to handling headers on the request, it is falling over with: Clearly, Accept-Ranges headers are not present in some requests performed during our test run. In order to pinpoint which request is causing this error, let&#8217;s output the name of each file during the test run: Run tests again with ng test and see the file name causing this issue: At this point, we can see the file name and this should hopefully be familiar to you. The chances are your project is somehow trying to load this file from the assets folder using a relative path. Let&#8217;s look at what we can do to fix this issue. Fix #1 &#8211; Configure karma to use proxy The very first thing I tried to fix this issue was to follow the advice of Ievgen, who had the same problem within an Angular project inside a docker container. Simply add the following code in karma.conf.js after&#160;config.set({ Ievgen suggests this new rule in karma configuration will point all requests matching /assets/ to the base folder of the project. Unfortunately, this did not work for me even after adjusting the path to match the setup of my project. Although Ievgen&#8217;s solution did not work for me, it put me in the right direction and helped identify the following fixes. Fix #2 &#8211; Stop using relative paths The first thing I did was to find all the usages of assets folder in the entire source code. It turned out some css files were using relative paths to load some images from the assets folder: The fix is to define the path from the src folder: Repeat this for all references of assets folder to ensure all paths correctly identify a file. Fix #3 &#8211; Exclude 3rd party stylesheets during test run There may be external packages included in the test configuration within angular.json that are using relative path to assets folder. As you can see in the above snippet, the test configuration is loading styles from an external package. Since this package is internally using relative paths to assets, folder the exception is thrown. The solution is to remove this line of code to exclude 3rd party stylesheets during the test run. I hope you found this post useful, drop a comment below to let me know what you think!</p>
<p>The post <a href="https://onthecode.co.uk/blog/fixing-angular-unit-tests-cannot-read-property-range-of-undefined">Fixing Angular Unit Tests: Cannot read property &#8216;range&#8217; of undefined</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>While upgrading Node from v12 to v16, I came across a problem with <a href="/blog/category/angular" target="_blank" rel="noreferrer noopener">Angular </a>unit tests where an exception would stop the test run with error <code>Cannot read property 'range' of undefined</code>.</p>



<p>In this post, I&#8217;ll explain the steps I took to identify the root cause of issue and propose potential solutions.</p>



<h2 class="wp-block-heading">Identifying the root cause</h2>



<p>The exception stack trace hints at the root cause of this issue:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript shcb-code-table"><span class='shcb-loc'><span>(Windows <span class="hljs-number">8.1</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>): Executed <span class="hljs-number">9</span> <span class="hljs-keyword">of</span> <span class="hljs-number">846</span>‌ SUCCESS‌ (<span class="hljs-number">0</span> secs &amp;#x2F; <span class="hljs-number">1.912</span> secs)‌
</span></span><mark class='shcb-loc'><span><span class="hljs-number">15</span> <span class="hljs-number">12</span> <span class="hljs-number">2022</span> <span class="hljs-number">15</span>:<span class="hljs-number">14</span>:<span class="hljs-number">23.895</span>:ERROR &#91;karma-server]: ‌<span class="hljs-built_in">TypeError</span>: Cannot read properties <span class="hljs-keyword">of</span> <span class="hljs-literal">undefined</span> (reading <span class="hljs-string">'range'</span>)‌
</span></mark><span class='shcb-loc'><span>    at handleRangeHeaders (D:\Agents\<span class="hljs-number">1</span>\_work\<span class="hljs-number">424</span>\s\MyApp.Web\node_modules\webpack-dev-middleware\lib\util.js:<span class="hljs-number">134</span>:<span class="hljs-number">21</span>)
</span></span><span class='shcb-loc'><span>    at processRequest (D:\Agents\<span class="hljs-number">1</span>\_work\<span class="hljs-number">424</span>\s\MyApp.Web\node_modules\webpack-dev-middleware\lib\middleware.js:<span class="hljs-number">98</span>:<span class="hljs-number">19</span>)
</span></span><span class='shcb-loc'><span>    at ready (D:\Agents\<span class="hljs-number">1</span>\_work\<span class="hljs-number">424</span>\s\MyApp.Web\node_modules\webpack-dev-middleware\lib\util.js:<span class="hljs-number">54</span>:<span class="hljs-number">12</span>)
</span></span><span class='shcb-loc'><span>    at handleRequest (D:\Agents\<span class="hljs-number">1</span>\_work\<span class="hljs-number">424</span>\s\MyApp.Web\node_modules\webpack-dev-middleware\lib\util.js:<span class="hljs-number">185</span>:<span class="hljs-number">5</span>)
</span></span><span class='shcb-loc'><span>    at D:\Agents\<span class="hljs-number">1</span>\_work\<span class="hljs-number">424</span>\s\MyApp.Web\node_modules\webpack-dev-middleware\lib\middleware.js:<span class="hljs-number">64</span>:<span class="hljs-number">7</span>
</span></span><span class='shcb-loc'><span>    at <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span> (<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">anonymous</span>&gt;</span>)</span>
</span></span></code></span></pre>


<p>Let&#8217;s dig deeper and find out what&#8217;s going on the line of code throwing this exception:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-comment">// node_modules\webpack-dev-middleware\lib\util.js:134 </span>
</span></span><span class='shcb-loc'><span>handleRangeHeaders(content, req, res) {
</span></span><span class='shcb-loc'><span>    <span class="hljs-comment">// assumes express API. For other servers, need to add logic to access</span>
</span></span><span class='shcb-loc'><span>    <span class="hljs-comment">// alternative header APIs</span>
</span></span><span class='shcb-loc'><span>    res.setHeader(<span class="hljs-string">'Accept-Ranges'</span>, <span class="hljs-string">'bytes'</span>);
</span></span><span class='shcb-loc'><span>
</span></span><mark class='shcb-loc'><span>    <span class="hljs-keyword">if</span> (req.headers.range) {
</span></mark><span class='shcb-loc'><span>      <span class="hljs-keyword">const</span> ranges = parseRange(content.length, req.headers.range);
</span></span></code></span></pre>


<p>It looks like <code>webpack-dev-middleware</code> is handling requests as part of the test run. When it comes to handling headers on the request, it is falling over with:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">Cannot read properties <span class="hljs-keyword">of</span> <span class="hljs-literal">undefined</span> (reading <span class="hljs-string">'range'</span>)‌</code></span></pre>


<p>Clearly, <code>Accept-Ranges</code> headers are not present in some requests performed during our test run.</p>



<p>In order to pinpoint which request is causing this error, let&#8217;s output the name of each file during the test run:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// node_modules\webpack-dev-middleware\lib\util.js:134 </span>
  handleRangeHeaders(content, req, res) {
    <span class="hljs-built_in">console</span>.log(req.url);</code></span></pre>


<p>Run tests again with <code>ng test</code> and see the file name causing this issue:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">/_karma_webpack_/assets/icons/icon-library.svg
<span class="hljs-number">15</span> <span class="hljs-number">12</span> <span class="hljs-number">2022</span> <span class="hljs-number">15</span>:<span class="hljs-number">14</span>:<span class="hljs-number">23.895</span>:ERROR &#91;karma-server]: ‌<span class="hljs-built_in">TypeError</span>: Cannot read properties <span class="hljs-keyword">of</span> <span class="hljs-literal">undefined</span> (reading <span class="hljs-string">'range'</span>)‌</code></span></pre>


<p></p>



<p>At this point, we can see the file name and this should hopefully be familiar to you. The chances are your project is somehow trying to load this file from the assets folder using a relative path.</p>



<p>Let&#8217;s look at what we can do to fix this issue.</p>



<h2 class="wp-block-heading">Fix #1 &#8211; Configure karma to use proxy</h2>



<p>The very first thing I tried to fix this issue was to follow the advice of <a href="https://ievgen.de/2020/11/17/angular-tests-fail-docker/" target="_blank" rel="noreferrer noopener">Ievgen</a>, who had the same problem within an Angular project inside a docker container. </p>



<p>Simply add the following code in <em>karma.conf.js</em> after&nbsp;<code>config.set({</code></p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">proxies: {
    <span class="hljs-string">'/assets/'</span>: <span class="hljs-string">'/base/src/assets/'</span>
},</code></span></pre>


<p>Ievgen suggests this new rule in karma configuration will point all requests matching <code>/assets/</code> to the base folder of the project. Unfortunately, this did not work for me even after adjusting the path to match the setup of my project. </p>



<p>Although Ievgen&#8217;s solution did not work for me, it put me in the right direction and helped identify the following fixes. </p>



<h2 class="wp-block-heading">Fix #2 &#8211; Stop using relative paths</h2>



<p>The first thing I did was to find all the usages of <code>assets</code> folder in the entire source code. </p>



<p>It turned out some <code>css</code> files were using relative paths to load some images from the assets folder:</p>


<pre class="wp-block-code"><span><code class="hljs">  content: url(../../../assets/icons/back-icon.png);
</code></span></pre>


<p>The fix is to define the path from the src folder:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">  content: url(<span class="hljs-string">"/src/assets/icons/back-icon.png"</span>);
</code></span></pre>


<p>Repeat this for all references of assets folder to ensure all paths correctly identify a file.</p>



<h2 class="wp-block-heading">Fix #3 &#8211; Exclude 3rd party stylesheets during test run</h2>



<p>There may be external packages included in the test configuration within <code>angular.json</code> that are using relative path to assets folder.</p>


<pre class="wp-block-code"><span><code class="hljs language-json shcb-code-table"><span class='shcb-loc'><span><span class="hljs-comment">// angular.json </span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">"test"</span>: {
</span></span><span class='shcb-loc'><span>          <span class="hljs-attr">"builder"</span>: <span class="hljs-string">"@angular-devkit/build-angular:karma"</span>,
</span></span><span class='shcb-loc'><span>          <span class="hljs-attr">"options"</span>: {
</span></span><span class='shcb-loc'><span>            <span class="hljs-attr">"codeCoverage"</span>: <span class="hljs-literal">true</span>,
</span></span><span class='shcb-loc'><span>            <span class="hljs-attr">"main"</span>: <span class="hljs-string">"src/test.ts"</span>,
</span></span><span class='shcb-loc'><span>            <span class="hljs-attr">"polyfills"</span>: <span class="hljs-string">"src/polyfills.ts"</span>,
</span></span><span class='shcb-loc'><span>            <span class="hljs-attr">"tsConfig"</span>: <span class="hljs-string">"src/tsconfig.spec.json"</span>,
</span></span><span class='shcb-loc'><span>            <span class="hljs-attr">"karmaConfig"</span>: <span class="hljs-string">"karma.conf.js"</span>,
</span></span><span class='shcb-loc'><span>            <span class="hljs-attr">"styles"</span>: &#91;
</span></span><span class='shcb-loc'><span>              <span class="hljs-string">"src/styles.css"</span>
</span></span><mark class='shcb-loc'><span>              <span class="hljs-string">"node_modules/@my-company/web-styles/sass/main.scss"</span>
</span></mark><span class='shcb-loc'><span>            ],
</span></span><span class='shcb-loc'><span>            <span class="hljs-attr">"scripts"</span>: &#91;],
</span></span><span class='shcb-loc'><span>            <span class="hljs-attr">"assets"</span>: &#91;
</span></span><span class='shcb-loc'><span>              <span class="hljs-string">"src/assets"</span>,
</span></span><span class='shcb-loc'><span>              <span class="hljs-string">"src/Web.config"</span>,
</span></span><span class='shcb-loc'><span>              <span class="hljs-string">"src/auth.config"</span>
</span></span><span class='shcb-loc'><span>            ]
</span></span><span class='shcb-loc'><span>          } 
</span></span></code></span></pre>


<p>As you can see in the above snippet, the test configuration is loading styles from an external package.</p>



<p>Since this package is internally using relative paths to assets, folder the exception is thrown. The solution is to remove this line of code to exclude 3rd party stylesheets during the test run.</p>



<p>I hope you found this post useful, drop a comment below to let me know what you think!</p>
<p>The post <a href="https://onthecode.co.uk/blog/fixing-angular-unit-tests-cannot-read-property-range-of-undefined">Fixing Angular Unit Tests: Cannot read property &#8216;range&#8217; of undefined</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/fixing-angular-unit-tests-cannot-read-property-range-of-undefined/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Angular Universal: Setting HTTP Status Code</title>
		<link>https://onthecode.co.uk/blog/angular-universal-setting-http-status-code</link>
					<comments>https://onthecode.co.uk/blog/angular-universal-setting-http-status-code#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Tue, 29 Nov 2022 23:17:51 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=5443</guid>

					<description><![CDATA[<p>Angular Universal gives superpowers to traditional Angular apps such as server-side rendering (SSR) and full features using Express.js server. This allows us to implement features like returning HTTP status codes in appropriate scenarios. In this post, I will show you how to set the HTTP status code from an Angular application with SSR. Background Let&#8217;s address why you might even want to set HTTP status code from an Angular component in the first place. As an example, my application renders the following component when it does not recognise a URL: When the component is rendered in the browser, the status code is actually 200 OK. Search engines would consider this response as valid and continue indexing the contents of this page. In this case, we should be returning the correct status code: 404 Not Found. Another possible scenario is returning status code 401 Unauhorised when securing pages from anonymous access. Inject response from Express.js Like any other server-side application, we need to modify the HTTP response to set the status code. To do this in Angular Universal, we can inject the Response object from Express.js server into the constructor of the component: Notice the dependency is optional since Angular Universal applications run on both the server and the browser. An optional parameter becomes null when the application is running in the browser. This means any usage of the response should be protected with a null guard. Setting the status code With the response available in the component, we can implement our logic inside the OnInit event. We can pass in the status code to the status method as shown below as per Response API docs. Since the response can be null in the browser context, we guard against null value to avoid our component from failing. Let&#8217;s now serve an SSR build locally to test the status code. Running the same scenario now yields 404 Not Found response in the browser. Full source code Putting it all together this is how the component looks like now: Unit tests It helps to put in unit test coverage around the features of the component to act as a safety net. Tests also help document our code. This is the full spec file containing the implementation details for all of the tests:</p>
<p>The post <a href="https://onthecode.co.uk/blog/angular-universal-setting-http-status-code">Angular Universal: Setting HTTP Status Code</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Angular Universal gives superpowers to traditional Angular apps such as server-side rendering (SSR) and full features using Express.js server. This allows us to implement features like returning HTTP status codes in appropriate scenarios. </p>



<p>In this post, I will show you how to set the HTTP status code from an Angular application with SSR.</p>



<h2 class="wp-block-heading">Background</h2>



<p>Let&#8217;s address why you might even want to set HTTP status code from an Angular component in the first place.</p>



<p>As an example, my application renders the following component when it does not recognise a URL:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-not-found-page'</span>,
  template: <span class="hljs-string">`
      &lt;h1&gt;Not Found&lt;/h1&gt;
      &lt;p&gt;This page does not exist.&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> NotFoundPageComponent {}</code></span></pre>


<p>When the component is rendered in the browser, the status code is actually <code>200 OK</code>. </p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img fetchpriority="high" decoding="async" src="https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-27-at-15.12.27-1024x654.png" alt="Not Found 200 OK" class="wp-image-5444" width="512" height="327" srcset="https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-27-at-15.12.27-1024x654.png 1024w, https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-27-at-15.12.27-300x192.png 300w, https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-27-at-15.12.27-768x491.png 768w, https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-27-at-15.12.27.png 1236w" sizes="(max-width: 512px) 100vw, 512px" /><figcaption>Not Found 200 OK</figcaption></figure></div>


<p>Search engines would consider this response as valid and continue indexing the contents of this page. </p>



<p>In this case, we should be returning the correct status code: <code>404 Not Found</code>.</p>



<p>Another possible scenario is returning status code <code>401 Unauhorised</code> when securing pages from anonymous access. </p>



<h2 class="wp-block-heading">Inject response from Express.js</h2>



<p>Like any other server-side application, we need to modify the HTTP response to set the status code.</p>



<p>To do this in Angular Universal, we can inject the <code>Response</code> object from Express.js server into the constructor of the component:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { Component, Inject, Optional } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { RESPONSE } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nguniversal/express-engine/tokens'</span>
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { Response } <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>
</span></span><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">'app-not-found-page'</span>,
</span></span><span class='shcb-loc'><span>  template: <span class="hljs-string">`</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">      &lt;h1&gt;Not Found&lt;/h1&gt;</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">      &lt;p&gt;This page does not exist.&lt;/p&gt;</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">  `</span>
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> NotFoundPageComponent {
</span></span><span class='shcb-loc'><span>  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>
</span></span><mark class='shcb-loc'><span><span class="hljs-params">    <span class="hljs-meta">@Optional</span>() <span class="hljs-meta">@Inject</span>(RESPONSE) <span class="hljs-keyword">private</span> response: Response</span>
</span></mark><span class='shcb-loc'><span><span class="hljs-params">  </span>) { }
</span></span><span class='shcb-loc'><span>}
</span></span></code></span></pre>


<p>Notice the dependency is optional since Angular Universal applications run on both the server and the browser.</p>



<p>An optional parameter becomes null when the application is running in the browser. This means any usage of the <code>response</code> should be protected with a null guard.</p>



<h2 class="wp-block-heading">Setting the status code</h2>



<p>With the response available in the component, we can implement our logic inside the <code>OnInit</code> event.</p>



<p>We can pass in the status code to the <code>status</code> method as shown below as per Response API <a href="https://expressjs.com/en/api.html#res.status" target="_blank" rel="noreferrer noopener">docs</a>. </p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> NotFoundPageComponent <span class="hljs-keyword">implements</span> OnInit {
</span></span><span class='shcb-loc'><span>  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>
</span></span><span class='shcb-loc'><span><span class="hljs-params">    <span class="hljs-meta">@Optional</span>() <span class="hljs-meta">@Inject</span>(RESPONSE) <span class="hljs-keyword">private</span> response: Response</span>
</span></span><span class='shcb-loc'><span><span class="hljs-params">  </span>) { }
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span>  ngOnInit() {
</span></span><span class='shcb-loc'><span>    <span class="hljs-comment">// Return 404 when running server side</span>
</span></span><span class='shcb-loc'><span>    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.response) {
</span></span><mark class='shcb-loc'><span>      <span class="hljs-keyword">this</span>.response.status(<span class="hljs-number">404</span>);
</span></mark><span class='shcb-loc'><span>    }
</span></span><span class='shcb-loc'><span>  }
</span></span><span class='shcb-loc'><span>}
</span></span></code></span></pre>


<p>Since the response can be null in the browser context, we guard against null value to avoid our component from failing.</p>



<p>Let&#8217;s now serve an SSR build locally to test the status code.</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">npm run build:ssr
npm run serve:ssr</code></span></pre>


<p>Running the same scenario now yields <code>404 Not Found</code> response in the browser.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" src="https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-29-at-22.52.12-1.png" alt="Not Found 404" class="wp-image-5456" width="506" height="393" srcset="https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-29-at-22.52.12-1.png 1012w, https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-29-at-22.52.12-1-300x233.png 300w, https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-29-at-22.52.12-1-768x596.png 768w" sizes="(max-width: 506px) 100vw, 506px" /><figcaption>Not Found 404</figcaption></figure></div>


<h2 class="wp-block-heading">Full source code</h2>



<p>Putting it all together this is how the component looks like now:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">import</span> { Component, Inject, OnInit, Optional } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { RESPONSE } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nguniversal/express-engine/tokens'</span>
<span class="hljs-keyword">import</span> { Response } <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>
<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-not-found-page'</span>,
  template: <span class="hljs-string">`
      &lt;h1&gt;Not Found&lt;/h1&gt;
      &lt;p&gt;This page does not exist.&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> NotFoundPageComponent <span class="hljs-keyword">implements</span> OnInit {

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">
    <span class="hljs-meta">@Optional</span>() <span class="hljs-meta">@Inject</span>(RESPONSE) <span class="hljs-keyword">private</span> response: Response
  </span>) { }

  ngOnInit() {
    <span class="hljs-comment">// Return 404 when running server side</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.response) {
      <span class="hljs-keyword">this</span>.response.status(<span class="hljs-number">404</span>);
    }
  }
}</code></span></pre>


<h2 class="wp-block-heading">Unit tests</h2>



<p>It helps to put in unit test coverage around the features of the component to act as a safety net. Tests also help document our code. </p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" src="https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-29-at-23.04.53.png" alt="" class="wp-image-5461" width="346" height="120" srcset="https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-29-at-23.04.53.png 692w, https://onthecode.co.uk/wp-content/uploads/2022/11/Screenshot-2022-11-29-at-23.04.53-300x104.png 300w" sizes="(max-width: 346px) 100vw, 346px" /></figure></div>


<p>This is the full <code>spec</code> file containing the implementation details for all of the tests:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">import</span> { ComponentFixture, TestBed } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core/testing'</span>;

<span class="hljs-keyword">import</span> { NotFoundPageComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'./not-found-page.component'</span>;
<span class="hljs-keyword">import</span> { RESPONSE } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nguniversal/express-engine/tokens'</span>;
<span class="hljs-keyword">import</span> { By } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser'</span>;

describe(<span class="hljs-string">'NotFoundPageComponent'</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
  <span class="hljs-keyword">let</span> component: NotFoundPageComponent;
  <span class="hljs-keyword">let</span> fixture: ComponentFixture&lt;NotFoundPageComponent&gt;;
  <span class="hljs-keyword">let</span> response: <span class="hljs-built_in">any</span>;

  describe(<span class="hljs-string">'client-side'</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    beforeEach(<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">await</span> TestBed.configureTestingModule({
        declarations: &#91;NotFoundPageComponent],
        providers: &#91;
          {
            provide: RESPONSE,
            useValue: <span class="hljs-literal">null</span>
          }
        ]
      })
        .compileComponents();

      fixture = TestBed.createComponent(NotFoundPageComponent);
      component = fixture.componentInstance;
      response = TestBed.inject(RESPONSE);
      fixture.detectChanges();
    });

    it(<span class="hljs-string">'should create'</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
      expect(component).toBeTruthy();
    });

    it(<span class="hljs-string">'should render elements'</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
      expect(fixture.debugElement.query(By.css(<span class="hljs-string">"h1"</span>)).nativeElement.textContent).toEqual(<span class="hljs-string">"Not Found"</span>);
      expect(fixture.debugElement.query(By.css(<span class="hljs-string">"p"</span>)).nativeElement.textContent).toEqual(<span class="hljs-string">"This page does not exist."</span>);
    });
  });

  describe(<span class="hljs-string">'server-side'</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    beforeEach(<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">await</span> TestBed.configureTestingModule({
        declarations: &#91;NotFoundPageComponent],
        providers: &#91;
          {
            provide: RESPONSE,
            useValue: jasmine.createSpyObj(<span class="hljs-string">"Response"</span>, &#91;<span class="hljs-string">"status"</span>])
          }
        ]
      })
        .compileComponents();

      fixture = TestBed.createComponent(NotFoundPageComponent);
      component = fixture.componentInstance;
      response = TestBed.inject(RESPONSE);
      fixture.detectChanges();
    });

    it(<span class="hljs-string">'should set 404 status code on response'</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
      expect(response.status).toHaveBeenCalledOnceWith(<span class="hljs-number">404</span>);
    });
  });

});
</code></span></pre><p>The post <a href="https://onthecode.co.uk/blog/angular-universal-setting-http-status-code">Angular Universal: Setting HTTP Status Code</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/angular-universal-setting-http-status-code/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Error: Cannot resolve type entity i3.DialogModule to symbol</title>
		<link>https://onthecode.co.uk/blog/error-cannot-resolve-type-entity-i3-dialogmodule-to-symbol</link>
					<comments>https://onthecode.co.uk/blog/error-cannot-resolve-type-entity-i3-dialogmodule-to-symbol#comments</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Sun, 11 Sep 2022 09:56:00 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=5226</guid>

					<description><![CDATA[<p>While updating my Angular Material Starter Template to Angular 14, I ran into an error causing broken builds. The console output seems to suggest this is a problem with Dialog module from Angular Component Dev Kit (CDK): Cannot resolve type entity i3.DialogModule to symbol. After hours of research online with no luck, it turns out I never had @angular/cdk as a dependency in the project. I found this out by checking the getting started section of Angular Material docs. How to fix Error: Cannot resolve type entity i3.DialogModule to symbol: Open up package.json file Add @angular/cdk to dependencies section: Run npm install to update download the new package It doesn&#8217;t matter where you put the new dependency, as long as it is within the dependencies block. One thing to watch out for is using the correct version &#8211; it must match the rest of the Angular packages. In the code snippet below, you can see I am using version ^14.2.1 because all other angular packages are on this version. I hope this post helped you solve this problem! It is really not clear to my why I didn&#8217;t have this error in Angular 13. After all, a missing dependency should break builds, right? Let me know in the comments, if you know why.</p>
<p>The post <a href="https://onthecode.co.uk/blog/error-cannot-resolve-type-entity-i3-dialogmodule-to-symbol">Error: Cannot resolve type entity i3.DialogModule to symbol</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>While updating my <a href="https://onthecode.co.uk/angular-material-starter-template-for-your-next-project/">Angular Material Starter Template</a> to Angular 14, I ran into an error causing broken builds. The console output seems to suggest this is a problem with <code>Dialog</code> module from Angular <a href="https://material.angular.io/cdk/categories" target="_blank" rel="noreferrer noopener">Component Dev Kit (CDK)</a>: Cannot resolve type entity i3.DialogModule to symbol.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript shcb-code-table"><span class='shcb-loc'><span>./src/polyfills.ts - <span class="hljs-built_in">Error</span>: Module build failed (<span class="hljs-keyword">from</span> ./node_modules/@ngtools/webpack/src/ivy/index.js):
</span></span><mark class='shcb-loc'><span><span class="hljs-built_in">Error</span>: Cannot resolve type entity i3.DialogModule to symbol
</span></mark><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-attr">Error</span>: node_modules/@angular/material/dialog/index.d.ts:<span class="hljs-number">3</span>:<span class="hljs-number">36</span> - error TS2307: Cannot find <span class="hljs-built_in">module</span> <span class="hljs-string">'@angular/cdk/dialog'</span> or its corresponding type declarations.
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-number">3</span> <span class="hljs-keyword">import</span> { CdkDialogContainer } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/cdk/dialog'</span>;
</span></span></code></span></pre>


<p>After hours of research online with no luck, it turns out I never had <code>@angular/cdk</code> as a dependency in the project. </p>



<p>I found this out by checking the getting started section of <a href="http://material.angular.io" target="_blank" rel="noreferrer noopener">Angular Material docs</a>.</p>



<p>How to fix <strong>Error: Cannot resolve type entity i3.DialogModule to symbol</strong>:</p>



<ol class="wp-block-list"><li>Open up <code>package.json</code> file </li><li>Add <code>@angular/cdk</code> to dependencies section:</li><li>Run <code>npm install</code> to update download the new package</li></ol>



<p>It doesn&#8217;t matter where you put the new dependency, as long as it is within the dependencies block. </p>



<p>One thing to watch out for is using the correct version &#8211; it must match the rest of the Angular packages. </p>



<p>In the code snippet below, you can see I am using version <code>^14.2.1</code> because all other angular packages are on this version. </p>


<pre class="wp-block-code"><span><code class="hljs language-javascript shcb-code-table"><span class='shcb-loc'><span>  ....
</span></span><span class='shcb-loc'><span>  <span class="hljs-string">"dependencies"</span>: {
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">"@angular/animations"</span>: <span class="hljs-string">"^14.2.1"</span>,
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">"@angular/common"</span>: <span class="hljs-string">"^14.2.1"</span>,
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">"@angular/compiler"</span>: <span class="hljs-string">"^14.2.1"</span>,
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">"@angular/core"</span>: <span class="hljs-string">"^14.2.1"</span>,
</span></span><mark class='shcb-loc'><span>    <span class="hljs-string">"@angular/cdk"</span>: <span class="hljs-string">"^14.2.1"</span>,
</span></mark><span class='shcb-loc'><span>    ...
</span></span><span class='shcb-loc'><span>  }
</span></span><span class='shcb-loc'><span>  ...
</span></span></code></span></pre>


<p>I hope this post helped you solve this problem!</p>



<p>It is really not clear to my why I didn&#8217;t have this error in Angular 13. After all, a missing dependency should break builds, right? Let me know in the comments, if you know why.</p>
<p>The post <a href="https://onthecode.co.uk/blog/error-cannot-resolve-type-entity-i3-dialogmodule-to-symbol">Error: Cannot resolve type entity i3.DialogModule to symbol</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/error-cannot-resolve-type-entity-i3-dialogmodule-to-symbol/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Using ng-deep in Angular</title>
		<link>https://onthecode.co.uk/blog/thoughts-on-ng-deep-in-angular</link>
					<comments>https://onthecode.co.uk/blog/thoughts-on-ng-deep-in-angular#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Fri, 26 Aug 2022 21:20:00 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=5164</guid>

					<description><![CDATA[<p>ng-deep is a special selector in Angular that you should use very carefully. I often come across ng-deep in code reviews, where I investigate further to see if it is really necessary. In this post, I will talk a little bit about ng-deep: what it does, where it is useful and also what alternative approaches we can use instead of ng-deep. What does ng-deep do? One of the great features of Angular is that components support view encapsulation. With view encapsulation, Angular creates a scope for every component at runtime so that the styles of a component don&#8217;t affect the rest of the application. While this protects logic from leaking to other components, it also makes it more difficult to style elements in child components. To overcome this issue, Angular introduced a special selector ng-deep. ng-deep selector completely disables the view encapsulation policy of a child component, leaking styles into components you don&#8217;t want to change. ng-deep example In the example below, the parent component is styling a button within the child component using ng-deep selector. So that&#8217;s what ng-deep looks like &#8211; it makes it easy to workaround the view encapsulation. Why you need to avoid ng-deep The main reason for avoiding ng-deep is because the selector has been deprecated for years. Angular also plans to drop support for ng-deep in a future release so your next Angular upgrade may be more difficult. Also, ng-deep can lead to unexpected outcomes. Since ng-deep pierces the view encapsulation policy, you might find your deep styles affect a component unintentionally. The only case you cannot avoid ng-deep Based purely on my experience, there is only one situation where you cannot avoid ng-deep. And that&#8217;s when you&#8217;re dealing with components from third party libraries like Bootstrap, Material etc. This is because you simply cannot change the third party component code, so you have to use ng-deep. Let me clarify an important point before we start, there is no true replacement to ng-deep. Alternative #1 &#8211; :host selector In situations where you want to apply styles directly to a child component (not its elements), :host selector can be used instead of ng-deep. :host selector targets the child component as a whole, instead of elements inside its template. Any style marked with :host in a child component can be overridden by a parent component without using ng-deep. This approach works well for simple scenarios where you want to modify the styles of the child component and not its elements. Alternative #2- CSS variables In more complex cases, where you need to apply styles to elements of Another alternative to ng-deep is to use CSS variables to share values between parent and child component. Angular view-encapsulation does not cover CSS variables so it is possible for the parent to define a variable like --text-colour and the child component can make use of it in its stylesheet file. This is especially useful for complex scenarios where you want the child component to be reusable. It is worth noting that major browsers have full support for CSS variables. This, of course, does not include IE. It is also possible to bind CSS variables in the HTML template of the parent component: The only limitation of this approach is that you need to modify the child component. This may be a problem if you&#8217;re trying to style a third party component.</p>
<p>The post <a href="https://onthecode.co.uk/blog/thoughts-on-ng-deep-in-angular">Using ng-deep in Angular</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>ng-deep is a special selector in <a href="https://onthecode.co.uk/category/angular" target="_blank" rel="noreferrer noopener">Angular</a> that you should use very carefully. I often come across ng-deep in code reviews, where I investigate further to see if it is really necessary. In this post, I will talk a little bit about ng-deep: what it does, where it is useful and also what alternative approaches we can use instead of ng-deep.</p>



<h2 class="wp-block-heading">What does ng-deep do?</h2>



<p>One of the great features of Angular is that components support <a href="https://angular.io/guide/view-encapsulation" target="_blank" rel="noreferrer noopener">view encapsulation</a>. </p>



<p>With view encapsulation, Angular creates a scope for every component at runtime so that the styles of a component don&#8217;t affect the rest of the application. </p>



<p>While this protects logic from leaking to other components, it also makes it more difficult to style elements in child components.</p>



<p>To overcome this issue, Angular introduced a special selector <code>ng-deep</code>. </p>



<p>ng-deep selector completely disables the view encapsulation policy of a child component, leaking styles into components you don&#8217;t want to change. </p>



<h2 class="wp-block-heading">ng-deep example</h2>



<p>In the example below, the parent component is styling a button within the child component using <code>ng-deep</code> selector. </p>


<pre class="wp-block-code"><span><code class="hljs language-javascript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/core"</span>;
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span>@Component({
</span></span><span class='shcb-loc'><span>  <span class="hljs-attr">selector</span>: <span class="hljs-string">"app-parent"</span>,
</span></span><span class='shcb-loc'><span>  <span class="hljs-attr">template</span>: <span class="hljs-string">`&lt;app-child&gt;&lt;/app-child&gt;`</span>,
</span></span><span class='shcb-loc'><span>  <span class="hljs-attr">styles</span>: &#91;
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">`</span>
</span></span><mark class='shcb-loc'><span><span class="hljs-string">      ::ng-deep .hello {</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">        color:red;</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">      }</span>
</span></mark><span class='shcb-loc'><span><span class="hljs-string">    `</span>
</span></span><span class='shcb-loc'><span>  ]
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ParentComponent</span> </span>{ }
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span>@Component({
</span></span><span class='shcb-loc'><span>  <span class="hljs-attr">selector</span>: <span class="hljs-string">"app-child"</span>,
</span></span><span class='shcb-loc'><span>  <span class="hljs-attr">template</span>: <span class="hljs-string">` &lt;button class="hello" (click)="sayHello()"&gt; Hello &lt;/button&gt; `</span>,
</span></span><span class='shcb-loc'><span>  <span class="hljs-attr">styles</span>: &#91;<span class="hljs-string">``</span>]
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ChildComponent</span> </span>{}
</span></span></code></span></pre>


<p>So that&#8217;s what ng-deep looks like &#8211; it makes it easy to workaround the view encapsulation.</p>



<h2 class="wp-block-heading">Why you need to avoid ng-deep</h2>



<p>The main reason for avoiding ng-deep is because the selector has been <a href="https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep" target="_blank" rel="noreferrer noopener">deprecated </a>for years.</p>



<p>Angular also plans to drop support for ng-deep in a future release so your next Angular upgrade may be more difficult.</p>



<p>Also, ng-deep can lead to unexpected outcomes. </p>



<p>Since ng-deep pierces the view encapsulation policy, you might find your deep styles affect a component unintentionally.</p>



<h2 class="wp-block-heading">The only case you cannot avoid ng-deep</h2>



<p>Based purely on my experience, there is only one situation where you cannot avoid ng-deep.</p>



<p>And that&#8217;s when you&#8217;re dealing with components from third party libraries like Bootstrap, Material etc.</p>



<p>This is because you simply cannot change the third party component code, so you have to use ng-deep.</p>



<p>Let me clarify an important point before we start, there is no true replacement to ng-deep.</p>



<h2 class="wp-block-heading">Alternative #1 &#8211; :host selector</h2>



<p>In situations where you want to apply styles directly to a child component (not its elements), <code>:host</code> selector can be used instead of ng-deep.</p>



<p><code>:host</code> selector targets the child component as a whole, instead of elements inside its template.</p>



<p>Any style marked with <code>:host</code> in a child component can be overridden by a parent component without using <code>ng-deep</code>.</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">"app-parent"</span>,
</span></span><span class='shcb-loc'><span>  template: <span class="hljs-string">`&lt;app-child&gt;&lt;/app-child&gt;`</span>,
</span></span><span class='shcb-loc'><span>  styles: &#91;
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">`</span>
</span></span><mark class='shcb-loc'><span><span class="hljs-string">      app-child {</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">        background-color:green;</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">      }</span>
</span></mark><span class='shcb-loc'><span><span class="hljs-string">    `</span>
</span></span><span class='shcb-loc'><span>  ]
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ParentComponent { }
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">"app-child"</span>,
</span></span><span class='shcb-loc'><span>  template: <span class="hljs-string">`</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">  &lt;button class="hello"&gt; Hello &lt;/button&gt;</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">  `</span>,
</span></span><span class='shcb-loc'><span>  styles: &#91;
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">`</span>
</span></span><mark class='shcb-loc'><span><span class="hljs-string">    :host {</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">      background-color:red;</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">      width:200px;</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">      height:200px;</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">      display: block;</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">    }</span>
</span></mark><span class='shcb-loc'><span><span class="hljs-string">    `</span>
</span></span><span class='shcb-loc'><span>  ]
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChildComponent {}
</span></span></code></span></pre>


<p>This approach works well for simple scenarios where you want to modify the styles of the child component and not its elements.</p>



<h2 class="wp-block-heading">Alternative #2- CSS variables</h2>



<p>In more complex cases, where you need to apply styles to elements of Another alternative to ng-deep is to use CSS variables to share values between parent and child component.</p>



<p>Angular view-encapsulation does not cover CSS variables so it is possible for the parent to define a variable like <code>--text-colour</code> and the child component can make use of it in its stylesheet file. </p>



<p>This is especially useful for complex scenarios where you want the child component to be reusable. </p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/core"</span>;
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">"app-parent"</span>,
</span></span><span class='shcb-loc'><span>  template: <span class="hljs-string">`&lt;app-child&gt;&lt;/app-child&gt;`</span>,
</span></span><span class='shcb-loc'><span>  styles: &#91;
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">`</span>
</span></span><mark class='shcb-loc'><span><span class="hljs-string">    app-child { /* declare variable for child */</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">      --text-colour: green;</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">    }</span>
</span></mark><span class='shcb-loc'><span><span class="hljs-string">    `</span>
</span></span><span class='shcb-loc'><span>  ]
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ParentComponent { }
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">"app-child"</span>,
</span></span><span class='shcb-loc'><span>  template: <span class="hljs-string">`</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">  &lt;button class="hello"&gt; Hello &lt;/button&gt;</span>
</span></span><span class='shcb-loc'><span><span class="hljs-string">  `</span>,
</span></span><span class='shcb-loc'><span>  styles: &#91;
</span></span><span class='shcb-loc'><span>    <span class="hljs-string">`</span>
</span></span><mark class='shcb-loc'><span><span class="hljs-string">    button { /* use variable from parent, or default value of 'red'*/</span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">      color: var(--text-colour, red); </span>
</span></mark><mark class='shcb-loc'><span><span class="hljs-string">    }</span>
</span></mark><span class='shcb-loc'><span><span class="hljs-string">    `</span>
</span></span><span class='shcb-loc'><span>  ]
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChildComponent {}
</span></span><span class='shcb-loc'><span>
</span></span></code></span></pre>


<p>It is worth noting that major browsers have full support for CSS variables. This, of course, does not include IE.</p>



<p>It is also possible to bind CSS variables in the HTML template of the parent component:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/core"</span>;
</span></span><span class='shcb-loc'><span>
</span></span><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">"app-parent"</span>,
</span></span><mark class='shcb-loc'><span>  template: <span class="hljs-string">`&lt;app-child &#91;style.--text-colour]="'green'"&gt;&lt;/app-child&gt;`</span>,
</span></mark><span class='shcb-loc'><span>  styles: &#91;<span class="hljs-string">` `</span>]
</span></span><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ParentComponent { }
</span></span><span class='shcb-loc'><span>
</span></span></code></span></pre>


<p>The only limitation of this approach is that you need to modify the child component. This may be a problem if you&#8217;re trying to style a third party component.</p>
<p>The post <a href="https://onthecode.co.uk/blog/thoughts-on-ng-deep-in-angular">Using ng-deep in Angular</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/thoughts-on-ng-deep-in-angular/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Making Styles Work with [innerHtml] in Angular</title>
		<link>https://onthecode.co.uk/blog/making-styles-work-with-innerhtml-in-angular</link>
					<comments>https://onthecode.co.uk/blog/making-styles-work-with-innerhtml-in-angular#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Tue, 21 Jun 2022 21:24:20 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=4696</guid>

					<description><![CDATA[<p>In this post, we&#8217;ll look at how we can apply styles to html content rendered via innerHtml attribute. By default, styles defined in an Angular component only work in that specific component. This is due to the Emulated view encapsulation policy set by Angular. This logical scope is great because styles of component A cannot affect component B. This is also the case where component B is a child of component A. Example In the following template, we want to apply styling the img tag in the html content. Unfortunately, the following CSS rule does not work because of the default view encapsulation policy. Emulated view encapsulation is preventing styles from intercepting inside and outside of the component. In this case, value bound to innerHtml attribute is considered outside of the component. This is because the value of content variable was not originally defined in your component HTML. There are a couple of ways you can work around this issue. Let&#8217;s check out each solution. Remove view encapsulation #1 workaround is to change the view encapsulation of the component to ViewEncapsulation.None Please note that changing ViewEncapsulation to None can have pretty far-reaching consequences. This applies your styles globally &#8211; so if you set something like a div tag to have a background color, this will change all divs in your app to have that background color. I would steer clear of changing the ViewEncapsulation unless you absolutely have to. Use ::ng-deep A better solution is to use ::ng-deep selector in each of your CSS rules. This styling above will now apply to images deep in this component. It is important to limit the use of ::ng-deep to only children of an encapsulated parent component. Otherwise, it would apply to all images in child components. Using the :host keyword before ::ng-deep takes care of this.</p>
<p>The post <a href="https://onthecode.co.uk/blog/making-styles-work-with-innerhtml-in-angular">Making Styles Work with [innerHtml] in Angular</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In this post, we&#8217;ll look at how we can apply styles to html content rendered via <code>innerHtml</code> attribute.</p>



<p>By default, styles defined in an Angular component only work in that specific component. This is due to the Emulated view encapsulation policy set by Angular. </p>



<p>This logical scope is great because styles of component A cannot affect component B. This is also the case where component B is a child of component A.</p>



<h2 class="wp-block-heading">Example</h2>



<p>In the following template, we want to apply styling the <code>img</code> tag in the html content.</p>


<pre class="wp-block-code"><span><code class="hljs language-xml">const content = '<span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">".."</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">".."</span>&gt;</span>'

<span class="hljs-comment">&lt;!-- Post page component html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> &#91;<span class="hljs-attr">innerHtml</span>]=<span class="hljs-string">"content"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></code></span></pre>


<p>Unfortunately, the following CSS rule does not work because of the default view encapsulation policy.</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-tag">img</span> {
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid red <span class="hljs-meta">!important</span>;
}</code></span></pre>


<p>Emulated view encapsulation is preventing styles from intercepting inside and outside of the component. </p>



<p>In this case, value bound to <code>innerHtml</code> attribute is considered outside of the component. This is because the value of <code>content</code> variable was not originally defined in your component HTML. </p>



<p>There are a couple of ways you can work around this issue. Let&#8217;s check out each solution.</p>



<h3 class="wp-block-heading">Remove view encapsulation</h3>



<p>#1 workaround is to change the view encapsulation of the component to <code>ViewEncapsulation.None</code></p>


<pre class="wp-block-code"><span><code class="hljs language-typescript shcb-code-table"><span class='shcb-loc'><span><span class="hljs-meta">@Component</span>({
</span></span><span class='shcb-loc'><span>  selector: <span class="hljs-string">'app-post-page'</span>,
</span></span><span class='shcb-loc'><span>  templateUrl: <span class="hljs-string">'./post-page.component.html'</span>,
</span></span><span class='shcb-loc'><span>  styleUrls: &#91;<span class="hljs-string">'./post-page.component.scss'</span>],
</span></span><mark class='shcb-loc'><span>  encapsulation: ViewEncapsulation.None
</span></mark><span class='shcb-loc'><span>})
</span></span><span class='shcb-loc'><span><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> PostPageComponent <span class="hljs-keyword">implements</span> OnInit {}
</span></span></code></span></pre>


<p>Please note that changing ViewEncapsulation to None can have pretty far-reaching consequences. </p>



<p>This applies your styles globally &#8211; so if you set something like a div tag to have a background color, this will change all divs in your app to have that background color. </p>



<p>I would steer clear of changing the ViewEncapsulation unless you absolutely have to.</p>



<h3 class="wp-block-heading">Use ::ng-deep</h3>



<p>A better solution is to use <code>::ng-deep</code> selector in each of your CSS rules.</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-pseudo">:host</span> <span class="hljs-selector-pseudo">::ng-deep</span> <span class="hljs-selector-tag">img</span> {
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid red <span class="hljs-meta">!important</span>;
}</code></span></pre>


<p>This styling above will now apply to images deep in this component.</p>



<p>It is important to limit the use of <code>::ng-deep</code> to only children of an encapsulated parent component. Otherwise, it would apply to all images in child components. </p>



<p>Using the <code>:host</code> keyword before <code>::ng-deep</code> takes care of this.</p>
<p>The post <a href="https://onthecode.co.uk/blog/making-styles-work-with-innerhtml-in-angular">Making Styles Work with [innerHtml] in Angular</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/making-styles-work-with-innerhtml-in-angular/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Queue Messages Sent to LiveAnnouncer</title>
		<link>https://onthecode.co.uk/blog/how-to-queue-messages-sent-to-liveannouncer</link>
					<comments>https://onthecode.co.uk/blog/how-to-queue-messages-sent-to-liveannouncer#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Sat, 20 Nov 2021 21:00:39 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=3392</guid>

					<description><![CDATA[<p>Angular provides LiveAnnouncer service to trigger screen reader announcements programmatically. It works well in simple scenarios but fails to queue messages when used concurrently. In this post, I will show you how to extend LiveAnnouncer to announce simultaneous messages. Problem demonstration There are many things to consider when it comes to building&#160;accessible&#160;web applications. One important consideration is visually impaired users – allowing them to interact by hearing where they cannot see. This includes announcing screen reader messages in a timely manner. The following example demonstrates how to use LiveAnnouncer service in Angular: While the above works fine, the problem surfaces when multiple components use announce method: LiveAnnouncer works by updating the text content of a single aria-live region within the HTML document object model. It always overwrites the text content when your code invokes announce. If notification service calls announce while a search is in progress and completes quickly, a visually impaired user would not hear You have a new message. This is not a great experience as the user would not know about the new message they have just received. Extending LiveAnnouncer Let&#8217;s create a singleton ScreenReaderService, which will internally use LiveAnnouncer. We need to delay each call to LiveAnnouncer using the setTimeout function. We also need to keep track of how many times our application wants to announce screen reader messages &#8211; with a counter. Extending each delay based on the counter creates a simple queue of announcements. Putting it all together: Waiting a varying period of time between each announcement allows screen reader software to read messages correctly. The following are some of the test cases that helped me come up with the solution above. I am using the fakeAsync zone to simulate the passage of time using the tick method. Now that we have a service for screen reader announcements, all we need to do is use it in our components. This is how I solved the problem of LiveAnnouncer not queueing messages! Are you considering accessibility when building your Angular applications? Share your thoughts in the comments below!</p>
<p>The post <a href="https://onthecode.co.uk/blog/how-to-queue-messages-sent-to-liveannouncer">How to Queue Messages Sent to LiveAnnouncer</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><a href="/blog/category/angular" target="_blank" rel="noreferrer noopener">Angular</a> provides LiveAnnouncer service to trigger screen reader announcements programmatically. It works well in simple scenarios but fails to queue messages when used concurrently. In this post, I will show you how to extend LiveAnnouncer to announce simultaneous messages.</p>



<h2 class="wp-block-heading" id="problem-demonstration">Problem demonstration</h2>



<p>There are many things to consider when it comes to building&nbsp;<a href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwiZ59iPm9n1AhULQEEAHZ0xBTcQFnoECAgQAQ&amp;url=https%3A%2F%2Fwww.w3.org%2FWAI%2Ffundamentals%2Faccessibility-intro%2F&amp;usg=AOvVaw0DZNZ1z8wYeGWe0bIstUQs" target="_blank" rel="noreferrer noopener">accessible</a>&nbsp;web applications. One important consideration is visually impaired users – allowing them to interact by hearing where they cannot see. This includes announcing screen reader messages in a timely manner.</p>



<p>The following example demonstrates how to use LiveAnnouncer service in Angular:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-meta">@Component</span>({...})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> MyComponent {

 <span class="hljs-keyword">constructor</span>(<span class="hljs-params">liveAnnouncer: LiveAnnouncer</span>) {
   liveAnnouncer.announce(<span class="hljs-string">"Hey Google"</span>);
 }
}</code></span></pre>


<p>While the above works fine, the problem surfaces when multiple components use <code>announce</code> method:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-comment">// Search component</span>
liveAnnouncer.announce(<span class="hljs-string">"Search in progress"</span>);

<span class="hljs-comment">// Notification component</span>
liveAnnouncer.announce(<span class="hljs-string">"You have a new message"</span>);

<span class="hljs-comment">// Search component</span>
liveAnnouncer.announce(<span class="hljs-string">"Search complete"</span>);</code></span></pre>


<p class="info-block">LiveAnnouncer works by updating the text content of a single <code>aria-live</code> region within the HTML document object model. It always overwrites the text content when your code invokes <code>announce</code>.  </p>



<p>If notification service calls <code>announce</code> while a search is in progress and completes quickly, a visually impaired user would not hear <em>You have a new message</em>. This is not a great experience as the user would not know about the new message they have just received.</p>



<h2 class="wp-block-heading" id="extending-liveannouncer">Extending LiveAnnouncer</h2>



<p>Let&#8217;s create a singleton <code>ScreenReaderService</code>, which will internally use LiveAnnouncer. </p>



<p>We need to delay each call to LiveAnnouncer using the <code>setTimeout</code> function. </p>



<p>We also need to keep track of how many times our application wants to announce screen reader messages &#8211; with a counter. Extending each delay based on the counter creates a simple queue of announcements. </p>



<p>Putting it all together:</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">import</span> { LiveAnnouncer } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/cdk/a11y"</span>;
<span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/core"</span>;
 
<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">"root"</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ScreenReaderService {
  <span class="hljs-keyword">private</span> counter = <span class="hljs-number">0</span>;
 
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> announcer: LiveAnnouncer</span>) { }
 
  announce(message: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">void</span> {
    setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
      <span class="hljs-keyword">this</span>.announcer.announce(message, <span class="hljs-string">"polite"</span>, <span class="hljs-number">200</span>);
      <span class="hljs-keyword">this</span>.counter--;
    }, <span class="hljs-number">300</span> * <span class="hljs-keyword">this</span>.counter);
 
    <span class="hljs-keyword">this</span>.counter++;
  }
}</code></span></pre>


<p>Waiting a varying period of time between each announcement allows screen reader software to read messages correctly.</p>



<p>The following are some of the test cases that helped me come up with the solution above. I am using the <code>fakeAsync</code> zone to simulate the passage of time using the <code>tick</code> method.</p>


<pre class="wp-block-code"><span><code class="hljs language-typescript"><span class="hljs-keyword">import</span> { LiveAnnouncer } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/cdk/a11y"</span>;
<span class="hljs-keyword">import</span> { discardPeriodicTasks, fakeAsync, flush, TestBed, tick } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/core/testing"</span>;
 
<span class="hljs-keyword">import</span> { ScreenReaderService } <span class="hljs-keyword">from</span> <span class="hljs-string">"./screen-reader.service"</span>;
 
describe(<span class="hljs-string">"ScreenReaderService"</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
  <span class="hljs-keyword">let</span> service: ScreenReaderService;
  <span class="hljs-keyword">let</span> announcer: <span class="hljs-built_in">any</span>;
 
  beforeEach(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    TestBed.configureTestingModule({
      providers: &#91;
        {
          provide: LiveAnnouncer,
          useValue: jasmine.createSpyObj(<span class="hljs-string">"LiveAnnouncer"</span>, &#91;<span class="hljs-string">"announce"</span>])
        }
      ]
    });
    service = TestBed.inject(ScreenReaderService);
    announcer = TestBed.inject(LiveAnnouncer);
  });
 
  it(<span class="hljs-string">"should be created"</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    expect(service).toBeTruthy();
  });
 
  it(<span class="hljs-string">"should announce message"</span>, fakeAsync(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    service.announce(<span class="hljs-string">"Page loaded"</span>);
    tick(<span class="hljs-number">0</span>);
    expect(announcer.announce).toHaveBeenCalledWith(<span class="hljs-string">"Page loaded"</span>, <span class="hljs-string">"polite"</span>, <span class="hljs-number">200</span>);
  }));
 
  it(<span class="hljs-string">"should announce two simultaneous messages correctly"</span>, fakeAsync(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    service.announce(<span class="hljs-string">"Page loaded"</span>);
    service.announce(<span class="hljs-string">"Content loaded"</span>);
    tick(<span class="hljs-number">300</span>);
    expect(announcer.announce).toHaveBeenCalledWith(<span class="hljs-string">"Page loaded"</span>, <span class="hljs-string">"polite"</span>, <span class="hljs-number">200</span>);
    tick(<span class="hljs-number">300</span>);
    expect(announcer.announce).toHaveBeenCalledWith(<span class="hljs-string">"Content loaded"</span>, <span class="hljs-string">"polite"</span>, <span class="hljs-number">200</span>);
  }));
 
  it(<span class="hljs-string">"should announce three simultaneous messages correctly"</span>, fakeAsync(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    service.announce(<span class="hljs-string">"Page loaded"</span>);
    service.announce(<span class="hljs-string">"Content loaded"</span>);
    service.announce(<span class="hljs-string">"Footer loaded"</span>);
    tick(<span class="hljs-number">300</span>);
    expect(announcer.announce).toHaveBeenCalledWith(<span class="hljs-string">"Page loaded"</span>, <span class="hljs-string">"polite"</span>, <span class="hljs-number">200</span>);
    tick(<span class="hljs-number">300</span>);
    expect(announcer.announce).toHaveBeenCalledWith(<span class="hljs-string">"Content loaded"</span>, <span class="hljs-string">"polite"</span>, <span class="hljs-number">200</span>);
    tick(<span class="hljs-number">300</span>);
    expect(announcer.announce).toHaveBeenCalledWith(<span class="hljs-string">"Footer loaded"</span>, <span class="hljs-string">"polite"</span>, <span class="hljs-number">200</span>);
  }));
});</code></span></pre>


<p>Now that we have a service for screen reader announcements, all we need to do is use it in our components.</p>



<p>This is how I solved the problem of LiveAnnouncer not queueing messages!</p>



<p>Are you considering accessibility when building your Angular applications? Share your thoughts in the comments below!</p>
<p>The post <a href="https://onthecode.co.uk/blog/how-to-queue-messages-sent-to-liveannouncer">How to Queue Messages Sent to LiveAnnouncer</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/how-to-queue-messages-sent-to-liveannouncer/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>5 Angular CLI Tips You Should Know</title>
		<link>https://onthecode.co.uk/blog/5-angular-cli-tips-you-should-know</link>
					<comments>https://onthecode.co.uk/blog/5-angular-cli-tips-you-should-know#respond</comments>
		
		<dc:creator><![CDATA[Umut Esen]]></dc:creator>
		<pubDate>Wed, 23 Sep 2020 22:43:31 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<guid isPermaLink="false">https://onthecode.co.uk/?p=3043</guid>

					<description><![CDATA[<p>As Angular developers, we often interact with the command-line interface (CLI) to scaffold components and manage packages. It is very important to master the CLI to make sure your development flow is smooth. Having developed several Angular applications myself, I have come to realise the 5 tips below. Shorten commands The official getting started guide tells you to use the full names of commands, such as: While this is great for beginners, it is also possible to achieve the same output by using the initials of commands. You can shorten various commands as shown in examples below: Dry run flag It is often useful to know what effect executing a certain command will have on your workspace. You can use the CLI flag --dryRun to see the effects of a command without making any changes: Enable routing and Sass for new projects The CLI can easily scaffold a new application using the new command. Unless you plan on keeping your newly created project for demonstration purposes, you should enable routing and Sass support. As you&#8217;d expect, this will scaffold a new application called HelloWorld. Since we used the routing flag, a new file called app-routing.module.ts&#160;will appear under src\app. This is for your convenience to start adding routes to your application. It even registers the routing module with AppModule so you can get going right away. It is worth noting this flag also works when generating modules. The command also creates a styles.scss in your project, instead of the usual style.css. Since we enabled Sass support, all newly generated components will also have a corresponding *.scss file. Combine commands You can combine multiple Angular CLI commands, for example: This command generates a new feature module with routing support. It also registers the feature module as a lazy-loaded module in app.module. It is amazing how all of the above can be achieved just by using a single command. Strict mode (v10) Angular promotes best practices and consistency since the early days of development. With the adoption of Typescript, we have had compile-time checks that allowed us to prevent issues as early as possible. With the recent release of Angular v10, we now have optional strict mode in CLI. The strict mode lets us perform more build-time optimisations and deliver faster apps with fewer issues. In order to opt into the strict mode, you need to use the strict flag: This command generates a new project with the following settings: Strict mode in TypeScript, as well as other strictness flags recommended by the TypeScript team. Specifically,&#160;strict,&#160;forceConsistentCasingInFileNames,&#160;noImplicitReturns,&#160;noFallthroughCasesInSwitch Turns on strict Angular compiler flags&#160;strictTemplates&#160;and&#160;strictInjectionParameters Reduced bundle size budgets by ~75% Turns on&#160;no-any&#160;TSLint rule to prevent declarations of type&#160;any Marks your application as&#160;side-effect free&#160;to enable more advanced tree-shaking So there you have it, these are my favourite Angular CLI tips! What is your favourite CLI feature? Let me know by dropping a comment below.</p>
<p>The post <a href="https://onthecode.co.uk/blog/5-angular-cli-tips-you-should-know">5 Angular CLI Tips You Should Know</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>As <a href="/blog/category/angular">Angular</a> developers, we often interact with the command-line interface (CLI) to scaffold components and manage packages. It is very important to master the CLI to make sure your development flow is smooth.</p>



<p>Having developed several Angular applications myself, I have come to realise the 5 tips below.</p>






<h2 class="wp-block-heading">Shorten commands</h2>



<p>The official getting started guide tells you to use the full names of commands, such as:</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">ng generate component MyComponent</code></span></pre>


<p>While this is great for beginners, it is also possible to achieve the same output by using the initials of commands.</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">ng g c MyComponent</code></span></pre>


<p>You can shorten various commands as shown in examples below:</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">ng generate module MyModule ====&gt; ng g m MyModule
ng generate pipe MyPipe ====&gt; ng g p MyPipe
ng generate service MyService ====&gt; ng g s MyService</code></span></pre>


<h2 class="wp-block-heading">Dry run flag</h2>



<p>It is often useful to know what effect executing a certain command will have on your workspace. You can use the CLI flag <code>--dryRun</code> to see the effects of a command without making any changes:</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">hello-world % ng generate component Home --dryRun
CREATE src/app/home/home.component.css (0 bytes)
CREATE src/app/home/home.component.html (19 bytes)
CREATE src/app/home/home.component.spec.ts (614 bytes)
CREATE src/app/home/home.component.ts (261 bytes)
UPDATE src/app/app.module.ts (931 bytes)
NOTE: The <span class="hljs-string">"dryRun"</span> flag means no changes were made.</code></span></pre>


<h2 class="wp-block-heading">Enable routing and Sass for new projects</h2>



<p>The CLI can easily scaffold a new application using the <code>new</code> command. Unless you plan on keeping your newly created project for demonstration purposes, you should enable routing and Sass support.  </p>


<pre class="wp-block-code"><span><code class="hljs language-bash">ng new HelloWorld --routing --style=scss</code></span></pre>


<p>As you&#8217;d expect, this will scaffold a new application called <code>HelloWorld</code>. </p>



<p>Since we used the routing flag, a new file called <code>app-routing.module.ts&nbsp;</code>will appear under <code>src\app</code>. This is for your convenience to start adding routes to your application. It even registers the routing module with <code>AppModule</code> so you can get going right away. It is worth noting this flag also works when generating modules.</p>



<p>The command also creates a <code>styles.scss</code> in your project, instead of the usual <code>style.css</code>. Since we enabled Sass support, all newly generated components will also have a corresponding <code>*.scss</code> file. </p>



<h2 class="wp-block-heading">Combine commands</h2>



<p>You can combine multiple Angular CLI commands, for example:</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">ng g m feature --route feature --module app.module</code></span></pre>


<p>This command generates a new feature module with routing support. It also registers the feature module as a lazy-loaded module in app.module.</p>



<p>It is amazing how all of the above can be achieved just by using a single command. </p>



<h2 class="wp-block-heading">Strict mode (v10)</h2>



<p>Angular promotes best practices and consistency since the early days of development. With the adoption of Typescript, we have had compile-time checks that allowed us to prevent issues as early as possible.</p>



<p>With the recent release of Angular v10, we now have optional strict mode in CLI. The strict mode lets us perform more build-time optimisations and deliver faster apps with fewer issues. In order to opt into the strict mode, you need to use the <code>strict</code> flag:</p>


<pre class="wp-block-code"><span><code class="hljs language-bash">ng new HelloWorld --strict</code></span></pre>


<p>This command generates a new project with the following settings:</p>



<ul class="wp-block-list"><li>Strict mode in TypeScript, as well as other strictness flags recommended by the TypeScript team. Specifically,&nbsp;<code>strict</code>,&nbsp;<code>forceConsistentCasingInFileNames</code>,&nbsp;<code>noImplicitReturns</code>,&nbsp;<code>noFallthroughCasesInSwitch</code></li><li>Turns on strict Angular compiler flags&nbsp;<code>strictTemplates</code>&nbsp;and&nbsp;<code>strictInjectionParameters</code></li><li>Reduced bundle size budgets by ~75%</li><li>Turns on&nbsp;<code>no-any</code>&nbsp;TSLint rule to prevent declarations of type&nbsp;<code>any</code></li><li>Marks your application as&nbsp;<a href="https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free">side-effect free</a>&nbsp;to enable more advanced tree-shaking</li></ul>



<p>So there you have it, these are my favourite Angular CLI tips! What is your favourite CLI feature? Let me know by dropping a comment below.</p>
<p>The post <a href="https://onthecode.co.uk/blog/5-angular-cli-tips-you-should-know">5 Angular CLI Tips You Should Know</a> appeared first on <a href="https://onthecode.co.uk">onthecode</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://onthecode.co.uk/blog/5-angular-cli-tips-you-should-know/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
