<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Santosh Yadav on Medium]]></title>
        <description><![CDATA[Stories by Santosh Yadav on Medium]]></description>
        <link>https://medium.com/@santosh.yadav198613?source=rss-c0dd31a08f42------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*Cm2ssulEP5ecprnzoDRSMQ.jpeg</url>
            <title>Stories by Santosh Yadav on Medium</title>
            <link>https://medium.com/@santosh.yadav198613?source=rss-c0dd31a08f42------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 25 May 2026 22:23:40 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@santosh.yadav198613/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Angular: The Framework of Past, Present, and Future]]></title>
            <link>https://medium.com/@santosh.yadav198613/angular-the-framework-of-past-present-and-future-f9da5ed36763?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/f9da5ed36763</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[webdev]]></category>
            <category><![CDATA[angular]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Thu, 13 Apr 2023 20:26:12 GMT</pubDate>
            <atom:updated>2023-04-13T20:26:12.240Z</atom:updated>
            <content:encoded><![CDATA[<p>Photo by <a href="https://unsplash.com/ja/@dbeamer_jpg?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Drew Beamer</a> on <a href="https://unsplash.com/photos/xU5Mqq0Chck?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p><p>I started using Angular in 2017 when version 4 was released. And I have seen this framework growing since then. In this blog, let’s see why Angular is a framework of Past, Present, and Future.</p><h3>AngularJS and the Start of Angular</h3><p>AngularJS was released in 2010 and was one of Google’s first Open Source front-end frameworks. It was open-sourced and lived for 12 years before reaching the end of life in 2022.</p><p>AngularJS introduced a new way to write the html templates. It introduced directives like “ng-for, ng-if,” which paved the way for many other frameworks and rendering engines.</p><p>The AngularJS team quickly realized it’s difficult to maintain a vast codebase written in JavaScript. And a rewrite of AngularJS called Angular was announced in 2014.</p><h3>Choosing the best tool for the job</h3><p>Angular is known for deep diving into the existing tools before picking the best for the job. Let’s see the tools chosen by the Angular team over the years.</p><h4>Past</h4><p>When Angular development started, Angular Team decided to use <strong>Typescript</strong>, which was very new in 2014, and many didn’t like it. Some chose not to use it and moved to another framework where they could use Javascript.</p><p>But everyone has realized the true power of Typescript over the years, and most developers now choose and prefer Typescript over Javascript.</p><p>2014 was the time many build tools for Javascript started appearing. I remember using Grunt and Gulp. Even when the early version of Angular appeared (2.0), SystemJS was used, and developers had to configure everything independently. With Angular 4.0 Angular team introduced <strong>Webpack</strong> and <strong>CLI</strong>, and all the configuration was hidden from the developers. Webpack served as the best and most stable tool over the years. It became a tool trusted by many other frameworks and developers.</p><p>There was a time the Angular team considered introducing <strong>Bazel</strong> as the build tool. Bazel is a great tool, but introducing it might have complicated the development effort, as it is hard to understand. The angular team decided not to take that path.</p><h4><strong>Present</strong></h4><p>Angular still uses <strong>Webpack</strong> and has experimental support for <strong>esbuild</strong>. The team realized its time to move on and chose other tools better than Webpack.</p><p><strong>CLI</strong> has improved over the years, enabling smooth migrations between Angular versions. Check out <a href="https://update.angular.io/">https://update.angular.io/</a></p><h4>Future</h4><p>After considering many build tools, Angular will invest in <strong>esbuild</strong>, which will be used for building Angular applications.</p><p>But <strong>vite</strong> is the hottest tool now; you said, yes team decided not to use it as it was not the best fit for building Angular applications. Still, it will serve applications using <strong>vite</strong> when you are doing the dev build.</p><h3>Rendering Engines</h3><p>Angular uses a compiler to build and produce the final build output, which generally goes through multiple tools. One of them is the rendering engine; the Angular team has iterated over the rendering engines numerous times, and Ivy is the current generation which has unblocked the Angular team to introduce great features like the Standalone component.</p><h3>Focus on Reactivity</h3><h4>Past</h4><p>Angular wanted developers to write more reactive code from Day 1 and chose the best tool present <strong>RxJs</strong>. For APIs like <strong>HTTP</strong> and <strong>Router</strong>, Angular used RxJs internally; even for EventEmitter RxJs Subject was used.</p><h4>Present</h4><p>RxJs usage has grown over the years, and more and more developers are using this powerful library. Still, many developers asked for Angular without RxJs. Many want better integration of Angular with RxJs.</p><h4>Future</h4><p>The angular team is experimenting with Signals, and there will be a public RFC soon. Signals will reduce the learning curve, which was required for RxJs. Still, it will also introduce APIs to better integrate with RxJs.</p><h3>Change Detection</h3><h4>Past</h4><p>Change Detection has always been a very critical part of any framework. The angular team introduced zone.js very early to take care of change detection.</p><h4>Present</h4><p>Angular still uses zone.js, but soon it started giving performance issues for large apps, and developers had to figure out how to improve the performance. OnPush change detection strategy is widely used to improve performance. Libraries like RxAngular allow you to disable zone.js but need some refactoring.</p><h4>Future</h4><p>We, developers, should focus on writing more quality code rather than caring about change detection. Yes, this is the policy the Angular team has decided to go with. With the introduction of Signals, zone.js will become optional, and you can care less about Change Detection strategies.</p><h3>Do not leave anyone behind policy.</h3><p>Angular has a release cycle of 6 months, which means there will be a new major release every 6 months. And the version has support for the next 18 months, which means if you have been on an Angular version for more than 18 months, chances are the version is not supported anymore.</p><p>But Angular has your back. For any new version release, Angular CLI offers an automatic migration. You need to run ng update and relax.</p><p>You can read the <a href="https://update.angular.io/">docs</a> to update Angular between multiple versions</p><pre>ng update</pre><p>Enter fullscreen mode Exit fullscreen mode</p><h3>Great Set of features</h3><p>Over the years, the Angular team has interacted more with the community and worked on some excellent features.</p><h4>inject function</h4><p>One of the most loved features of Angular is DI (Dependency Injection). We all love it. With inject, function Angular team made the developer experience even better.</p><p>Let’s see an example before and after:</p><pre>@Component({<br>  selector: &#39;app-employee-details&#39;,<br>  templateUrl: &#39;./employee-details.component.html&#39;,<br>  styleUrls: [&#39;./employee-details.component.scss&#39;],<br>})<br>export class EmployeeDetailsComponent {<br><br>  modes$ = this.route.queryParamMap.pipe(<br>    map((params: ParamMap) =&gt; params.get(&#39;mode&#39;))<br>  );<br>  userName$ = this.route.paramMap.pipe(<br>    map((params: ParamMap) =&gt; params.get(&#39;username&#39;))<br>  );<br><br>  employeeId$ = this.route.paramMap<br>    .pipe(<br>      map((params: ParamMap) =&gt; params.get(&#39;employeeId&#39;))<br>    );<br>  constructor(private route: ActivatedRoute) { }<br><br>}</pre><p>Enter fullscreen mode Exit fullscreen mode</p><p>With inject function</p><pre>@Component({<br>  selector: &#39;app-employee-details&#39;,<br>  templateUrl: &#39;./employee-details.component.html&#39;,<br>  styleUrls: [&#39;./employee-details.component.scss&#39;],<br>})<br>export class EmployeeDetailsComponent {<br>  modes$ = inject(ActivatedRoute).queryParamMap.pipe(<br>    map((params: ParamMap) =&gt; params.get(&#39;mode&#39;))<br>  );<br>  userName$ = inject(ActivatedRoute).paramMap.pipe(<br>    map((params: ParamMap) =&gt; params.get(&#39;username&#39;))<br>  );<br><br>  employeeId$ = inject(ActivatedRoute).paramMap.pipe(<br>    map((params: ParamMap) =&gt; params.get(&#39;employeeId&#39;))<br>  );<br>  constructor() {}<br>}</pre><p>Enter fullscreen mode Exit fullscreen mode</p><p>Template:</p><pre>&lt;h1&gt;<br>   Employee Details for EmployeeId: {{employeeId$ | async}}<br>&lt;/h1&gt;<br><br>&lt;h2&gt;Current Mode: {{ modes$ | async }} &lt;/h2&gt;</pre><p>Enter fullscreen mode Exit fullscreen mode</p><h4>Standalone components</h4><p>The angular community has been asking Angular Module less Angular for a long time. I still love Angular Modules, it still has their place when structuring your apps, but we can usually work without them. Not having Angular Modules reduces the mental modal and learning curve. So now we have Standalone Components, Standalone Component does not require to be registered with any Angular Modules, and it still has backward compatibility, meaning you can use them in an Angular Module.</p><pre>import { Component, OnInit } from &#39;@angular/core&#39;;<br>import { MatTableModule } from &#39;@angular/material/table&#39;;<br>import { MatPaginatorModule } from &#39;@angular/material/paginator&#39;;<br>import { MatSortModule } from &#39;@angular/material/sort&#39;;<br><br>@Component({<br>  selector: &#39;app-user&#39;,<br>  templateUrl: &#39;./user.component.html&#39;,<br>  styleUrls: [&#39;./user.component.scss&#39;],<br>  standalone: true, // Standalone flag to differentiate between component with module<br>  imports:[<br>    MatTableModule,<br>    MatPaginatorModule,<br>    MatSortModule<br>  ] // you can import Angular Module, Standalone Component/Directive/Pipe here<br>})<br>export class UserComponent implements OnInit{<br><br>  constructor() {<br>  }<br><br>}</pre><p>Enter fullscreen mode Exit fullscreen mode</p><h4>Standalone APIs</h4><p>To take the Standalone Component experience to the next level, Angular introduced Standalone APIs, its already available for Router and HttpClient, and even libraries like NgRx also introduced the Standalone APIs.</p><p>Let’s see the code sample below to use Standalone APIs for Http and Router</p><pre>providers: [<br>    provideHttpClient(),<br>       provideRouter(<br>      routes,<br>      withDebugTracing(),<br>      withEnabledBlockingInitialNavigation() //required for SSR<br>      withHashLocation(),<br>      withPreloading( PreloadAllModules),<br>      withRouterConfig({<br>        onSameUrlNavigation: &#39;reload&#39;,<br>      })<br>    ),<br>]</pre><p>Enter fullscreen mode Exit fullscreen mode</p><h4>Standalone Component Migration</h4><p>Of course, we now have Standalone Components but think about the effort you and your team have to go through to convert all components to Standalone, dont worry; the Angular teams have your back, run the below command and migrate all components, directives, and pipes to Standalone, Happy migration.</p><pre>ng generate @angular/core:standalone</pre><p>Enter fullscreen mode Exit fullscreen mode</p><h4>functional guards</h4><p>Router guards are great, but we had to write a service every time we had to write a guard. It all changed with the introduction of the functional guard. Guards can be a function now. No need to write a class anymore.</p><pre>const authGuard: CanMatchFn = () =&gt; {<br>  const authService = inject(LoginService);<br>  const router = inject(Router);<br><br>  if (authService.isLoggedIn) {<br>    return true;<br>  }<br><br>  return router.parseUrl(&#39;/login&#39;);<br>};</pre><p>Enter fullscreen mode Exit fullscreen mode</p><h4>New Image Directive</h4><p>It’s 2023, and images are among the most critical reasons for bad LCP(Largest Conentful Page). You dont need to care about this anymore with the introduction of the NgOptimizedImage directive.</p><h3>Listening to Community</h3><h4>Optional ZoneJS</h4><p>If you are an Angular developer, you know what zone.js is. It is responsible for all the magic in Angular around change detection.</p><p>But it starts giving performance hits in large enterprise applications, and enterprise is where Angular shines.</p><p>Finally, we will have an optional zone for our Applications. Signals are coming to Angular, and it will make zone.js optional, and a good thing it’s backward compatible. It means you can still have an existing app with zone.js and run these new components, which are signals side by side. There are ways to disable zone.js, but it’s not very straightforward.</p><p>In the below sample signals: true property will land soon, but not available with 16.0.0-next.7 version</p><pre>import { Component, signal } from &#39;@angular/core&#39;;<br>import { CommonModule } from &#39;@angular/common&#39;;<br><br>@Component({<br>  selector: &#39;app-counter&#39;,<br>  standalone: true,<br>  signals: true, // you can still try this code by commenting this line<br>  imports: [CommonModule],<br>  templateUrl: &#39;./counter.component.html&#39;,<br>  styleUrls: [&#39;./counter.component.scss&#39;]<br>})<br>export default class CounterComponent {<br>  count = signal(0);<br><br>  increment() {<br>    this.count.update(n =&gt; n + 1);<br>  }<br><br>}</pre><p>Enter fullscreen mode Exit fullscreen mode</p><pre>&lt;p&gt;counter works!&lt;/p&gt;<br>{{ count() }}<br><br>&lt;button (click)=&quot;increment()&quot;&gt;Increment&lt;/button&gt;</pre><p>Enter fullscreen mode Exit fullscreen mode</p><p>But Signals will bring more than just optional zone.js. you can read more on the RFC</p><p><a href="https://github.com/angular/angular/discussions/49685">https://github.com/angular/angular/discussions/49685</a></p><ul><li><a href="https://github.com/angular/angular/discussions/49685">[Complete] RFC: Angular Signals🚦 · angular angular · Discussion #49685</a></li><li><a href="https://github.com/angular/angular/discussions/49684">[Complete] Sub-RFC 1: Signals for Angular Reactivity · angular angular · Discussion #49684</a></li><li><a href="https://github.com/angular/angular/discussions/49682">[Complete] Sub-RFC 3: Signal-based Components · angular angular · Discussion #49682</a></li><li><a href="https://github.com/angular/angular/discussions/49683">[Complete] Sub-RFC 2: Signal APIs · angular angular · Discussion #49683</a></li><li><a href="https://github.com/angular/angular/discussions/49681">[Complete] Sub-RFC 4: Observable and Signal Interoperability · angular angular · Discussion #49681</a></li></ul><p>SSR in Angular has many issues today. SSR in Angular is less famous than other React or Vue-based SSR frameworks. The Angular team has started improving the SSR experience and released the first feature.</p><figure><img alt="unknown tweet media content" src="https://cdn-images-1.medium.com/max/800/0*n_8Bj6lShlej_5Ml.jpg" /></figure><figure><img alt="Minko Gechev profile image" src="https://cdn-images-1.medium.com/max/48/0*VWsU5VvUZbjMCyfm.jpg" /></figure><blockquote>Minko Gechev</blockquote><blockquote><a href="https://dev.to/mgechev">@mgechev</a></blockquote><blockquote>We just landed hydration in Angular! You can try it in the prerelease of v16 on Wednesday 🔥<br><br>- No flicker due to rerendering when using SSR<br>- Better Core Web Vitals. 45% improvement in LCP based on early testing<br><br><a href="https://t.co/pFSlEWAj2d">github.com/angular/angula…</a></blockquote><blockquote>18:49 PM — 04 Apr 2023</blockquote><h4>Typed Forms</h4><p>Angular has types of forms ReactiveForms and Template Driven forms. The community wanted forms to be typed for a long time, and it finally landed in Angular 14.</p><p>Yes, you can create typed forms now, and chances are you are already using them.</p><pre>form: FormGroup = this.fb.group({<br>    name: new FormControl&lt;string&gt;(&#39;&#39;),<br>    salary: new FormControl&lt;number&gt;(0),<br>    age: new FormControl&lt;number&gt;(0),<br>    dob: new FormControl&lt;Date&gt;(new Date()),<br>  });<br>constructor(private fb: FormBuilder) {}</pre><p>Enter fullscreen mode Exit fullscreen mode</p><h3>Conclusion</h3><p>I tried to summarize all the fantastic things Angular is going to bring to you as a developer. I am looking at a great future investing in Angular as I did six years ago when I picked up Angular and transitioned from a .Net developer to Angular Developer.</p><p>Investing my time in learning and supporting the Angular framework was worth it in the Past, which is still rocking in the present, and I am sure with features like Signals, it will keep shining in the future.</p><p>This article is published w/ <a href="https://scattr.io?ref=medium">Scattr ↗️</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9da5ed36763" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My Course on Angular Getting Started]]></title>
            <link>https://medium.com/@santosh.yadav198613/my-course-on-angular-getting-started-8ed65e316a45?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/8ed65e316a45</guid>
            <category><![CDATA[learning]]></category>
            <category><![CDATA[course]]></category>
            <category><![CDATA[webdev]]></category>
            <category><![CDATA[angular]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Sat, 11 Mar 2023 21:38:20 GMT</pubDate>
            <atom:updated>2023-03-11T21:38:20.354Z</atom:updated>
            <content:encoded><![CDATA[<p>Photo by <a href="https://unsplash.com/@nickmorrison?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Nick Morrison</a> on <a href="https://unsplash.com/s/photos/course?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p><p>I had planned an Angular Course for the community for a very long time, last year I even decided to stream it. But all efforts were unsuccessful.</p><p>There was too much in my plate, I decided to move to a new country, which caused lot of changes in my plan.</p><h4>New Plan</h4><p>I decided to publish it around May again, but due to other factors and depression. I decided to put it on hold again. The plan was to publish it as paid course, but with pay what you want model.</p><h4>Finally Publishing It</h4><p>I decided to leave my job in the mid July, which gave me some free time. I decided to utilize this free time and publish the course.</p><h4>Why this course is Free</h4><p>Lot of people may have this question why free, when I had decided to make it paid.</p><p>There is one reason — <strong>community</strong>, Last 7 months were really rough for me, staying away from your loved ones is hard, specially when they are stuck in different country and you can not visit them.</p><p>During this time, I got so much support from community, I decided to do something in return.</p><p>This is my small way to say think you for everything you all have done for me.</p><h4>Where to get this course</h4><p>You can access it on YouTube</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F3qBXWUpoPHo%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D3qBXWUpoPHo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F3qBXWUpoPHo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/dd9e0edfda497fbafbe515886e9d1a73/href">https://medium.com/media/dd9e0edfda497fbafbe515886e9d1a73/href</a></iframe><h4>What if you want to pay</h4><p>This course will remain free forever, but if you decide to support my work, so I can invest more time creating content for community, you can use GitHub Sponsors link below:</p><p><a href="https://github.com/sponsors/santoshyadavdev">Sponsor @santoshyadavdev on GitHub Sponsors</a></p><p>Finally thanks to some amazing folks for sponsoring me:</p><ul><li>Chau Tran — <a href="https://twitter.com/Nartc1410">https://twitter.com/Nartc1410</a></li><li>Anand Chowdhary — <a href="https://twitter.com/AnandChowdhary">https://twitter.com/AnandChowdhary</a></li><li>Sunil — <a href="https://twitter.com/sunil_designer">https://twitter.com/sunil_designer</a></li><li>Trung Vo — <a href="https://twitter.com/tuantrungvo">https://twitter.com/tuantrungvo</a></li><li>Umair Hafeez — <a href="https://twitter.com/_UmairHafeez_">https://twitter.com/_UmairHafeez_</a></li><li>Pavan Kumar Jadda — <a href="https://twitter.com/pavankjadda">https://twitter.com/pavankjadda</a></li><li>Pabio — <a href="https://twitter.com/PabioHQ">https://twitter.com/PabioHQ</a></li><li>Maarten Tibau — <a href="https://twitter.com/maartentibau">https://twitter.com/maartentibau</a></li></ul><p>This article is published w/ <a href="https://scattr.io?ref=medium">Scattr ↗️</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8ed65e316a45" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How we built This is Learning Community]]></title>
            <link>https://medium.com/@santosh.yadav198613/how-we-built-this-is-learning-community-bc7ba44af5fb?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/bc7ba44af5fb</guid>
            <category><![CDATA[community]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Sat, 11 Mar 2023 21:01:19 GMT</pubDate>
            <atom:updated>2023-03-11T21:06:44.771Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BD4g_u8l06XREkbvGwf35g.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@claybanks?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Clay Banks</a> on <a href="https://unsplash.com/photos/LjqARJaJotc?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>This is Learning was started in 2020 by <a href="https://dev.to/layzee">@layzee</a>. I presented how we built this community at the GDE summit in Berlin in Jan 2023. Over the last 3 years, <a href="https://dev.to/this-is-learning">this-is-learning</a> and <a href="https://dev.to/this-is-angular">this-is-angular</a> have grown over 150+ contributors and more than 2.5M views.</p><h3>How It Started</h3><p>In 2020 <a href="https://dev.to/layzee">@layzee</a> had a vision of starting a publication that is free and open to everyone. And he wanted to ensure everyone was free to express their views, and there should not be any gatekeeping.</p><p>I also joined the publication when it started, so I was one of the early contributors to this community.</p><h3>Joining TIL as Co-Founder</h3><p>In 2020 I was running my show called <a href="https://www.youtube.com/@TechTalksWithSantosh">Tech Talks with Santosh</a>, where I was streaming every week. After doing it for a year, I was getting burned out. I also called my friend <a href="https://twitter.com/learn_n_share">Amandeep</a>, and he suggested it’s better to collaborate as you won’t be able to scale it up.</p><p>When I was thinking about collaboration, there are 2 things I can do.</p><ul><li>Onboard someone to run Tech Talks with Santosh together, but the show was in my name, and I wanted to keep using this channel in the future.</li><li>Collaborate with <a href="https://dev.to/layzee">@layzee</a> as I have known him since 2019, and admire his work for the community.</li></ul><p>I decided to reach out to Lars and proposed that I join <a href="https://dev.to/this-is-learning">this-is-learning</a>, and Lars was convinced, as we can focus on more areas other than blogs.</p><p>During our call, we exchanged thoughts on the values of the community,</p><ul><li>We both wanted to ensure we kept the community free from any influence from outside.</li><li>Which means we will never take sponsorship.</li><li>Anyone interested in sharing knowledge can join the community with no gatekeeping.</li><li>Keep the bar low. No one needs to be an expert to join our publication; dedication and effort matter.</li></ul><h4>Other Initiatives</h4><p>After joining the <a href="https://dev.to/this-is-learning">this-is-learning</a> as co-founder, we decided to bring more initiatives to grow the community. <br> We started</p><ul><li>This Is Tech Talks Podcast (<a href="https://www.youtube.com/@ThisisTechTalks">https://www.youtube.com/@ThisisTechTalks</a>)</li><li>This is Learning Newsletter (<a href="https://thisislearning.substack.com/">https://thisislearning.substack.com/</a>)</li><li>Community Discord Server (<a href="https://discord.gg/REY2x8SJYk">https://discord.gg/REY2x8SJYk</a>)</li><li>This is Angular guides (<a href="https://this-is-learning.github.io/rxjs-fundamentals-course/">https://this-is-learning.github.io/rxjs-fundamentals-course/</a>)</li><li>NgRx Essentials (<a href="https://this-is-angular.github.io/ngrx-essentials-course/">https://this-is-angular.github.io/ngrx-essentials-course/</a>)</li><li>RxJS Fundamentals (<a href="https://github.com/this-is-learning/rxjs-fundamentals-course">https://github.com/this-is-learning/rxjs-fundamentals-course</a>)</li></ul><h4>How we added more contributors</h4><p>Growing a community takes work. Our motto was to have a community that promotes Free, open, and honest software education.</p><p>To grow the community, we started reaching out to folks on Twitter and LinkedIn, and we reached out to the community members who were already writing blogs.</p><p>Reaching out to community members works excellently for us. Most of the community members writing and publishing our blogs came via this channel.</p><p>We also got some great contributors, like <a href="https://twitter.com/djgovani">Deep</a>, who took the initiative and started writing the newsletter, which he has been writing for over a year.</p><p>We also have <a href="https://twitter.com/JayCooperBell">Jay</a>, who joined us as co-host for our podcast.</p><p>And 100s of other contributors who are very active in writing for the publication.</p><figure><img alt="This is Angular Writers" src="https://cdn-images-1.medium.com/max/355/0*bHVFAunJbwZ78e1w.png" /></figure><figure><img alt="This is Learning Writers" src="https://cdn-images-1.medium.com/max/262/0*L-fKiNk70-xxLBqX.png" /></figure><h4>Where are we now</h4><p>The community is growing monthly, and we have seen incredible growth over the years.</p><p>The community servers crossed 300 members, and our private discord of contributors struck 150+ members.</p><p>The blog post crossed 2.5M reads.</p><figure><img alt="This is Learning Stats" src="https://cdn-images-1.medium.com/max/880/0*arFUORVaQBNLNKTu.png" /></figure><figure><img alt="This is Angular Stats" src="https://cdn-images-1.medium.com/max/880/0*EBQ5_c1AD_gkfCm6.png" /></figure><p>The podcast crossed 350 subscribers and 8k views.</p><figure><img alt="This is Learning Podcast" src="https://cdn-images-1.medium.com/max/880/0*4YEFrbIAt0pSXxd4.png" /></figure><p>How to join <br> We run multiple initiatives, and you can help the community in several ways.</p><ul><li>Write blogs for TIL or TIA</li><li>Podcast.</li><li>Newsletter</li><li>Help writing educational content on GitHub (<a href="https://github.com/this-is-learning">https://github.com/this-is-learning</a>)</li></ul><p>If you want to be part of the community reach out to <a href="https://twitter.com/SantoshYadavDev">Me</a> or <a href="https://twitter.com/LayZeeDK">Lars</a> , our <a href="https://discord.com/invite/WquDAakwkK">community discord</a> is open to everyone.</p><p>This article is published w/ <a href="https://scattr.io?ref=medium">Scattr ↗️</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bc7ba44af5fb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why and How we migrated to Nx from Angular CLI]]></title>
            <link>https://medium.com/@santosh.yadav198613/why-and-how-we-migrated-to-nx-from-angular-cli-f9a6192e8430?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/f9a6192e8430</guid>
            <category><![CDATA[nx-dev-tools]]></category>
            <category><![CDATA[nx]]></category>
            <category><![CDATA[monorepo]]></category>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[migration]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Tue, 21 Jun 2022 18:12:56 GMT</pubDate>
            <atom:updated>2022-06-21T18:12:56.707Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OQsOlX8uh4YmZOen9mpAfQ.jpeg" /></figure><p><strong>Note</strong>: Due to NDA, we won’t mention the client’s name.</p><p>We finished migrating to Nx from Angular CLI last year, and it was one of the biggest restructure we did. This post will cover why we decided to do it and what we did.</p><h3>Our challenges</h3><ul><li><strong>Code Sharing:</strong> We had code shared across the applications. We had most of the reusables as part of our App, and we kept adding more reusable code as part of our main Application.</li><li><strong>Refactoring:</strong> We had started perf optimization as mentioned. It was challenging to refactor the codebase in the existing state. It was challenging to determine which part of the code needed to touch. Or where to add a new feature.</li><li><strong>Build Time:</strong> Our build time was high; we had to wait a lot of time post every PR/MR. More build time means more time stuck at a task and fewer changes to shipping every release cycle.</li><li><strong>Adding new features:</strong> It was challenging to add new features in the App that was already too big.</li><li><strong>Code Review: </strong>It was hard to add code owners with a single app holding all the codebase.</li></ul><p>The above pain points gave us a clear idea that NxDevTools is the best option for us, and we should go ahead with it.</p><h3>Why we did it</h3><p>It was a big decision to move to Nx from Angular CLI. We had a single project for the main app created using Angular CLI and some smaller separate applications within the same workspace before migrating to Nx. It was like a massive piece of code sitting inside a single code base, so we had a lot of challenges migrating, and even more if we never migrated to Nx.</p><p>When I joined the team, there was a decision to tackle the performance issues in the App, so we had a lot of refactoring of code coming soon.</p><h4>What is Nx</h4><p>Nx is a DevTools for managing mono-repos. The advantage of using <a href="https://monorepo.tools/">mono-repos </a>is you can create and manage multiple applications inside a single workspace and maintain/<a href="https://monorepo.tools/#why-a-monorepo">share</a> libraries. <br>Nx does more than a mono-repo. It gives you access to the devkit to write your generators and builders/executors (custom command).</p><p>Nx also provides caching for your builds, so you don’t have to compile your unchanged code every time you run your build. And Nx Cloud is a fantastic product if you want to get the caching advantages on your CI pipeline.</p><h4>Concern before we started</h4><p>Before starting the migration, it was essential to identify what part of the code needed to be moved from App and created as libraries.</p><p>We decided to do the following:</p><ul><li>Breaking everything was not what we wanted to do. We decided in the first iteration we would only move a big folder named common/legacy, which had a most reusable code base, and create a new library.</li><li>As soon as we moved the large legacy folder to another library, we ended up with another issue. The plan to move legacy code was the right choice in the end. The problem was an increase in the bundle size, and it grew exponentially. And we couldn’t go ahead with this.</li></ul><p>We were on the drawing board again, and we decided to assemble and discuss.<br>We had the below choices:</p><ul><li>I had used secondary entrypoints in the past. My suggestion was to go with secondary entrypoints.<br> — This sounds like the best idea, and I will go with this option in most cases.<br> — The problem was we had extensive code to be moved to libraries.<br> — If we went with this option, it might have taken us more than a year considering the large codebase, as we had three people team and only me doing this full-time.</li><li>Considering the complexity of Solution one, we decided to go with another solution<br> — We decided to use wild card paths in `tsconfig.base.json` like below<br> `”<a href="http://twitter.com/domain/common-legacy">@domain/common-legacy</a>/*”: [“libs/common/legacy/src/lib/*”]`<br> — This was a good idea as we import only what we need.<br> — But it has its challenges</li></ul><h4>Little about the Solution</h4><p>We decided to split the entire migration into 3 parts:</p><p>- Move the common/legacy and solve the issue we come across.<br>- Move the rest of the code after the first step is a success.<br>- Take care of Circular Dependency.</p><h4>Initial Solution</h4><p>- We dont need to create secondary entrypoints less work. We can just have folders for each `component/module/service/` etc. And use it as</p><p>```<br>import { HomeModule } from ‘<a href="http://twitter.com/domain">@domain</a>-common-legacy/home.module’<br>```</p><p>- We dont get the entire lib as part of the bundle. We only get the code that we need. Keeping bundle budget under control. And as we move new code, we need to configure the path correctly.</p><p>- But it introduced an issue, the libraries created were not buildable. But we decided to move ahead as having buildable libraries was not part of Part 1 of this migration process.</p><p>- We decided to disable the Circular Dependency checks.</p><h3>The Final solution</h3><p>Once we figured out how our initial Solution works, we decided to go through the codebase, identify all the features we have, and split them into libs.</p><p>We identified most of the features we have consist of 3 parts:<br>- feature/common: Common components/directives used within the feature and other features.<br>- Core: We lazy load our features, so we don’t end up with a large bloated application. The core-libs consisted of components/services/directives/modules which are part of the lazy-loaded feature and not shared outside.<br>- State: Every feature has a state, we use NgRx for global state and RxAngular for handling local state, the state library holds the NgRx code for feature and is sometimes shared with other features.</p><p>We also decided the shared code will be part of a folder called core so we have<br>- core/directive<br>- core/shared-components<br>- core/state<br>- core/model</p><p>and many more, these libs are used across the libraries and multiple applications inside the organization.</p><h4>What after creating Libraries</h4><p>As I mentioned, creating libs was only part one of the entire migration. During this exercise, we figured out a huge chunk of state management/ NgRx code with our main bundle.</p><p>We decided we could parallelly handle this by splitting them and only loading the states we need as part of the main code.</p><p>We started with around 2.9MB in the main bundle down to 2.30MB with the build for the evergreen browser.</p><h4>Handling Circular Dependency</h4><p>Once we were done creating libraries, we ended up with 180+ libraries, which we had started with a single application.</p><p>Now it was time to handle the Circular Dependency issues. It was not possible to do it in one go.<br>So we decided to start with core libs and figured out, that the large codebase responsible for the Circular Dependency issues was part of core-libs, mostly interfaces/services and states.</p><p>We kept the Circular Dependency check disabled, even though we were fixing one of the mistakes we made.</p><p>We realized we could enable the check for new code, and we enabled the check for an entire repo by adding in the root eslint config and disabled it for all the libs which had Circular Dependency. In this way, now new libraries can only be merged if they dont have a Circular Dependency issue.</p><p>We decided to enable the Circular Dependency check for libraries as we kept fixing it.</p><p>The Circular Dependency fix required us to create more libraries and finally, we ended up with more than 250+ libraries.</p><h4>Building Libraries</h4><p>As we mentioned earlier, one of the issues with the approach as we can not build these libraries.</p><p>Our teammate decided to take this matter into his own hands and ended up writing a builder to build all the new libraries created with this approach.</p><p>Matt also wrote a Library Generator so we create all the libraries using the same structure, so we don’t end up with entire libs as part of the bundle.</p><h4>What we achieved</h4><p>After this migration, we have</p><ul><li><strong>Code Owners:</strong> We decided to create a CODEOWNERS file to split the responsibility for code review and which group owns the specific part of the code.</li><li><strong>Custom eslint rules:</strong> As a part of our process, we have some checks for our code review process; moving to Nx allowed us to convert all those checks to custom eslint rules, saving more time for us.</li><li><strong>Easy to refactor code:</strong> We fix/add a lot of code weekly, and having those libs made our life easier, as now it’s easy to find out which part of the code needs to be touched.</li></ul><h3>Conclusion</h3><p>The choice to move to NX worked well for us, and we were able to identify features and move them to libraries, giving us the advantage of having small PRs. Also, we could identify the unused and duplicate code.</p><p>Adding custom rules and code owners was a great help for us. We were able to identify the code we needed to review.</p><p>Please share your experience on Twitter migrating to Nx and how it helped you.</p><p>You can Join Nx Community Slack: <a href="https://go.nrwl.io/join-slack">https://go.nrwl.io/join-slack</a></p><p>Special thanks to <a href="https://twitter.com/juristr">Juri </a>for giving his precious time to review this article. Love you and your work Juri 💙</p><p>Shoutout to my [GitHub Sponsors](<a href="https://github.com/sponsors/santoshyadavdev">https://github.com/sponsors/santoshyadavdev</a>)</p><p>- [Sunil](<a href="https://twitter.com/sunil_designer">https://twitter.com/sunil_designer</a>)<br>- [Fahad](<a href="https://twitter.com/fahadqazi">https://twitter.com/fahadqazi</a>)<br>- [Digger.dev](<a href="https://digger.dev/">https://digger.dev/</a>)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9a6192e8430" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Stop Using Shared Material Module]]></title>
            <link>https://medium.com/angular-in-depth/stop-using-shared-material-module-9f9b154d710b?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/9f9b154d710b</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[angular-material]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Fri, 27 Mar 2020 08:00:31 GMT</pubDate>
            <atom:updated>2020-03-28T04:17:23.788Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4BTYird9np0pteU1jK5iBg.jpeg" /><figcaption>Image By <a href="http://www.96five.com">www.96five.com</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/0*kMOSJzN75FaVgeLM.png" /></figure><blockquote><a href="https://medium.com/angular-in-depth"><strong><em>AngularInDepth</em></strong></a><strong><em> is moving away from Medium. </em></strong><a href="https://indepth.dev/stop-using-shared-material-module/"><strong><em>This article</em></strong></a><strong><em>, its updates and more recent articles are hosted on the new platform </em></strong><a href="https://indepth.dev/"><strong><em>inDepth.dev</em></strong></a></blockquote><p>In this blog post, I will talk about a mistake I have made and have seen many developers doing it as well, which is a shared Material Module. I am sure if you used Angular Material, you still have a SharedMaterial Module in your project, time to remove it.</p><h4>What is my Motivation</h4><p>I am working on a new project which has many modules. It has more than 20k Lines of Code. I was working on making some modules as Lazy Loaded modules. I realized we are using the SharedMaterial module in all modules. First, I thought it’s ok, but I tried to do an experiment which proved its a bad idea.</p><h4>Time To Prove Ourselves Wrong</h4><p>In my last project where we had our custom components like Grid, Tables, Forms and I did ended up using a big Shared Material Module, as all the components were written on top of Angular Material Component. And now it’s time to prove myself wrong that it was not a good approach.</p><p>Let’s create a new App, and we will cover what’s wrong with this approach and how it increases the bundle size. We will be using webpack-bundle-analyzer to check the bundle size. Run the below command to create a new App. Make sure you are using the latest Angular CLI</p><pre>ng new demoapp</pre><p>next install webpack-bundle-analyzer using the below command</p><pre>npm i webpack-bundle-analyzer -D</pre><p>now add the given script in package.json</p><pre>&quot;analyze&quot;: &quot;ng build --prod --stats-json &amp;&amp; webpack-bundle-analyzer ./dist/demoapp/stats-es2015.json&quot;</pre><p>now run the below command to view the stats.</p><pre>npm run analyze</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/652/1*kYz03-zTdb3LR7XW4OdkZw.png" /><figcaption>Bundle Analyzer 1.1</figcaption></figure><p>The above command opens a page, as shown in the image above.</p><p>Now, let’s add Angular Material using the below command:</p><pre>ng add @angular/material</pre><p>Run the npm run analyze command again and see the main bundle size. It&#39;s already increased by around 70 KB without using even a single component from Angular Material.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/243/1*QRGtAxdQ8k46hr17MBsoBA.png" /><figcaption>After Adding Angular Material 1.2</figcaption></figure><p>Now let’s add 2 modules employee and department, respectively, using the below command. We will not lazy load them for the first example.</p><pre>ng g m employee --routing --module app<br>ng g c employee --export true<br>ng g m department --routing --module app<br>ng g c department --export true</pre><p>Open app.component.html and replace the default template data with</p><pre>&lt;app-employee&gt;&lt;/app-employee&gt;</pre><pre>&lt;app-department&gt;&lt;/app-department&gt;</pre><p>If we analyze the bundle again at this point as we hardly have any code, there is a very small change in size, and it has reduced as the default template contains lots of markups and CSS.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/237/1*NPS-0kVG6OR86m5JPtLTRQ.png" /><figcaption>After adding modules 1.3</figcaption></figure><p>Now let’s add some code in both the component, we will copy some code from <a href="https://material.angular.io/">Material documentation</a>.</p><p>Add the below code into department and employee component respectively</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4b33a79040be2d080d5a008b9351f8ec/href">https://medium.com/media/4b33a79040be2d080d5a008b9351f8ec/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/deb991847a81f0b2ea5944a559951339/href">https://medium.com/media/deb991847a81f0b2ea5944a559951339/href</a></iframe><p>One more change is needed in department.component.ts add the below property :</p><pre>panelOpenState = false;</pre><p>Now, we need to add some Material module into our employee, and department module as well to avoid the build error, and this is where most of us decide to create a SharedMaterial module like one below.</p><pre>ng g m shared/material --flat true</pre><p>and add the below code into the new module:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a3b188d9fb99d51cffd8ed63a6a46e7c/href">https://medium.com/media/a3b188d9fb99d51cffd8ed63a6a46e7c/href</a></iframe><p>Now include the newly create MaterialModule into employee and department module.</p><pre>imports: [<br>   CommonModule,<br>   MaterialModule<br>]</pre><p>Now run the analyzer again, you can see 216 KB has increased.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/241/1*JNsWC2FXTRoCR4hYamD8Mg.png" /><figcaption>After using Angular Components 1.4</figcaption></figure><p>Now to optimize the app, the next approach we take is lazy load the modules. Let’s convert the employee and department module to a lazy loaded module.</p><p>Remove the EmployeeModule and DepartmentModule from app.module.ts remove the import statement and from the import array as well.</p><p>This is the code after removing both modules</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/de872f5fc3db0ac1fb38257a367bcbf7/href">https://medium.com/media/de872f5fc3db0ac1fb38257a367bcbf7/href</a></iframe><p>Next, configure the employee and department as a lazy-loaded module. Add the below code to app-routing.module.ts</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2a43bb6bbeaa5f1f77ad30d528de149a/href">https://medium.com/media/2a43bb6bbeaa5f1f77ad30d528de149a/href</a></iframe><p>Next, add the below code in employee-routing.module.ts</p><pre><em>import</em> { NgModule } <em>from</em> &#39;@angular/core&#39;;<br><em>import</em> { Routes, RouterModule } <em>from</em> &#39;@angular/router&#39;;<br><em>import</em> { EmployeeComponent } <em>from</em> &#39;./employee.component&#39;;</pre><pre>const<em> routes</em>:<em> Routes </em>=<em> </em>[<br>    {<em> path</em>:<em> </em>&#39;&#39;<em> </em>,<em> component </em>:<em> EmployeeComponent </em>}<br>];</pre><pre>@<em>NgModule</em>({<br>    imports: [RouterModule<em>.forChild</em>(routes)],<br>    exports: [RouterModule]<br>})<br><em>export</em> class EmployeeRoutingModule { }</pre><p>And similar changes in department-routing.module.ts</p><pre><em>import</em> { NgModule } <em>from</em> &#39;@angular/core&#39;;<br><em>import</em> { Routes, RouterModule } <em>from</em> &#39;@angular/router&#39;;<br><em>import</em> { DepartmentComponent } <em>from</em> &#39;./department.component&#39;;</pre><pre>const<em> routes</em>:<em> Routes </em>=<em> </em>[<br>    {<em> path</em>:<em> </em>&#39;&#39;,<em> component</em>:<em> DepartmentComponent </em>}<br>];</pre><pre>@<em>NgModule</em>({<br>    imports: [RouterModule<em>.forChild</em>(routes)],<br>    exports: [RouterModule]<br>})<br><em>export</em> class DepartmentRoutingModule { }</pre><p>Let’s change app.component.html to use routerLink to lazy-load these 2 modules.</p><pre>&lt;a <em>[routerLink]</em>=&quot;[&#39;/employee&#39;]&quot; <em>routerLinkActive</em>=&quot;router-link-active&quot;&gt;Employee&lt;/a&gt;</pre><pre>&lt;a <em>[routerLink]</em>=&quot;[&#39;/department&#39;]&quot; <em>routerLinkActive</em>=&quot;router-link-active&quot;&gt;Department&lt;/a&gt;</pre><pre>&lt;router-outlet&gt;&lt;/router-outlet&gt;</pre><p>Now run the analyzer again and check the bundle size. After lazy loading, the bundle size should be reduced, but it increased by around 70KB.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/243/1*FMDPRaS5F8Gi6Lh0263NyQ.png" /><figcaption>After lazy loading 1.5</figcaption></figure><p>Now, let’s remove the Shared Material module and import only the modules which are needed. In employee.module.ts import MatFormFieldModule and MatSelectModule and in department.module.ts import MatExpansionModule and MatFormFieldModule delete the shared module and run the command to analyze the bundle size. In this example, we save around 40KB.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/248/1*hk6OtFLDUBQb6JE5wZmeEA.png" /></figure><h4>CONCLUSION</h4><p>I did a similar experiment in my current project and the bundle size was reduced by around 200 KB. Remember when it comes to the web every single KB matters. So, I would suggest and try in your app refactor and share your experience.</p><p>GitHub Repo: <a href="https://github.com/santoshyadav198613/sharedmodule-demo">https://github.com/santoshyadav198613/sharedmodule-demo</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9f9b154d710b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angular-in-depth/stop-using-shared-material-module-9f9b154d710b">Stop Using Shared Material Module</a> was originally published in <a href="https://medium.com/angular-in-depth">Angular In Depth</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Angular’s ‘root’ and ‘any’ provider scopes]]></title>
            <link>https://medium.com/angular-in-depth/angulars-root-and-any-provider-scopes-1ccc53466a7b?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/1ccc53466a7b</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[dependency-injection]]></category>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Sat, 15 Feb 2020 16:57:18 GMT</pubDate>
            <atom:updated>2020-02-15T16:58:59.825Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/200/1*YtaSz2oCDek_dCJjVs_1rA.png" /></figure><blockquote><a href="https://medium.com/angular-in-depth"><strong><em>AngularInDepth</em></strong></a><strong><em> is moving away from Medium. </em></strong><a href="https://indepth.dev/angulars-root-and-any-provider-scopes/"><strong><em>This article</em></strong></a><strong><em>, its updates and more recent articles are hosted on the new platform </em></strong><a href="https://indepth.dev/"><strong><em>inDepth.dev</em></strong></a></blockquote><p>In this blog post we will explore 2 values for providedIn property used with Angular provider Scope.</p><h4>Introduction</h4><p>If you are following Angular 9 release, you may have heard about providedIn has few more properties, module injector scope has been possible since version 2, tree-shakable module scope became available in version 6 with providedIn: MyServiceModule,and now we have ‘any’ and ‘platform’ .</p><h3>Manfred Steyer on Twitter</h3><p>Did you know, #Angular 9 introduces providedIn:&#39;any&#39;: 💥Gives you a separate service instance per lazy module (+ one for &#39;root&#39;) 💥Can replace the need to force consumer to call forRoot and forChild in some cases</p><p>In this blog post we will see the example why we needed &#39;any&#39; and how it is useful. Will leave ‘platform’ for next blog-post.</p><h4>Tree-shakable Providers</h4><p>In Angular 6 providedIn property was added to providers, to make services tree shakable. If you are new to Angular, let me give you an simple explanation what we mean by tree shaking. It is a process to remove unused code from our application. It means if you created a service but do not use it, in your application the code will not be part of final production build. To learn more you can refer to this blog post from <a href="https://medium.com/u/f0e7507974eb">Lars Gyrup Brink Nielsen</a>:</p><p><a href="https://medium.com/angular-in-depth/tree-shakable-dependencies-in-angular-projects-5aaa7012b9e7">Tree-shakable Dependencies in Angular Projects</a></p><h4>Why the any scope?</h4><p>So we now know why &#39;root&#39; was introduced, the idea was to make services tree-shakable. To understand providedIn: &#39;any&#39; we have to talk a little bit about implementation of forRoot, forChild and lazy loading. If you have used Angular Router or NgRx then you know about these methods.</p><p>The problem of working with lazy loaded module is that if we use providedIn: &#39;root&#39; even though we think we should get a new instance of a service, it gives the same instance and that might not be the behavior we expect. When working with a lazy-loaded module, a new instance should be created when we load the module.</p><p>Let’s write some code to see what was the issue earlier and how &#39;any&#39; resolves that for us.</p><h4>What we are going to achieve</h4><ul><li>A config service which will take some config parameter apiEndpoint and timeout.</li><li>2 lazy-loaded modules: employee and department. They want to use the config service, but with different values.</li></ul><h4>The problem with using the root scope</h4><ul><li>Create a new Angular 9 app using the below command</li></ul><pre>npx -p @angular/cli@next ng new providerdemo</pre><ul><li>Now let’s create 2 new lazy-loaded modules with components. Run the below commands</li></ul><pre>npx -p <a href="http://twitter.com/angular/cli">@angular/cli</a>@next ng g module employee --routing --route employee</pre><pre>npx -p <a href="http://twitter.com/angular/cli">@angular/cli</a>@next ng g module department --routing --route department --module app</pre><ul><li>Create a new value provider and an interface. You can add it in a new shared folder, as this code will be shared between multiple modules.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1ab352b1f35b687387499b49011c9b36/href">https://medium.com/media/1ab352b1f35b687387499b49011c9b36/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/774065ef9e97131c61ee57f96746041f/href">https://medium.com/media/774065ef9e97131c61ee57f96746041f/href</a></iframe><ul><li>Next, create a new service. We will call it ConfigService which will read the value from token and use it to perform some operation. Use the below command to create it.</li></ul><pre>npx -p @angular/cli@next ng g service shared/config</pre><ul><li>Once created, add the below code to your service</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/892f134bba1e168c89f8174767354832/href">https://medium.com/media/892f134bba1e168c89f8174767354832/href</a></iframe><ul><li>Now let’s use this service in the Employee and Department Components we created with their respective modules. We are just printing the values received from Token.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8538f7d628225f7a6d2b429c081ee812/href">https://medium.com/media/8538f7d628225f7a6d2b429c081ee812/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b2f19ddd589b754c36947f42d83a6b1b/href">https://medium.com/media/b2f19ddd589b754c36947f42d83a6b1b/href</a></iframe><ul><li>Next, let’s try to pass 2 different configuration for Employee and Department, add the below code into both the modules.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8dac764af66077e3a8827d228e3b2d9d/href">https://medium.com/media/8dac764af66077e3a8827d228e3b2d9d/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cc2ce29907962c962ccb4dc9bed5a88a/href">https://medium.com/media/cc2ce29907962c962ccb4dc9bed5a88a/href</a></iframe><ul><li>As seen, the difference is in the config values. Let’s run the application and see what we get. Remember the providedIn value is still &#39;root&#39;. To test the application in it’s current state, let’s add links to the routes. Add the below snippet in app.component.html</li></ul><pre>&lt;a routerLink=&quot;employee&quot;&gt;Employee&lt;/a&gt;<br>&lt;br&gt;<br>&lt;a routerLink=&quot;department&quot;&gt;Department&lt;/a&gt;<br>&lt;router-outlet&gt;&lt;/router-outlet&gt;</pre><ul><li>Next, run the application using the below command</li></ul><pre>npx -p <a href="http://twitter.com/angular/cli">@angular/cli</a>@next ng serve -o</pre><ul><li>The application works, but when we click on a link, boom we have an error. Our expectation was to see the different config values, but we have the below error.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/693/1*xSsXrcNMUfW63PpLrkhh4Q.png" /><figcaption>provider-error</figcaption></figure><h4>So what went wrong here?</h4><p>We did everything right. Our expectation was to get different config values for both the employee and department components, but we ended up getting an error. This is due to the providedIn: &#39;root&#39; value. Refer to Figure 1 to visualize what happened.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1019/1*fb7NZoE8g2L2kqTplY6SIQ.png" /><figcaption>Figure 1. Root provider scope.</figcaption></figure><p>When we provide the service with providedIn: &#39;root&#39;, it is registered with our AppModule. As soon as we tried to activate one of the routes, the service expected the config value which was not provided. So let’s make it work by making changes to our AppModule.</p><p>Add the below code to your app.module.ts</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1c5aac4937db3eecd0c0601d581ac503/href">https://medium.com/media/1c5aac4937db3eecd0c0601d581ac503/href</a></iframe><p>Now the application works, but when we click on the links, we see the below 2 values for both the employee and department components. This is the expected behavior as per Figure 1.</p><pre>apiEndPoint: &#39;def.com&#39;<br>timeout: 5000</pre><p><strong>What we wanted to achieve</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/987/1*LeuxVc06dUDJGEWbeJPbzQ.png" /><figcaption>Figure 2. Injector provider scope.</figcaption></figure><p>In reality, we wanted something like Figure 2 , where each module has their own instance. With providedIn: &#39;root&#39;, this was not possible.</p><ul><li>To resolve this issues, the previous solution was implementing forRoot and forChild static methods, so each component can have their own instances.</li><li>The other way to achieve this was to provide the ConfigService in each and every module. The problem is then, that the service is no longer tree-shakable.</li></ul><pre><a href="http://twitter.com/NgModule">@NgModule</a>({<br>  providers: [<br>    ConfigService,<br>    { provide: CONFIG_TOKEN, useValue: CONFIG_VALUE }<br>  ]<br>}<br><em>export</em> class EmployeeModule { }</pre><ul><li>Now let’s change the providedIn option for ConfigService to below</li></ul><pre>@Injectable({<br>  providedIn: &#39;any&#39;<br>})</pre><ul><li>Run the application again and notice the console now.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1017/1*jgJnuEI6LzXWtHFPTJdCBw.gif" /><figcaption>Final App</figcaption></figure><ul><li>Bingo, we got the separate instances without implementing forRoot or forChild static methods or compromise regarding tree-shakable providers.</li></ul><p>So what happened after changing to providedIn: &#39;any&#39;? As shown in Figure 3, now all eagerly loaded modules will share one common instance and all lazy-loaded modules will have their own instance of ConfigService.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xXtFcoRnkyycQl1vdtvh_g.png" /><figcaption>Figure 3. Any provider scope.</figcaption></figure><h4>Conclusion</h4><p>Earlier for all developers it was a challenge whenever they wanted to make sure they get a new instance of a service for lazy-loaded modules. Now with the &#39;any&#39; option to provide services in injector scopes, it’s simplest thing to do. We can provide any tokens and developers can provided the values per lazy-loaded module. The service will always create a new instance per lazy-loaded module.</p><p>You can download the code from <a href="https://github.com/santoshyadav198613/angular9-providerdemo">GitHub</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1ccc53466a7b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angular-in-depth/angulars-root-and-any-provider-scopes-1ccc53466a7b">Angular’s ‘root’ and ‘any’ provider scopes</a> was originally published in <a href="https://medium.com/angular-in-depth">Angular In Depth</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Time For Employers To Change Their Perspective On Open Source Contribution]]></title>
            <link>https://medium.com/@santosh.yadav198613/time-for-employers-to-change-their-perspective-on-open-source-contribution-73d54765fddc?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/73d54765fddc</guid>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[information-technology]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Mon, 03 Feb 2020 15:15:24 GMT</pubDate>
            <atom:updated>2020-02-04T08:15:35.328Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*e9HFDShEG_cUN5sGjxScIA.png" /></figure><p>Before you read this article, I want to make it very clear, I am not blaming anyone here. Keeping this in mind, let’s move ahead.</p><h4>Background</h4><p>I have been working in Tech Industry from last 11 years, and have seen a big change in technology, I started my career in asp.net web forms era, moved to MVC and then worked with .net Web APIs, and now working with mostly Javascript/Typescript. When I started my career in 2008, I was not even aware of what Open Source means, the only term I had heard was Java is Open Source.</p><p>I started contributing to Open Source in 2019, and believe me its fun, and you get to learn a lot while helping many developers across the world. I also received the opportunity to speak at conferences, which I really wanted to, so I can share my knowledge on a bigger stage.</p><h4>What is the problem</h4><p>I was working for a big Financial Institution, and all Financial Institutions have strict rules for their employees to get involved in community-related work, which does make sense, as it may create an issue if someone shares some confidential information, which may include the code as well. Even there are developers, contributing to Open Source, who wants to be low profile in their own organization, as they are scared, they will be treated in a different way or the organization may expect something more, like providing free training’s, or working for more hours, rather than investing their time contributing to OSS, and I know few people from the community, they are going through this.</p><h4>How it can be changed</h4><p>Time is changing if you see the <a href="https://octoverse.github.com/">Octoverse</a> data from 2019, the number of developers is increasing so do developers contributing to open source. See the below stats from 2019.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qZ4QXuaU2RxpMcan4eXB5Q.png" /></figure><p>And all tech companies including Financial Institutions are using and trying to be part of this change. Many financial institutions have Open Source projects, including where I used to work and many startups have there owned Open Source products.</p><p>These are few things which Organization especially Financial Institutions should do, to adopt the change to support developers contributing or speaking at conferences:</p><ul><li><strong>Training Sessions: </strong>If disclosing some confidential information is a problem, provide the training to developers, who are going to speak at the conference. They should be given training, what they can talk about, how they should present themselves.</li><li><strong>Better Expectations: </strong>If an organization is ready to pay 15–20k (per day rate in India), for acquiring the services from outside, to train their employees, than you should not expect your employees to do it for free.</li><li><strong>Support OSS: </strong>Only making some projects open source is not enough to support the community. There are organizations with billion $ in profit, using open source projects. But when it comes to supporting those projects they don’t even invest a single dollar.</li><li><strong>Motivate Developers: </strong>If you are a Tech lead, rather than asking them “what you get by doing OSS, or writing blog post, you even don’t get paid”, please motivate them to do it, and I have heard from many developers, their tech leads, did used these words, once they came to know about there OSS or blog posts. And the change in this culture should come from management.</li><li><strong>Support Community Driven Conferences: </strong>There are many conferences which happen across the world, support them my becoming sponsor, motivate your employees to attend those conferences.</li></ul><p>When it comes to the biggest IT companies in the world, Microsoft and Google is Sponsor for almost every other conference around the globe. But the same is not true for others. You can search for any community-driven conference and try to find any other Organization from Top 10, you will see the reality.</p><p><strong>Conclusion</strong></p><p>Supporting Open Source does not mean, making some projects Open Source, It includes supporting them financially, or helping them fix the issues as well. It also means the employees, who are contributing to Open Source from your organization should be treated better and given the opportunity to showcase their talent. Every organization wants the best developer to work for them, but as an employer, it is your responsibility to help your employees become best too.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=73d54765fddc" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using in-memory-db With NestJS]]></title>
            <link>https://medium.com/better-programming/using-in-memory-db-with-nestjs-803a91a8eb11?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/803a91a8eb11</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Mon, 13 Jan 2020 22:33:27 GMT</pubDate>
            <atom:updated>2020-01-14T18:16:25.150Z</atom:updated>
            <content:encoded><![CDATA[<h4>In this piece, we will see how we can use in-memory-db to perform CRUD operations</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*oTbTuBA4_RtKoXCsZ-ybKQ.png" /><figcaption>NestJS logo</figcaption></figure><p>Let’s see why we should and how we can use in-memory-db, you can access the source code <a href="https://github.com/nestjs-addons/in-memory-db">on GitHub</a>.</p><h3>Why</h3><p>Below are two scenarios where you may need in-memory-db.</p><ul><li>POC (Proof of Concept): When you need to create a quick POC for an upcoming project and you want to create an API with <a href="https://nestjs.com/">NestJS</a>, for integration with a UI.</li><li>Mock: You need to write the test cases and you want to mock the DB operations. This is the perfect use case for using in-memory-db.</li></ul><h3><strong>How</strong></h3><p>Follow the below steps to create an API with in-memory-db.</p><ul><li>Run the below command to create a NestJS project.</li></ul><pre>nest new in-memory-demo</pre><ul><li>Once the app is ready, run the below command to install in-memory-db support.</li></ul><pre>nest add @nestjs-addons/in-memory-db</pre><ul><li>We will create a ProductController with CRUD operations, so we will add a module and controller for the same.</li></ul><pre>nest generate module product<br>nest generate controller product</pre><ul><li>Next, we need an entity. Create a new folder entities inside the product folder.</li><li>Create a new file product.entity.ts and add the below code.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6c6e6291179e6a459660cfefef1be6ab/href">https://medium.com/media/6c6e6291179e6a459660cfefef1be6ab/href</a></iframe><ul><li>In the above code, InMemoryDBEntity adds an id property to any interface that extends this interface.</li><li>Next, we need to add some code to the controller and the module. There are two ways in which you can perform CRUD operations, by providing your own implementation or using the built-in InMemoryDBEntityAsyncController or InMemoryDBEntityController.</li></ul><p>We will see both approaches, let’s see how to implement our own.</p><ul><li>Open app.controller.ts and add the below code, this file already exists.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2338bc2be89e8b8229d792cb7fc0e2a6/href">https://medium.com/media/2338bc2be89e8b8229d792cb7fc0e2a6/href</a></iframe><p>You can see in the above code that we have added the below code to provide the Post method.</p><pre>@Post()<br>AddProduct(@Body() product: ProductEntity): ProductEntity {<br>    return this.productService.create(product);<br>}</pre><ul><li>The ProductService is instantiated from InMemoryDBService. It comes with many built-in methods to perform CRUD operations, without writing a single line of code. The service contains two types of methods, sync and async which return an observable.</li><li>In the above code, the below-highlighted code is needed to create an instance of service which takes the entity ProductEntity and provides all methods.</li></ul><pre>constructor(private readonly appService: AppService,                           <strong>private productService: InMemoryDBService&lt;ProductEntity&gt;</strong>) {}</pre><p>The methods that we are going to implement are:</p><ul><li>getAll(): Retrieve all records.</li><li>create(): Insert new records. Use createMany to insert multiple records.</li><li>update(): Update the record for the provided id in the request body.</li><li>delete(): Delete the record for the provided id.</li><li>query(): Query the data from the records added.</li></ul><p>Below is the complete code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/88ecfefe74f62ce057d78d72f7023342/href">https://medium.com/media/88ecfefe74f62ce057d78d72f7023342/href</a></iframe><p>Now, in most cases, you just want to provide CRUD operations and if we keep adding the same code, it will cause code duplication and the package keeps that in mind.</p><p>It has InMemoryDBEntityAsyncController orInMemoryDBEntityController to achieve the same.</p><ul><li>To implement CRUD operations using the above interface, you can just add the below lines of code.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0fcc8fef1a9f8807906b18ea8d5c2eb3/href">https://medium.com/media/0fcc8fef1a9f8807906b18ea8d5c2eb3/href</a></iframe><p>The InMemoryDBEntityAsyncController provides the implementation for the below methods by default.</p><ul><li>create</li><li>update</li><li>updateMany</li><li>delete</li><li>deleteMany</li><li>get</li><li>getMany</li></ul><h3>For Feature Modules</h3><p>In case you have a different feature module, you need to use the forFeature method to register InMemoryDBModule. The below code gives an example of how to use it for ProductModule.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ad55ccd5108a983a4accae3f6f773e4d/href">https://medium.com/media/ad55ccd5108a983a4accae3f6f773e4d/href</a></iframe><p>You can also use the feature-specific instances of InMemoryDBService. You need to use the below code in the constructor.</p><pre>constructor(@InjectInMemoryDBService(&#39;product&#39;) private productService: InMemoryDBService&lt;ProductEntity&gt;)</pre><h4>Seeding Test Data</h4><p>For testing, you may need to create some dummy data and we don’t expect you to create all records manually, this is where you can use seed method to create dummy data.</p><ul><li>Create a new Module, Controller, and Entity by using the below command.</li></ul><pre>nest generate module employee<br>nest generate controller employee</pre><ul><li>Next, add a new entities folder in the employee folder and add a new file employee.ts and add the below code.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c534efde8fcbf8724609011aa939e0b7/href">https://medium.com/media/c534efde8fcbf8724609011aa939e0b7/href</a></iframe><ul><li>Next, register the InMemoryDBModule for employee Module, add the below code in employee.module.ts</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7f5b7e5625efb566f554be520ee66c07/href">https://medium.com/media/7f5b7e5625efb566f554be520ee66c07/href</a></iframe><ul><li>Final Step is to use seed method to create 10 dummy records.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2d12b12e83deb3b41fd65150e92285ff/href">https://medium.com/media/2d12b12e83deb3b41fd65150e92285ff/href</a></iframe><p>Next, trigger the seed method by accessing the <a href="http://localhost:3000/employee/seed">http://localhost:3000/employee/seed</a> which will create 10 records.</p><p>You can update the count, in the below method to create more records.</p><pre>this.employeeService.seed(recordFactory, <strong>10</strong>);</pre><p>You can use postman to test out the APIs. In the next article, we will see how we can add swagger capabilities to create a test page for testing.</p><p>You can refer to the code for this demo at:</p><p><a href="https://github.com/santoshyadav198613/nest-in-memory-demo">santoshyadav198613/nest-in-memory-demo</a></p><h3>Conclusion</h3><p>in-memory-db is widely used in other frameworks like .Net, Java, and Angular to create POCs or create a mock back end.</p><p>This package brings the same capability to the NestJS ecosystem and you can easily plugin the same with existing NestJS projects to create POCs.</p><p>Thanks to <a href="https://medium.com/u/9af1d23366c8">Wes Grimes</a> and the team for creating this package.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=803a91a8eb11" width="1" height="1" alt=""><hr><p><a href="https://medium.com/better-programming/using-in-memory-db-with-nestjs-803a91a8eb11">Using in-memory-db With NestJS</a> was originally published in <a href="https://betterprogramming.pub">Better Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Deep Dive Into the NestJS Injection Scope]]></title>
            <link>https://medium.com/better-programming/a-deep-dive-into-nestjs-injection-scope-d45e87fd918d?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/d45e87fd918d</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[nodejs]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Fri, 10 Jan 2020 01:56:39 GMT</pubDate>
            <atom:updated>2020-01-10T19:46:44.338Z</atom:updated>
            <content:encoded><![CDATA[<h4>How can we use them?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*oTbTuBA4_RtKoXCsZ-ybKQ.png" /></figure><p>In my <a href="https://medium.com/better-programming/introduction-to-nestjs-services-2a7c9a629da9">previous piece</a>, we discussed <a href="https://docs.nestjs.com/">NestJS </a>services. In this piece, we’ll look at the injection scope.</p><h3>Provider Scope</h3><p>There are three modes to define the scope. We can either define the scope properties on the service level or module level. It can be used with a class-based and nonclass-based service and with controllers. The three modes are:</p><ul><li>DEFAULT</li><li>REQUEST</li><li>TRANSIENT</li></ul><p>The syntax for defining the scope is as below:</p><h4><strong>For service</strong></h4><pre>@Injectable({<br>    scope: Scope.TRANSIENT<br>})</pre><h4><strong>For module</strong></h4><pre>providers : [{<br>    provide : PRODUCT,<br>    useValue: Product_Token,<br>    scope : Scope.REQUEST<br>}]</pre><h4><strong>For controllers</strong></h4><pre>@Controller({ path: &#39;product&#39;, scope: Scope.REQUEST })</pre><p>Now that we’e aware of how to use the scope property, let&#39;s see each one of them in detail.</p><h3>The Default Scope</h3><p>You don’t need to define the scope to DEFAULT. When you don’t define the property, it’s set to DEFAULT, and the instances will be singleton (which means once the connection is established, the same instance will be used for all requests).</p><p>For most of cases, like database connection and logger services, singleton is the best option to use.</p><p>In the below example, showing a LoggerService in singleton, any controller/service using LoggerService will get the same instance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/663/1*rRNpRlKJIn7raa63Hy9VIQ.jpeg" /><figcaption>DEFAULT scope</figcaption></figure><h3>The Request Scope</h3><p>In a REQUEST scope, the same instance will be shared for the same request.</p><p>You can see in the below diagram that LoggerService is shared for each request. The GetProduct action and ProductService will share the same instance, and if we try to access an AddProduct action, another instance will be created.</p><p>A real-time use case is if we want to share the Request object between the controller and the service for each request.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aBV382PlOwGQ0EKaq_By9A.jpeg" /><figcaption>REQUEST scope</figcaption></figure><h3>The Transient Scope</h3><p>In a TRANSIENT scope, a new instance will be created for every controller or service where we’re using it. The below diagram shows the same scenario where the scope is changed to TRANSIENT. Here a new instance of LoggerService is created for every action and service.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1012/1*waNftzDzgrdiZJTsy6s0rQ.jpeg" /><figcaption>TRANSIENT Scope</figcaption></figure><h4>Code</h4><p>Create a new LoggerService using the below command:</p><pre>nest generate service Logger</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/595f40ecef077a13ddd8f576db5c96a7/href">https://medium.com/media/595f40ecef077a13ddd8f576db5c96a7/href</a></iframe><p>Next, inject the service into the ProductController and the ProductService.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/010bfd1a6b2b037a488fd2f91008fcdf/href">https://medium.com/media/010bfd1a6b2b037a488fd2f91008fcdf/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/823b456fabb25a96533a1b2eee7e13d2/href">https://medium.com/media/823b456fabb25a96533a1b2eee7e13d2/href</a></iframe><p>Next, run the application. Change the scope, and see how the scope gets changed in action.</p><h3>Conclusion</h3><p>Though it’s OK to have a singleton instance, using REQUEST and TRANSIENT scopes can impact the <a href="https://docs.nestjs.com/fundamentals/injection-scopes#performance">performance,</a> as per docs.</p><p>But there may be scenarios where we need to change the scope — but until you’re sure, just use the DEFAULT scope.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d45e87fd918d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/better-programming/a-deep-dive-into-nestjs-injection-scope-d45e87fd918d">A Deep Dive Into the NestJS Injection Scope</a> was originally published in <a href="https://betterprogramming.pub">Better Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introduction to NestJS Services]]></title>
            <link>https://medium.com/better-programming/introduction-to-nestjs-services-2a7c9a629da9?source=rss-c0dd31a08f42------2</link>
            <guid isPermaLink="false">https://medium.com/p/2a7c9a629da9</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[nestjs]]></category>
            <dc:creator><![CDATA[Santosh Yadav]]></dc:creator>
            <pubDate>Wed, 08 Jan 2020 01:09:35 GMT</pubDate>
            <atom:updated>2020-01-09T13:42:58.100Z</atom:updated>
            <content:encoded><![CDATA[<h4>How we can work with services in NestJS</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*oTbTuBA4_RtKoXCsZ-ybKQ.png" /><figcaption>NestJS logo</figcaption></figure><h3>Service</h3><p>In enterprise applications, we follow the SOLID principle, where S stands for <em>Single Responsibility</em>.</p><p>The controllers are responsible for accepting HTTP requests from the client and providing a response. For providing the response, you may need to connect to some external source for data.</p><p>If we add the code to connect to the external source inside, we are not following the single responsibility principle.</p><p>To avoid this issue, you use services, which will be responsible for providing some data, which can be reused across the application. It can also hold some validation logic or logic to validate users.</p><h3>Creating and Using the Service</h3><p>There are two types of services that can be created in <a href="https://nestjs.com/">NestJS</a>:</p><ul><li>Class-based Provider</li><li>Non-class-based Provider</li></ul><p>Note:<strong> </strong>If you are coming from Angular, there are high chances you already know these concepts.</p><h4>Class-based Provider</h4><p>To create a class-based provider, we can use the CLI command below, the command will create the service inside the product folder.</p><pre>nest generate service product</pre><p>In the product folder, you will find two files:</p><ul><li>product.service.ts (For logic.)</li><li>product.service.spec.ts (For unit testing.)</li></ul><p>You may end up using multiple services for a feature or even multiple types of providers.</p><h4>Using a class-based Provider</h4><p>Now open the product.service.ts file and add the below code, we will move some code from ProductController to ProductService.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b66405722ffb527417da5e9d8a9492a4/href">https://medium.com/media/b66405722ffb527417da5e9d8a9492a4/href</a></iframe><p>As the service is ready now, open product.controller.ts and make the below changes.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7d9c6e5a71dff2a2b43a5f34b5a0874e/href">https://medium.com/media/7d9c6e5a71dff2a2b43a5f34b5a0874e/href</a></iframe><p>The way ProductService is used here is known as <a href="https://en.wikipedia.org/wiki/Dependency_injection">dependency injection</a>.</p><p>Like Controllers, Services need to be registered as well, the CLI does this for us, you can do it manually by adding it to the providers array of the module.</p><pre>providers: [AppService, ProductService]</pre><p>There is more about class-based services which we will cover in upcoming articles.</p><h4>Non-class-based Providers</h4><p>We can also create a service that is not a class-based service. There are two types:</p><ul><li>Tokens: We can use string value as the token.</li><li>Factory: Useful when we have a service that needs some data from another service.</li></ul><h4>Creating tokens</h4><p>You can create an injection token to use as service, to do that, create a new file product.token.ts inside the product folder and add the below code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ca4e000ba129e6470f0b5ca8ee7e268e/href">https://medium.com/media/ca4e000ba129e6470f0b5ca8ee7e268e/href</a></iframe><p>Now open app.module.ts and register the token using the providers property.</p><pre>import { PRODUCT, Product_Token } from &#39;./product/product.token&#39;;</pre><pre>providers: [<br>{<br>    provide : PRODUCT,<br>    useValue: Product_Token<br>}]</pre><p>Next, open the product.service.ts and let’s use this token and add the below code. This is just for demo purposes, in the real-time application we may want to use this value.</p><pre>import { Injectable, Inject } from &#39;@nestjs/common&#39;;<br>import { PRODUCT, Product } from &#39;./product.token&#39;;</pre><pre>constructor(@Inject(PRODUCT) product: Product) <br>{<br>    console.log(product.endPoint);<br>}</pre><p>Once you run the application using the value, endPoint will be logged on the console.</p><h4>Using factory</h4><p>Factories are another type of provider and are available for a very special use case.</p><p>Generally, when we provide a service, they are resolved when the modules are loaded, but there may be instances where we need to create the instance dynamically, this is where we need factories.</p><p>For example, getting the database connection, for a client at runtime deciding which database to connect to.</p><p>Run the below commands to create two services:</p><pre>nest generate service dbprovider<br>nest generate service client</pre><p>Add the below code in client.service.ts.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5f9f54024fc74b09bc0c463548398435/href">https://medium.com/media/5f9f54024fc74b09bc0c463548398435/href</a></iframe><p>Next, open dbprovider.service.ts and add the below code.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/833ea3481bc48893f3decdaabc4a227f/href">https://medium.com/media/833ea3481bc48893f3decdaabc4a227f/href</a></iframe><p>In dbprovider.service.ts, here we are using a string property, if you try to run this application, you will get the error as this is not allowed.</p><p>We want to create the instance of DbproviderService at runtime, so we need to make one more change. Open app.module.ts and remove DbproviderService from the providers property.</p><p>Nest lets us create the factory, create a new file connection.provider.ts, and add the below code.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cc62e7d8c18377bd65fd128f8635c24b/href">https://medium.com/media/cc62e7d8c18377bd65fd128f8635c24b/href</a></iframe><p>Here we are creating a new instance of DbproviderService by getting db from ClientService. You can use multiple services here, you just need to pass them comma-separated in useFactory and the same services need to be added in the inject property.</p><p>Now we are done with the factory, let’s register and use it. Open app.module.ts and add dbConnectionFactory in the providers property.</p><p>Next, open product.service.ts and add the below code.</p><pre>constructor(@Inject(PRODUCT) product: Product,<br>    <strong>@Inject(&#39;ClientConnection&#39;) dbProviderService: DbproviderService</strong>){<br>    console.log(product.endPoint);<br>    <strong>console.log(dbProviderService.getProductsForClient())</strong><br>}</pre><h3>Conclusion</h3><p>We learned about how to create and use different types of providers in NestJS, we used the dependency injection design pattern to use services, which lets you achieve Singel Responsibility as well.</p><p>The services are singleton, but we can also control the scope of Services, which we will see in the next article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2a7c9a629da9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/better-programming/introduction-to-nestjs-services-2a7c9a629da9">Introduction to NestJS Services</a> was originally published in <a href="https://betterprogramming.pub">Better Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>