<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marcin Milewicz</title>
    <description>The latest articles on DEV Community by Marcin Milewicz (@marcinmilewicz).</description>
    <link>https://dev.to/marcinmilewicz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1115031%2Fc73df9c1-6c69-4a5a-8f33-51added3836f.png</url>
      <title>DEV Community: Marcin Milewicz</title>
      <link>https://dev.to/marcinmilewicz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marcinmilewicz"/>
    <language>en</language>
    <item>
      <title>Why Your Angular Tests Probably Smell</title>
      <dc:creator>Marcin Milewicz</dc:creator>
      <pubDate>Sat, 08 Jul 2023 09:34:07 +0000</pubDate>
      <link>https://dev.to/marcinmilewicz/why-your-angular-tests-probably-smell-4fkj</link>
      <guid>https://dev.to/marcinmilewicz/why-your-angular-tests-probably-smell-4fkj</guid>
      <description>&lt;h2&gt;
  
  
  Why Your Angular Tests Probably Smell
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common pitfalls encountered when testing Angular projects
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NAQO4tru--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/8926/1%2Aw4nE9TCy8pU2VG3g4YXlJQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NAQO4tru--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/8926/1%2Aw4nE9TCy8pU2VG3g4YXlJQ.jpeg" alt="Photo by [Aaron Burden](https://unsplash.com/@aaronburden?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/relax?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText)" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Testing an Angular application is inherently straightforward. Angular frameworks are built from the ground up so their abstractions are easy to test. Default loose architecture, splitting logic into components, directives, services, modules or pipes — all of these significantly help us in the testing process itself. If we follow proven patterns and produce truly testable code, testing shouldn’t be a nuisance — it should be something that facilitates reliable code development.&lt;/p&gt;

&lt;h3&gt;
  
  
  You’ll never walk alone
&lt;/h3&gt;

&lt;p&gt;Moreover, Angular does not leave us alone on the battlefield — it equips us with a powerful set of tools that facilitate and accelerate writing tests.&lt;/p&gt;

&lt;p&gt;As Angular users, it’s our responsibility to learn these tools thoroughly. In this Angular Testing Series of articles, I would like to present the typical and correct use of built-in unit testing mechanism in Angular, based on prepared examples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LBj9SY7k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AoUXa5poUvq936fSUkNcpkA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LBj9SY7k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AoUXa5poUvq936fSUkNcpkA.jpeg" alt="Photo by [Randy Fath](https://unsplash.com/@randyfath?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/team?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText)" width="640" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad testing habits
&lt;/h3&gt;

&lt;p&gt;Bad habits often come from temptation. I’ve noticed that we (developers) also often give in to one temptation: &lt;em&gt;copying a code for unit testing&lt;/em&gt;. This technique has two faces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;We can stick to a consistent way in testing and accelerate our productivity and bringing value.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or, if we do not know what we’re actually copying:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;We can contribute to smearing smelly pieces of code among all the tests in the projects.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I would like to focus on those smelly pieces of code in unit tests that I have encountered in various Angular projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Component Testing
&lt;/h2&gt;

&lt;p&gt;Let’s assume this is our component under test:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
We would like to verify whether Full Names is rendered into the  tag. Let’s look at the following test:&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
When we run jest everything works:

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2dlBXUn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AGYJ1Y-RpeduP_QOJPA8yRg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2dlBXUn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AGYJ1Y-RpeduP_QOJPA8yRg.png" alt="" width="583" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But something smells — can you tell what it is?&lt;/p&gt;

&lt;p&gt;Let’s take a look at the last test and see what’s going on there. ngOnInit is called, change detection is simulated in fixture, and assertion is made when the fixture template is ready. Apparently, everything is OK, but this is a distortion of the truth and a bad simulation of the component’s life cycle. In this example, everything will work out as expected. However, the method ngOnInit is called twice. The change detection is also performed one more time.&lt;/p&gt;
&lt;h3&gt;
  
  
  How should we handle it?
&lt;/h3&gt;

&lt;p&gt;What should we do to make our test reflect reality is to get rid of the ngOnInit call? Instantiated fixture:ComponentFixture has appropriate responsibility and when we call on it detectChanges method, we can trust that the individual component lifecycle methods will be executed automatically.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
In the above gist, I changed one more thing. The async function was replaced with waitForAsync. Why? Because in Angular 10, the async function is finally marked as deprecated and we can expect that in Angular 12 we won’t see it at all.
&lt;h3&gt;
  
  
  Don’t care about rendering in tests
&lt;/h3&gt;

&lt;p&gt;Quite often we find and write component tests where it is not important to check if actual values are generated in the DOM. Whether this is a good or bad approach depends only on your test findings and objectives, but I would like to mention another common mistake related to this type of test.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Now, we want to verify only if the field title has the expected value assigned. It seems that everything is fine, and the test itself is deterministic, but something stinks about the solution presented.

&lt;p&gt;As mentioned previously, the fixture reflects the template with the generated DOM model. In the above test, we don’t check anything in DOM. Is it worth using resources to create fixture, indeed? This is a typical example of an isolation test. If all tests gathered in the spec collection are isolated, then the entire spec should be implemented, like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In isolated tests, we have to remember to call appropriate lifecycle methods like ngOnInit&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Isolated tests are significantly faster than shallow tests with ComponentFixture. Even for such simple tests, the difference in resource usage and total test time is significant.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oiTL67sk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AuyDT_032HLTMQ-h4gQe9hg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oiTL67sk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AuyDT_032HLTMQ-h4gQe9hg.png" alt="" width="660" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Asynchronous Services and Events
&lt;/h2&gt;

&lt;p&gt;In Angular’s project development, we deal with asynchronous operations most of the time. XHR requests, handling of render/browser events, debouncing of inputs entered by users are all asynchronous tasks, so tests should handle them appropriately.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VgvFRwW4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3840/1%2AZvoOP_fhRWToiVIhC1BH1g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VgvFRwW4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3840/1%2AZvoOP_fhRWToiVIhC1BH1g.jpeg" alt="Photo by [Harry Sandhu](https://unsplash.com/@harryxsandhu?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText) on [Unsplash](https://unsplash.com/@harryxsandhu?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText)" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s analyze the sample scenario with a straightforward service which fetches data as XHRs:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The above service is used by the smart domain component FullNameListComponent.&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
We would like to test fullNames$ stream. This time, we use ComponentFixture, due to the fact that it’s a convenient way of providing stubs to Angular DI.&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Two basic tests can look like this:&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The tests are passed. Is it OK? Obviously, not! To find out why I slightly modify the second test:

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should fullNames be triggered on name change', () =&amp;gt; {
  const expectedFullNames = *FAKE_NAMES*;

  component.fullNames$.subscribe((fullNames) =&amp;gt; {
    expect(fullNames).toEqual(**null**);
  });

  component.name = 'John';
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;I modified assertation to expect fullNames as null, which is incorrect. The test is still passing. What’s wrong?&lt;/p&gt;
&lt;h3&gt;
  
  
  fakeAsync for help
&lt;/h3&gt;

&lt;p&gt;Aside from the fact that so-called subscribe-assert is not the best method we can use for stream testing, we often forget about one thing. If the stream runs asynchronously, the test should take this fact into account. Fortunately, Angular provides us with useful tooling: a special fakeAsync zone.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('should fullNames be triggered on name change', fakeAsync(() =&amp;gt; {
  const expectedFullNames = ***FAKE_NAMES***;

  component.fullNames$.subscribe((fullNames) =&amp;gt; {
    expect(fullNames).toEqual(null);
  });

  component.name = 'John';
  tick();
}));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Now, the test runner is able to identify that assertion is not correct:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cafvze7---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2328/1%2AMjPSErydpqX8HGcKjCa7Fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cafvze7---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2328/1%2AMjPSErydpqX8HGcKjCa7Fw.png" alt="" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don’t want to explain exactly whatfakeAsync is here, because that’s not the purpose of this article. However, we must always remember that if we deal with asynchrony, then we should also take it into account in tests.&lt;/p&gt;

&lt;p&gt;There is another smelly thing in the above test method. Let’s look at our stub:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Here we simulate returning Observable with fake data. It’s a popular approach, but is it correct? Not at all.&lt;/p&gt;

&lt;p&gt;I refer here to a very good &lt;a href="https://netbasal.com/testing-observables-in-angular-a2dbbfaf5329"&gt;article&lt;/a&gt; from &lt;a href="https://dev.toundefined"&gt;Netanel Basal&lt;/a&gt;. He explains well why of is not an appropriate function to use to fake an API response.&lt;/p&gt;

&lt;p&gt;In short, of function provides synchronous data, while the response to an XHR is asynchronous and treated as a macrotask. Faking asynchronous data with synchronous invocation is cheating and stinks. It increases code coverage, but the quality of such tests is questionable.&lt;/p&gt;

&lt;p&gt;As providing an appropriate scheduler to the of function is deprecated, I recommend the following approach:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ***asyncScheduler***, Observable, scheduled } from 'rxjs';

getFullNames(name: string): Observable&amp;lt;FullName[]&amp;gt; {
  return scheduled([***FAKE_NAMES***], ***asyncScheduler***);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6BTWKO2U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3840/1%2A2NjubR0EEZl9wTpicqtpaQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6BTWKO2U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/3840/1%2A2NjubR0EEZl9wTpicqtpaQ.jpeg" alt="Photo by [jcob nasyr](https://unsplash.com/@j_cobnasyr1?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/island?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText)" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;How to avoid such mishaps in tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Try to follow Red/Green/Refactor technique. If you don’t use TDD methodology, try to fail your tests on purpose.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;See and learn about two features that Angular gives us: &lt;a href="https://angular.io/api/core/testing/waitForAsync"&gt;waitForAsync&lt;/a&gt; and &lt;a href="https://angular.io/api/core/testing/fakeAsync"&gt;fakeAsync&lt;/a&gt;. Be aware of the differences between them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don’t use of for faking data. In most cases, you don’t notice any differences. However, there is a framework hacking. Trust the provided fakeAsync zone to simulate synchronous execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All examples are gathered in the &lt;a href="https://github.com/marcinmilewicz/angular-testing"&gt;repository&lt;/a&gt; on my Github.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;I would be grateful also if you tell me what your consternation with Angular testing is. I will be happy to prepare a pragmatic solution and assist you.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How does APP_INITIALIZER work? So what do you need to know about dynamic configuration in Angular?</title>
      <dc:creator>Marcin Milewicz</dc:creator>
      <pubDate>Fri, 07 Jul 2023 08:26:29 +0000</pubDate>
      <link>https://dev.to/marcinmilewicz/how-does-appinitializer-work-so-what-do-you-need-to-know-about-dynamic-configuration-in-angular-5482</link>
      <guid>https://dev.to/marcinmilewicz/how-does-appinitializer-work-so-what-do-you-need-to-know-about-dynamic-configuration-in-angular-5482</guid>
      <description>&lt;h2&gt;
  
  
  How does APP_INITIALIZER work? So what do you need to know about dynamic configuration in Angular?
&lt;/h2&gt;

&lt;p&gt;When we develop an application designed to run on multiple environments, we have to decide how to provide a configuration of appropriate variables depending on those environments&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;TLDR; 📕&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;environment.ts&lt;/em&gt; is not the best way to provide an environment configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;do not introduce environmental configuration in build-time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Special injection token called &lt;em&gt;APP_INITIALIZER&lt;/em&gt; is used for convenient and effective external configuration providing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I’ve prepared for you the minimal example which solves this problem by using &lt;em&gt;APP_INITIALIZER&lt;/em&gt;. You can find it on &lt;a href="https://stackblitz.com/edit/angular-configuration-with-app-initializer"&gt;StackBlitz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  First round ❓
&lt;/h2&gt;

&lt;p&gt;The simplest example of an environmental variable is API configuration. Commonly, we use a different URL depending on target environment. For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;dev: &lt;a href="https://yourdomain.dev.org/api/resources"&gt;https://yourdomain.dev.org/api/resources&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;test: &lt;a href="https://yourdomain.test.org/api/resources"&gt;https://yourdomain.test.org/api/resources&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;prod: &lt;a href="https://yourdomain.prod.org/api/resources"&gt;https://yourdomain.prod.org/api/resources&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In many Angular projects that I have seen, this problem has been solved by using analogous files provided by the Angular framework: &lt;em&gt;environment.dev.ts&lt;/em&gt;, &lt;em&gt;environment.test.ts&lt;/em&gt; and &lt;em&gt;environment.prod.ts&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;These files for our example would look like this&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
It cannot be said that this approach is very bad or does nor meet the assumptions made. However, look what happens if you choose this way to keep your variables and want to complete the full cycle of application delivery to production.

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If everything works fine locally, the application is built on the development environment using the environment.dev.ts file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If everything works fine in the development environment, we can promote it to the test environment. In order for the application to run in the test environment, the application must be rebuilt using the environment.test.ts file this time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the application has been tested in the test environment and is ready for production, we have to take the same steps. So we need to rebuild the application again using environment.prod.ts&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Please note one fact. The application must be built three times (&lt;strong&gt;!!!&lt;/strong&gt;) before it goes from the developer’s hand to the production environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  The first conclusions that arise are: 👈
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you want to deliver a small change to production, you have to repeat the same building process several times, which will significantly extend the delivery time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can never be sure that a tested artifact from the dev environment or test will build correctly on the prod environment&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Based on these conclusions and my own experience, I can safely and honestly tell you that environment.ts files are not a good place to hold most types of configuration. More precisely:&lt;/p&gt;

&lt;p&gt;Certain configuration types should not be shipped when building an artifact. Storing environment-dependent variables in Angular’s environment.ts is the anti-pattern. Unfortunately, common anti-pattern.&lt;/p&gt;

&lt;p&gt;So if you choose not to hold your configuration in environment.ts, what can you do?&lt;/p&gt;

&lt;h2&gt;
  
  
  Round 2 — APP_INITIALIZER approach 💪
&lt;/h2&gt;

&lt;p&gt;Angular’s Injection Token APP_INITIALIZER comes with great help, thanks to which you can introduce additional initialization functions to your application. This functionality of the Angular framework ensures that the provided functions are executed when an application is started, while an application is still being initialized. These functions return a Promise object and an Angular’s app will not be initialized until it is being executed.&lt;/p&gt;

&lt;p&gt;Is is a proper way to pass the configuration?&lt;/p&gt;

&lt;h3&gt;
  
  
  Of course! Even in the official Angular framework documentation, you can read: 📕
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;You can, for example, create a factory function that loads language data or an external configuration, and provide that function to the &lt;a href="https://angular.io/api/core/APP_INITIALIZER"&gt;APP_INITIALIZER&lt;/a&gt; token. That way, the function is executed during the application bootstrap process, and the needed data is available on startup.&lt;br&gt;
 &lt;a href="https://twitter.com/marcin_milewicz"&gt;Follow me&lt;/a&gt; on Twitter if you want to be updated about new great Angular and frontend stuff! &lt;em&gt;😄&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Runtime configuration in practice
&lt;/h3&gt;

&lt;p&gt;Firstly, we need a file to hold configuration details in, and it will not be part of JavaScript artifacts which are built when &lt;em&gt;ng build&lt;/em&gt; is executed. This configuration file should be downloaded on demand when the application is initialized.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
for the following assumed configuration model.&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
We also need a service that has the responsibility to download the configuration and make it available while the application is running.&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The last step is to use the above method with the &lt;em&gt;APP_INITIALIZER&lt;/em&gt; token. It is used in the providers section for a specific &lt;em&gt;NgModule&lt;/em&gt;.

&lt;p&gt;It’s worth to consider creating a separate module dedicated to fetching configuration instead of adding the following code to the main app.module.ts&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The &lt;em&gt;loadConfiguration&lt;/em&gt; function is provided with the &lt;em&gt;useFactory&lt;/em&gt; parameter. The function itself looks like this&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
By following the steps above, we ensure the following behavior for our application

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;when the application is started, the &lt;em&gt;loadConfiguration&lt;/em&gt; from the &lt;em&gt;ConfigurationLoader&lt;/em&gt; instance is run and it starts downloading the configuration from &lt;em&gt;/assets/config/configuration.json&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the application waits until the configuration is loaded from &lt;em&gt;/assets/config/configuration.json&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the application is initialized and the configuration is available through &lt;em&gt;getConfiguration&lt;/em&gt; method of &lt;em&gt;ConfigurationLoader&lt;/em&gt; instance&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The magic is that the configuration placed in the &lt;em&gt;assets&lt;/em&gt; directory is not taken into account at the time of building. You can modify the contents of the &lt;em&gt;assets&lt;/em&gt; directory at any time without rebuilding the app. So the scheme for delivering the application to production now looks like this&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If everything works fine locally, the application is built on the development environment and the &lt;em&gt;/assets/config/configuration.json&lt;/em&gt; file is delivered externally&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If everything works fine in the development environment, the application is promoted to the test environment. In order to run the application in the test environment, we take the artifact already built and replace the &lt;em&gt;/assets/config/configuration.json&lt;/em&gt; file, which this time contains the configuration specific to the test environment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the application is passed the tests in the test environment and is ready to go to the production, we take the same artifact again, push it to the prod environment and replace the analogous configuration file &lt;em&gt;/assets/config/configuration.json&lt;/em&gt; for the prod environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Wow! By using &lt;em&gt;APP_INITIALIZER&lt;/em&gt; and runtime configuration approach, you are able to limit the process of building the application in the entire delivery cycle to only one time! Frankly speaking, this one time is the maximum number of times according to the best practices. You also ensured that your built artifact on the initial environment is equal to a single byte with what is placed in the final environment.&lt;/p&gt;

&lt;p&gt;If you want to see how this solution works, I have prepared a live example on &lt;a href="https://stackblitz.com/edit/angular-configuration-with-app-initializer"&gt;***StackBlitz&lt;/a&gt;*** for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XhFjOgaI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/6000/1%2A3XUVentW0YdEgmpTcEL7Fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XhFjOgaI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/6000/1%2A3XUVentW0YdEgmpTcEL7Fw.png" alt="" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;environment.ts&lt;/em&gt; is &lt;strong&gt;not the best way&lt;/strong&gt; to provide an environment configuration in Angular ecosystem. We can safely name it as anti-pattern.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;do not introduce&lt;/strong&gt; an environment configuration which is runtime-dependant&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Injection Token — APP_INITIALIZER is used for &lt;strong&gt;convenient and effective&lt;/strong&gt; external configuration delivery in Angular ecosystem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I have prepared for you a minimal example of solving the problem by using &lt;strong&gt;APP_INITIALIZER&lt;/strong&gt;. You will find him on &lt;a href="https://stackblitz.com/edit/angular-configuration-with-app-initializer"&gt;***StackBlitz&lt;/a&gt;***&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The feedback is important and best way in medium.com is clicking multiple times on clap icon 👏 on your left . If you click on it, I will know that my articiles has value for you ❤️ and I will be encouraged to write more 📙. Thanks!
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://twitter.com/marcin_milewicz"&gt;Follow me&lt;/a&gt; on Twitter if you want to be updated about new great Angular and frontend stuff! &lt;em&gt;😄&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
