<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Coding on Arto&#39;s dev time by-products</title>
    <link>https://artosalminen.github.io/series/coding/</link>
    <description>Recent content in Coding on Arto&#39;s dev time by-products</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Sat, 19 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://artosalminen.github.io/series/coding/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How I Built a Vehicle Cost Comparison Tool That Doesn&#39;t Ignore Depreciation</title>
      <link>https://artosalminen.github.io/posts/how-i-built-a-vehicle-cost-comparison-tool/</link>
      <pubDate>Sat, 19 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-i-built-a-vehicle-cost-comparison-tool/</guid>
      <description>&lt;p&gt;I was replacing a 2014 petrol MPV with a used EV. Along the way I collected insurance quotes, checked the vehicle tax bracket, asked for a battery health certificate, got a trade-in offer, and compared a cash price against a dealer&amp;rsquo;s financing plan. Somewhere in the middle of all that I wanted one simple thing: a single number telling me what switching would actually cost per year, compared to just keeping the car I already had.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to Resolve Vitest `EMFILE: too many open files` Errors on a High Thread Count Machine</title>
      <link>https://artosalminen.github.io/posts/how-to-resolve-vitest-mui-icons-emfile-too-many-open-files-error/</link>
      <pubDate>Wed, 02 Jul 2025 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-resolve-vitest-mui-icons-emfile-too-many-open-files-error/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;re running your Vitest suite on a high thread count machine—like an 8-core or 16-core development machine—you may encounter a frustrating error that looks like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;EMFILE: too many open files
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This issue can be cryptic at first, especially when your system doesn&amp;rsquo;t seem anywhere near running out of resources. But the root cause might not be in your system limits—it could be in your import statements.&lt;/p&gt;
&lt;h2 id=&#34;the-unexpected-culprit-named-imports-from-mui&#34;&gt;The Unexpected Culprit: Named Imports from MUI&lt;/h2&gt;
&lt;p&gt;In my case, after hours of digging, I discovered that the error was caused by using &lt;strong&gt;named imports&lt;/strong&gt; from Material UI (MUI) components and icons. These named imports, when used across many test files, were triggering Vitest to open an excessive number of files behind the scenes.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to Update Nested Array Subdocuments Using Main Document Field with Mongoose</title>
      <link>https://artosalminen.github.io/posts/how-to-update-nested-array-with-mongoose/</link>
      <pubDate>Fri, 05 Jul 2024 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-update-nested-array-with-mongoose/</guid>
      <description>&lt;p&gt;Updating nested array subdocuments based on a field in the main document is a common task when working with MongoDB and Mongoose. Here&amp;rsquo;s a simple guide and example to help you accomplish this.&lt;/p&gt;
&lt;h3 id=&#34;plan&#34;&gt;Plan&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;Model.updateMany()&lt;/code&gt; or &lt;code&gt;Model.findOneAndUpdate()&lt;/code&gt; to update multiple or a single document.&lt;/li&gt;
&lt;li&gt;Use an aggregation pipeline (&lt;code&gt;[{}]&lt;/code&gt;) as the second argument to reference document fields.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;$set&lt;/code&gt; stage within the pipeline to update the nested array.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;$$ROOT&lt;/code&gt; variable to reference fields from the main document.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;p&gt;Assume you have a &lt;code&gt;User&lt;/code&gt; model where each user has an array of &lt;code&gt;posts&lt;/code&gt;, and you want to set each post&amp;rsquo;s &lt;code&gt;authorName&lt;/code&gt; field based on the user&amp;rsquo;s &lt;code&gt;name&lt;/code&gt; field.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to sanitize NestJS API responses with Interceptor</title>
      <link>https://artosalminen.github.io/posts/how-to-manipulate-nestjs-response/</link>
      <pubDate>Thu, 11 Jan 2024 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-manipulate-nestjs-response/</guid>
      <description>&lt;p&gt;In any API development project, ensuring that sensitive or unnecessary data is not exposed in the responses is crucial for security and efficiency. In NestJS, interceptors provide a powerful way to manipulate the flow of data. In this blog post, we&amp;rsquo;ll explore how to use an interceptor to sanitize API responses by removing specific properties. We&amp;rsquo;ll also look at how to write tests to ensure the interceptor behaves as expected.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to resolve Intel Graphics Command Center port conflict</title>
      <link>https://artosalminen.github.io/posts/how-to-resolve-intel-control-center-port-conflict/</link>
      <pubDate>Wed, 10 Jan 2024 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-resolve-intel-control-center-port-conflict/</guid>
      <description>&lt;p&gt;For developers working on .NET Core and other development servers, encountering port conflicts can be a common issue. Recently, I came accross with the default port (5000) used for local development server and the Intel(R) Graphics Command Center server. In this blog post, I&amp;rsquo;ll introduce a workaround that involves editing the Windows registry to resolve the conflict and ensure smooth development processes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Understanding the Issue:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Intel(R) Graphics Command Center server, specifically the OneApp.IGCC.WinService.exe executable, by default, utilizes port 5000. However, this port is commonly used for development servers in the .NET Core ecosystem and other software development environments. When both the Intel(R) Graphics Command Center server and a development server attempt to bind to port 5000 simultaneously, a conflict arises.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to create a custom React hook for locale-specific date formatting</title>
      <link>https://artosalminen.github.io/posts/how-to-implement-hook-to-format-dates-in-react/</link>
      <pubDate>Fri, 22 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-implement-hook-to-format-dates-in-react/</guid>
      <description>&lt;p&gt;In this post, I will show you how to create a custom React hook that provides locale-specific date formatting functions. This hook can be useful if you want to display dates and times in different languages and formats depending on the user&amp;rsquo;s preferences.&lt;/p&gt;
&lt;h2 id=&#34;what-is-a-custom-react-hook&#34;&gt;What is a custom React hook?&lt;/h2&gt;
&lt;p&gt;A custom React hook is a function that starts with the word &lt;code&gt;use&lt;/code&gt; and may call other hooks. Custom hooks let you reuse stateful logic between components without duplicating code or introducing complex patterns. You can learn more about custom hooks from &lt;a href=&#34;https://artosalminen.github.io/posts/how-to-implement-hook-to-format-dates-in-react/#here-is-some-further-reading-for-you&#34;&gt;the official React documentation (1)&lt;/a&gt; or &lt;a href=&#34;https://artosalminen.github.io/posts/how-to-implement-hook-to-format-dates-in-react/#here-is-some-further-reading-for-you&#34;&gt;this tutorial (2)&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to capitalize each word of a string in TypeScript</title>
      <link>https://artosalminen.github.io/posts/how-to-capitalize-each-word-in-typescript/</link>
      <pubDate>Tue, 12 Sep 2023 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-capitalize-each-word-in-typescript/</guid>
      <description>&lt;p&gt;In the world of web development and application design, small details can make a big difference. One such detail is the proper capitalization of text, especially when dealing with user-generated content or dynamic data. Ensuring that text appears neat and consistent can significantly enhance the user experience. In this blog post, we&amp;rsquo;ll introduce you to a handy utility function called &lt;code&gt;capitalizeEachWord&lt;/code&gt; that can help you achieve just that.&lt;/p&gt;
&lt;h2 id=&#34;what-is-capitalizeeachword&#34;&gt;What is &lt;code&gt;capitalizeEachWord&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;capitalizeEachWord&lt;/code&gt; function is a TypeScript utility that capitalizes the first letter of each word in a given string while keeping the rest of the letters in lowercase. This function also allows you to specify a word separator, which can be useful when dealing with text containing multiple words separated by a character or whitespace.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to bump version number on Git push for projects using npm</title>
      <link>https://artosalminen.github.io/posts/how-to-bump-version-number-on-git-push/</link>
      <pubDate>Sat, 01 Apr 2023 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-bump-version-number-on-git-push/</guid>
      <description>&lt;p&gt;Note: &lt;strong&gt;This works only from command line&lt;/strong&gt; as user feedback is needed from keyboard to know which part of the version number to bump. It should not break pushing from a GUI tool (e.g. TortoiseGit), but you will not be prompted to update the version number. The positive thing is that the version change is done neatly as a separate commit.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;code&gt;husky&lt;/code&gt; as dev-dependency&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://typicode.github.io/husky/#/?id=install&#34;&gt;instructions&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following script into new file &lt;em&gt;.husky/pre-push&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to collect all npm licenses from multiple subdirectories with Powershell</title>
      <link>https://artosalminen.github.io/posts/how-to-collect-npm-licenses-from-subdirectories/</link>
      <pubDate>Wed, 29 Mar 2023 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-collect-npm-licenses-from-subdirectories/</guid>
      <description>&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;code&gt;license-report&lt;/code&gt; (&lt;a href=&#34;https://www.npmjs.com/package/license-report&#34;&gt;https://www.npmjs.com/package/license-report&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm install -g license-report&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;run the script&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-PowerShell&#34; data-lang=&#34;PowerShell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Get-ChildItem -Directory | &lt;span style=&#34;color:#66d9ef&#34;&gt;foreach&lt;/span&gt; { $_ &amp;gt;&amp;gt; ./licenses.csv ; license-report --output=csv --only=prod --package=./$_/package.json &amp;gt;&amp;gt; ./licenses.csv }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can use the same idea to run other stuff in subdirectories. Just replace the command. Here is an example of &lt;code&gt;git pull&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-PowerShell&#34; data-lang=&#34;PowerShell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Get-ChildItem -Directory -Force -Recurse *.git | ForEach-Object { cd $_.Parent.FullName; Write-Host $_.Parent.FullName; git pull }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>How to update a specified item in a nested array with Mongoose</title>
      <link>https://artosalminen.github.io/posts/how-to-update-specified-item-in-nested-mongo-array-with-mongoose/</link>
      <pubDate>Sat, 11 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-update-specified-item-in-nested-mongo-array-with-mongoose/</guid>
      <description>&lt;p&gt;In this blog post, we&amp;rsquo;ll go over how to update a specified item in a nested array inside a Mongoose document.&lt;/p&gt;
&lt;p&gt;##Setting up the environment&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s set up the environment by creating a Mongoose schema and model. Here&amp;rsquo;s an example schema that has a nested array of items:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mongoose&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mongoose&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;schema&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mongoose&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Schema&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;items&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; [{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; String,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;quantity&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; Number
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Model&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mongoose&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;model&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Model&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;schema&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;##Updating a specified item in a nested array&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to Set Up a Codeserver on Synology NAS</title>
      <link>https://artosalminen.github.io/posts/how-to-set-up-codeserver-on-synology-nas/</link>
      <pubDate>Thu, 09 Feb 2023 10:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-set-up-codeserver-on-synology-nas/</guid>
      <description>&lt;p&gt;Have you ever missed the VSCode on your tablet? Now there is a solution: run the
VSCode on your NAS at home and access it with a browser. That will be possible when you run
&lt;a href=&#34;https://registry.hub.docker.com/r/linuxserver/code-server/&#34;&gt;the Codeserver Docker container&lt;/a&gt; on your NAS.&lt;/p&gt;
&lt;p&gt;Before you do this, you probably want to set up a wildcard certificate and a proxy server on your NAS. That will
enable you to access the NAS outside your local network using HTTPS. How to do it, check this:
&lt;a href=&#34;https://artosalminen.github.io/posts/how-to-set-up-wildcard-certificate-and-proxy-on-synology-nas/&#34;&gt;How to Set Up Wildcard Certificate and Reverse Proxy on Synology NAS&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to use ConfigService in NestJS in application bootstrap</title>
      <link>https://artosalminen.github.io/posts/how-to-use-config-service-in-nestjs-bootstrap/</link>
      <pubDate>Thu, 09 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-use-config-service-in-nestjs-bootstrap/</guid>
      <description>&lt;p&gt;You might want to access the configuration, for example to set the microservice
configuration based on the values from the configuration service.&lt;/p&gt;
&lt;p&gt;One way to do this is to create an application context from the &lt;code&gt;AppModule&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-typescript&#34; data-lang=&#34;typescript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;appContext&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NestFactory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;createApplicationContext&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;BootstrapConfigModule&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;configService&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;appContext&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;ConfigService&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SERVICE_PORT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;configService&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;SERVICE_PORT&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;appContext&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;close&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But a better idea is to use a &amp;ldquo;temporary&amp;rdquo; module to avoid double instantiation of the whole app.
See a full example below.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-typescript&#34; data-lang=&#34;typescript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;import&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;Module&lt;/span&gt; } &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;@nestjs/common&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;import&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;ConfigService&lt;/span&gt; } &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;@nestjs/config&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;import&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;NestFactory&lt;/span&gt; } &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;@nestjs/core&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;import&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;MicroserviceOptions&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;Transport&lt;/span&gt; } &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;@nestjs/microservices&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;import&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;AppModule&lt;/span&gt; } &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;./app.module&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Bootstrap configuration module is needed to avoid
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// doing the DI resolution twice
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;@Module&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;providers&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#a6e22e&#34;&gt;ConfigService&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;exports&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#a6e22e&#34;&gt;ConfigService&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;BootstrapConfigModule&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;async&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;bootstrap() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;appContext&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NestFactory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;createApplicationContext&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;BootstrapConfigModule&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;configService&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;appContext&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;ConfigService&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SERVICE_PORT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;configService&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;SERVICE_PORT&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;appContext&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;close&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;app&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NestFactory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;createMicroservice&lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;MicroserviceOptions&lt;/span&gt;&amp;gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;AppModule&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;transport&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;Transport.TCP&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;options&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;port&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;SERVICE_PORT&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;app&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;listen&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;bootstrap&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Why would you need to use the configuration service instead of &lt;code&gt;process.env&lt;/code&gt; you might ask.
Well, while that may work, it doesn&amp;rsquo;t offer any type safety or support for fallbacks.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How to merge a nested list in Mongo document with another found in adjacent collection</title>
      <link>https://artosalminen.github.io/posts/how-to-merge-nested-list-to-collection-with-mongo-aggregate/</link>
      <pubDate>Sun, 05 Feb 2023 08:04:11 +0200</pubDate>
      
      <guid>https://artosalminen.github.io/posts/how-to-merge-nested-list-to-collection-with-mongo-aggregate/</guid>
      <description>&lt;p&gt;Let&amp;rsquo;s consider a situation where you have two collections, &lt;code&gt;houses&lt;/code&gt; and &lt;code&gt;people&lt;/code&gt;. Each house has a collection
of key holders, which link to the persons collection with their IDs. Key holders list also holds information
when the key was given for the identified person.&lt;/p&gt;
&lt;p&gt;In bson, the situation in the database looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;houses&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;ObjectId(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5fba17c1c4566e57fafdcd7e&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;address&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Main street 1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyHolders&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyDelivered&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2022-02-02T02:02:02&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;personId&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5fbb5ab778045a985690b5fc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyDelivered&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2021-01-01T01:01:01&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;personId&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5fbb5ab778045a985690b5fd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;ObjectId(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5fba17c1c4566e57fafdcd7f&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;address&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Broadway 3&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyHolders&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyDelivered&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1993-03-03T03:03:03&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;personId&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5fbb5ab778045a985690b5fc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;persons&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;ObjectId(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5fbb5ab778045a985690b5fc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Jack Bauer&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;ObjectId(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5fbb5ab778045a985690b5fd&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;James Bond&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can also do some mapping for the source list, for instance convert
foreign keys from strings to ObjectIds.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
