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

<channel>
	<title>Programming Archives - CodeJourney.net</title>
	<atom:link href="https://www.codejourney.net/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.codejourney.net/category/programming/</link>
	<description>Building real-world software with AI 🤖</description>
	<lastBuildDate>Tue, 05 May 2026 16:46:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://i0.wp.com/www.codejourney.net/wp-content/uploads/2018/10/cropped-512px-na-512px-JPEG-BEZ-NAPISU-1.jpg?fit=32%2C32&#038;ssl=1</url>
	<title>Programming Archives - CodeJourney.net</title>
	<link>https://www.codejourney.net/category/programming/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">123174533</site>	<item>
		<title>Everything Has Changed</title>
		<link>https://www.codejourney.net/everything-has-changed/</link>
					<comments>https://www.codejourney.net/everything-has-changed/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 05 May 2026 07:09:52 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[llm]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4978</guid>

					<description><![CDATA[<p>I first started drafting this post in December 2025. Couldn&#8217;t get myself to actually publish it. Classical writing blockage. But here I am, again. Putting it shortly: everything has changed since I last posted here. EVERYTHING. This blog post is my retrospective on the last 18 months. Personal. Self-healing. Unblocking. Moved back to Poland After&#8230;</p>
<p>The post <a href="https://www.codejourney.net/everything-has-changed/">Everything Has Changed</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I first started drafting this post in December 2025. Couldn&#8217;t get myself to actually publish it. Classical writing blockage. But here I am, again.</p>



<p class="wp-block-paragraph">Putting it shortly: everything has changed since I last posted here. <strong>EVERYTHING</strong>.</p>



<p class="wp-block-paragraph">This blog post is my retrospective on the last 18 months. Personal. Self-healing. Unblocking.</p>



<span id="more-4978"></span>



<h2 class="wp-block-heading">Moved back to Poland</h2>



<p class="wp-block-paragraph">After 6 years of <a href="https://www.codejourney.net/how-programming-helped-me-becoming-a-digital-nomad/">traveling and working remotely</a>, my wife and I decided to come back to Poland. When we left, there was no specific goal. We just wanted to explore and live this life (and we did to the fuuuuuullest and we still are!). Somewhere in the back of our heads there was this idea of finding a better place. An ideal place to settle down. But as it turned out, no place is perfect. Even living in the paradise of Indonesia for 15 months had its flaws <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f937-200d-2642-fe0f.png" alt="🤷‍♂️" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<p class="wp-block-paragraph">However, the best side effect (or maybe the <em>main</em> effect) of living in several different countries is the new perspective. Being back in Poland now (which is an amazing country) hits completely different than it was those ~7 years ago. I appreciate it 100000 times more. I am constantly amazed by little things that I previously took for granted or didn&#8217;t even notice. This gives me a unique perspective on living here and I really appreciate that.</p>



<p class="wp-block-paragraph">Longer trips and workations will resume, but for now I am proudly calling myself a self-retired digital nomad <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Switched to Mac</h2>



<p class="wp-block-paragraph">In mid-2025, I decided to switch to a Mac. I&#8217;ve always been a .NET guy, on Windows since 1998 <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" />, but my new job eliminated working with legacy desktop stuff, so I could make the move. I bought a 16-inch MacBook M4 Pro with 48GBs of RAM and 512 GBs of disk space. I was a little worried about the disk space, but after ~1 year it&#8217;s just enough for me. Just checked and I still have 260GBs of free space (did the cleanup a few days ago though, before that it was around 180 GBs free). My daily toolbox includes Rider, VS Code, .net&amp;npm, Claude Code, 6-10 docker containers and a few smaller local LLMs running in LM Studio.</p>



<p class="wp-block-paragraph">I wouldn&#8217;t believe saying this 2 years ago, but <strong>switching to Mac was the best decision ever</strong>. There&#8217;s even nothing to write about here. It&#8217;s just amazing and I can finally work 8-10 hours without charging it &#8211; just in time when I retired from full-time nomading <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Started working for a fully remote SaaS company</h2>



<p class="wp-block-paragraph">I also started working for an Australian, fully remote SaaS company. We are building a platform for healthcare professionals, mostly from Australia, US and the UK. The teams are distributed all over the world, but we are not a corporation (there&#8217;s probably around 90 of us currently, including ~40 engineers).</p>



<p class="wp-block-paragraph">It&#8217;s been challenging for me to move from a software house to working on an actual SaaS product, which comes with more responsibility, but also more possibilities and influence on the product.</p>



<h2 class="wp-block-heading">AI&#8230; AI everywhere <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f440.png" alt="👀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<p class="wp-block-paragraph">I didn&#8217;t want to start with this point, but this is HUGE. When writing my <a href="https://www.codejourney.net/real-net-interview-questions-2024-2025/">last article here, in December 2024</a>, the only AI I used was probably the tab completion with GitHub Copilot in VS Code. Early days <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Since then, my working turned upside down.</p>



<p class="wp-block-paragraph">I hope to write down more about it one day, but TLDR: </p>



<p class="wp-block-paragraph">I went through different tools (Cursor, Zed) to &#8211; for now &#8211; settle down with Claude Code and Codex, which I use every day. Today, I write the definitive most of my code with AI. I also research with AI. I&#8217;m building features leveraging LLMs, which bring amazing value to the users. I&#8217;m thinking much more about the product, the actual usage of it, the value for the end users, the architecture, security, deployments than about which C# features to use or how to structure the code on the lowest level. I don&#8217;t remember when I last visited StackOverflow <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f916.png" alt="🤖" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">And it&#8217;s not only work! AI also completely refactored my personal life. I make appointment notes with AI. I research stuff to buy with AI. I rarely use pure Google search. I vibe code apps for solving my daily issues like managing home finances or learning a new language. Fun times <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Code generation</h2>



<p class="wp-block-paragraph">I&#8217;ve already mentioned this above, but code generation should have its own paragraph. I&#8217;ve never been a developer who loves to write code. I always enjoyed everything around it &#8211; analyzing customers&#8217; needs, finding architectures that solve the issue, connecting different dots in the project, coordinating cross-team cooperation, maintaining the documentation or even <a href="https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/">writing tests</a>. So code generation with AI is something I welcomed with open arms <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<p class="wp-block-paragraph">As I&#8217;ve already mentioned, the vast majority of my code is AI-generated. I focus more on planning and reviewing it. It opens so many possibilities. I am also never hesitant or feeling blocked to start working on a task, because I always have a place to start &#8211; an AI agent.</p>



<h2 class="wp-block-heading">AI Devs course</h2>



<p class="wp-block-paragraph">A huge step in my AI journey was taking and completing the <a href="https://www.linkedin.com/posts/dawidsibinski_check-out-dawid-sibi%C5%84skis-aidevs-3-agents-activity-7368345627769909248-oSY8?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAABctqEwB_ctnKdITBCHjWc9jCy_2q4GT-fo">AI Devs course</a>. It&#8217;s been crazy 5 weeks of intensive learning about LLMs, AI agents and multimodality. Very practical, focused on solving real tasks. The course equipped me with solid foundations of the LLMs before the biggest shift with Claude Code and Opus 4.5 happened. It reminds me of <a href="https://www.codejourney.net/net-internals/">diving into .NET internals years ago</a>, just so today I can understand C# and the framework much better. It also opened my eyes to the possibilities LLMs give us. Things that were impossible (or very hard) to realize with pure code are now at our fingertips.</p>



<h2 class="wp-block-heading">Attended non-technical tech conference</h2>



<p class="wp-block-paragraph">By the end of September 2025 I <a href="https://www.linkedin.com/posts/dawidsibinski_for-the-last-2-days-i-had-a-pleasure-to-attend-activity-7377408996519055360-I8kB?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAABctqEwB_ctnKdITBCHjWc9jCy_2q4GT-fo">attended Beyond Code conference</a>. It&#8217;s probably the only non-technical IT conference in Poland. The talks and discussions were focused around well-being, mindfulness at work, soft skills and psychology. Very needed type of events, especially in this crazy AI era.</p>



<h2 class="wp-block-heading">Gave my first public talk</h2>



<p class="wp-block-paragraph">Another significant event was <a href="https://www.linkedin.com/posts/dawidsibinski_i-gave-my-first-public-talk-at-debbug-it-activity-7424909929423159297-Zzuh?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAABctqEwB_ctnKdITBCHjWc9jCy_2q4GT-fo">giving my first public talk at a local meetup in Bielsko-Biala</a>. I presented my approach to working with AI tools and how we transformed the software development at the company I work for. The feedback I got was very positive and it was a very rewarding experience <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">I was invited to a podcast</h2>



<p class="wp-block-paragraph">Last but no least, as kind of an aftermath of the meetup talk, I was invited to an AI podcast episode. <a href="https://www.linkedin.com/in/psmyrdek/">Przemek</a>, who is one of the co-founders of <a href="https://przeprogramowani.pl/">Przeprogramowani</a> (an initiative where the guys teach about AI development, basically), happened to attend my talk at the meetup and later invited me to record the podcast episode. We <a href="https://www.youtube.com/watch?v=ZA_VLUE21Sw">talked about AI again</a>, this time in more depth. I also shared a little about digital nomad life. The episode got quite a lot of traction and positive feedback.</p>



<h2 class="wp-block-heading">So&#8230; what&#8217;s next?</h2>



<p class="wp-block-paragraph">Ufff, I&#8217;m very happy that I got to this point. I really wanted to publish this article. I know it&#8217;s very personal, but that&#8217;s what I needed.</p>



<p class="wp-block-paragraph">To be fully honest, I have no idea what to do with this blog. When I finally sit to it, I really like writing. This is by the way very common in my life recently &#8211; I commit to many projects that I really enjoy when <em>actually</em> working on them, but then I have <em>no time to even start</em> working on them, because they are too many <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f926-200d-2642-fe0f.png" alt="🤦‍♂️" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">AI have completely reshaped the way I work and also changed my identity. I don&#8217;t anymore see myself as someone who will &#8220;help you becoming an independent full stack .NET web developer&#8221;, as the description in the sidebar of this page still says <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> The free PDF I&#8217;m sharing as part of newsletter signup is completely out-of-date now. I don&#8217;t even know how I would need to reshape it to fit the current AI era <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f937-200d-2642-fe0f.png" alt="🤷‍♂️" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">I don&#8217;t really know what&#8217;s next. Next for this blog, as well as for my activity in the IT community. Everything changes so fast&#8230; But maybe this is what we all found ourselves in right now? Maybe we just need to accept the current pace of things, outdated websites and blogs, as well as AI tools that become legacy a few days after being released? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/everything-has-changed/">Everything Has Changed</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/everything-has-changed/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4978</post-id>	</item>
		<item>
		<title>Real .NET Interview Questions (2024/2025)</title>
		<link>https://www.codejourney.net/real-net-interview-questions-2024-2025/</link>
					<comments>https://www.codejourney.net/real-net-interview-questions-2024-2025/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 03 Dec 2024 16:16:31 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4909</guid>

					<description><![CDATA[<p>From September to November 2024 I had a &#8220;pleasure&#8221; of looking for a new programming job as a senior full stack .NET developer. I was dedicated full time to this process as I have still been on a sabbatical break. It took me a bit more than 2 months, during which I submitted around 150&#8230;</p>
<p>The post <a href="https://www.codejourney.net/real-net-interview-questions-2024-2025/">Real .NET Interview Questions (2024/2025)</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">From September to November 2024 I had a &#8220;pleasure&#8221; of looking for a new programming job as a senior full stack .NET developer. I was dedicated full time to this process as <a href="https://www.codejourney.net/what-im-doing-with-two-months-of-full-time-coding-for-fun/">I have still been on a sabbatical break</a>. It took me a bit more than 2 months, during which I submitted around 150 well-crafted applications, took part in 25 full technical recruitment processes and was asked hundreds of .NET interview questions.</p>



<p class="wp-block-paragraph">In this article, I&#8217;m sharing a compiled list of the most popular .NET interview questions I was asked during all those interviews. They represent real questions asked on job interviews for a software developer with almost 10 years of experience. Hope you enjoy it <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4909"></span>



<h2 class="wp-block-heading">Technical .NET Interview Questions</h2>



<ol class="wp-block-list">
<li>What&#8217;s the difference between a <code>class</code> and an <code>interface</code>?</li>



<li>What&#8217;s the difference between an <code>abstract class</code> and an <code>interface</code>?</li>



<li>What is the difference between a <code>class</code> and a <code>struct</code>?</li>



<li>Describe the difference between overriding and overloading in C#</li>



<li>Can a <code>structure</code> have <code>virtual</code> methods?</li>



<li>Explain the difference between <code>GET</code>, <code>POST</code> and <code>PATCH</code> in HTTP APIs</li>



<li>Is there any limit go the <code>GET</code> request&#8217;s length? If yes, where is such a limit configured? What about <code>POST</code>?</li>



<li>How would you secure your WebAPI?</li>



<li>What is the flow of generating, obtaining and passing JWT token in a .NET application?</li>



<li>When using JWT tokens in an API, how does the server ensure it talks to a legitimate client?</li>



<li>Is the API security compromised when the user&#8217;s JWT token is stolen?</li>



<li>What is the difference between <code>IEnumerable</code> and <code>IQueryable</code> in the context of Entity Framework?</li>



<li>What are the dependency injection scopes in ASP.NET?</li>



<li>How can dependency injection be helpful in testing?</li>



<li>What is <code>IHttpClientFactory</code> used for and which issues does it help to eliminate?</li>



<li>What is wrong with creating <code>HttpClient</code> manually?</li>



<li>What would you choose for implementing communication between microservices: REST or a message broker? What would you consider when making such a choice?</li>



<li>What would you do as a backend developer when frontend developers are blocked because they are missing an API endpoint from your side?</li>



<li>What is the size of stack in .NET?</li>



<li>What are value and reference types? What is the difference between them? Give a practical example</li>



<li>Which objects go on Large Object Heap?</li>



<li>What is JIT compilation?</li>



<li>Describe the strategies for delivering a message in a message queue</li>



<li>When is <code>Dispose</code> method called on a class implementing <code>IDisposable</code>?</li>



<li>What is the difference between <code>Dispose</code> and <code>Finalize</code>?</li>



<li>What is SOLID? Can you elaborate on each SOLID acronym?</li>



<li>You are assigned a task to process a large piece of text by inserting and changing many parts of it. Which of the following would you use for that task: <code>string</code>, <code>StringBuilder</code>, <code>StringWriter</code> or <code>StringReader</code>?</li>



<li>What&#8217;s the difference between Repository and Query Object patterns?</li>



<li>What is the Saga pattern?</li>



<li>What is CQRS and in which scenarios may it be beneficial?</li>



<li>What is the difference between an event and a command (like in CQRS)?</li>



<li>What are the advantages and disadvantages of using a Repository pattern?</li>



<li>What is Clean Architecture? Who invented it and how it works?</li>



<li>What is Onion Architecture?</li>



<li>What is Modular Monolith?</li>
</ol>



<h2 class="wp-block-heading">Experience-related .NET Interview Questions</h2>



<ol start="36" class="wp-block-list">
<li>Describe how you realized authentication &amp; authorization in your last project</li>



<li>Explain your last project’s architecture</li>



<li>Explain a challenging task you faced in your last project and how you solved it</li>



<li>How would you approach diagnosing a performance issue on production, which cannot be reproduced locally?</li>



<li>Explain the &#8220;event-based architecture&#8221; you implemented in your last project. This was something I explicitly mentioned in my resume, so the advice is: prepare to elaborate on every experience you mention in your resume <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>



<li>How would you choose tech stack for a new full stack web application (backend + frontend)? Describe your decision-making process: what would you take into consideration when choosing a tech stack?</li>



<li>How would you decide whether to use an already-existing component (e.g. a library) vs implementing your own?</li>
</ol>



<h2 class="wp-block-heading">Final tips</h2>



<p class="wp-block-paragraph">These were not all of the questions I was asked, but the ones that recurred most frequently. As a programmer with almost 10 years of professional experience, I wasn&#8217;t asked many basic programming questions. The recruiters were mostly focused on my experience. They wanted to know how I solved problems at work in the past and what&#8217;s my approach to tackling issues. Rather than asking me theories about a design pattern, they wanted to know how I applied it in practice and whether I was happy with deciding to use it in the first place.</p>



<p class="wp-block-paragraph">My general advice is to be patient and iterate. After each technical interview, try to write down as many questions as you can remember. This will help you be better and better prepared with each interview you take. Don&#8217;t forget to update your <a href="https://www.linkedin.com/in/dawidsibinski/">LinkedIn profile</a> and keep building a quality network, even if you&#8217;re not on the job lookout right now. It comes in handy!</p>



<p class="wp-block-paragraph">If you happen to be in a work search right now, I keep my fingers crossed! I hope these .NET interview questions will help you get that dream job <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">If you&#8217;re interested in knowing something about programming job search in current market conditions, feel free to leave a comment <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/real-net-interview-questions-2024-2025/">Real .NET Interview Questions (2024/2025)</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/real-net-interview-questions-2024-2025/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4909</post-id>	</item>
		<item>
		<title>What is Mutation Testing and Why Should You Use It?</title>
		<link>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/</link>
					<comments>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 18:22:58 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mutation testing]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[unit tests]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4825</guid>

					<description><![CDATA[<p>Do you know what is a better testing metric than code coverage? Does 100% code coverage mean your code is well-tested? How to generate unit test cases for free, without using AI? The answer to all these questions is mutation testing. Interested? Read on 😉 Code Coverage &#8211; Our Old Friend You probably know what&#8230;</p>
<p>The post <a href="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/">What is Mutation Testing and Why Should You Use It?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Do you know what is a better testing metric than code coverage? Does 100% code coverage mean your code is well-tested? How to generate unit test cases for free, without using AI?</p>



<p class="wp-block-paragraph">The answer to all these questions is <strong>mutation testing</strong>. Interested? Read on <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4825"></span>



<h2 class="wp-block-heading">Code Coverage &#8211; Our Old Friend</h2>



<p class="wp-block-paragraph">You probably know what <a href="https://en.wikipedia.org/wiki/Code_coverage">code coverage</a> is. Traditionally, many teams tend to measure how good their tests&#8217; suite is by percentage line / statements / functions coverage. Some even require this metric to be 100%. Let&#8217;s start with this well-known approach first.</p>



<p class="wp-block-paragraph">We are working with <code>TicketsPriceCalculator</code> class today. It contains some simple business logic:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist133062269" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-ticketspricecalculator-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="ticketsPriceCalculator.ts content, created by dsibinski on 04:08PM on October 01, 2024."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="ticketsPriceCalculator.ts">
        <tr>
          <td id="file-ticketspricecalculator-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-ticketspricecalculator-ts-LC1" class="blob-code blob-code-inner js-file-line">export class TicketsPriceCalculator {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-ticketspricecalculator-ts-LC2" class="blob-code blob-code-inner js-file-line">  calculateTotalTicketsPrice(tickets: Ticket[]): number {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-ticketspricecalculator-ts-LC3" class="blob-code blob-code-inner js-file-line">    if (tickets.length === 0) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-ticketspricecalculator-ts-LC4" class="blob-code blob-code-inner js-file-line">      return 0;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-ticketspricecalculator-ts-LC5" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-ticketspricecalculator-ts-LC6" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-ticketspricecalculator-ts-LC7" class="blob-code blob-code-inner js-file-line">    let totalPrice = tickets.reduce((sum, ticket) =&gt; sum + ticket.price, 0);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-ticketspricecalculator-ts-LC8" class="blob-code blob-code-inner js-file-line">    const businessClassTickets = tickets.filter(</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-ticketspricecalculator-ts-LC9" class="blob-code blob-code-inner js-file-line">      (ticket) =&gt; ticket.isBusinessClass</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-ticketspricecalculator-ts-LC10" class="blob-code blob-code-inner js-file-line">    ).length;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-ticketspricecalculator-ts-LC11" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-ticketspricecalculator-ts-LC12" class="blob-code blob-code-inner js-file-line">    let totalDiscountToApply = 0;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-ticketspricecalculator-ts-LC13" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-ticketspricecalculator-ts-LC14" class="blob-code blob-code-inner js-file-line">    // Apply discounts based on total price</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-ticketspricecalculator-ts-LC15" class="blob-code blob-code-inner js-file-line">    if (totalPrice &gt; 2000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-ticketspricecalculator-ts-LC16" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.25;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-ticketspricecalculator-ts-LC17" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt; 1000 &amp;&amp; totalPrice &lt;= 2000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-ticketspricecalculator-ts-LC18" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.2;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-ticketspricecalculator-ts-LC19" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt; 500 &amp;&amp; totalPrice &lt;= 1000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-ticketspricecalculator-ts-LC20" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.15;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-ticketspricecalculator-ts-LC21" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt;= 200 &amp;&amp; totalPrice &lt;= 500) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-ticketspricecalculator-ts-LC22" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.1;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-ticketspricecalculator-ts-LC23" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-ticketspricecalculator-ts-LC24" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-ticketspricecalculator-ts-LC25" class="blob-code blob-code-inner js-file-line">    // Apply additional discount based on number of tickets</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-ticketspricecalculator-ts-LC26" class="blob-code blob-code-inner js-file-line">    if (tickets.length &gt;= 10) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-ticketspricecalculator-ts-LC27" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.05;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-ticketspricecalculator-ts-LC28" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-ticketspricecalculator-ts-LC29" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-ticketspricecalculator-ts-LC30" class="blob-code blob-code-inner js-file-line">    // Apply business class discounts</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-ticketspricecalculator-ts-LC31" class="blob-code blob-code-inner js-file-line">    if (businessClassTickets &gt;= 10) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-ticketspricecalculator-ts-LC32" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.2;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-ticketspricecalculator-ts-LC33" class="blob-code blob-code-inner js-file-line">    } else if (businessClassTickets &gt;= 5) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-ticketspricecalculator-ts-LC34" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.1;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-ticketspricecalculator-ts-LC35" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-ticketspricecalculator-ts-LC36" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-ticketspricecalculator-ts-LC37" class="blob-code blob-code-inner js-file-line">    return totalPrice * (1 &#8211; totalDiscountToApply);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-ticketspricecalculator-ts-LC38" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-ticketspricecalculator-ts-LC39" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/28087f239e57c7dab06d3df2e7532e6d/raw/d388fec49bd951d520a8d0af93c07907c122ce27/ticketsPriceCalculator.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/28087f239e57c7dab06d3df2e7532e6d#file-ticketspricecalculator-ts" class="Link--inTextBlock">
          ticketsPriceCalculator.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">As you can see, the class has one function whith returns the total price to be paid for a set of tickets. On the way, it applies various discounts based on some business rules. Fair enough.</p>



<p class="wp-block-paragraph">It&#8217;s a critical piece of business logic for the app we&#8217;re working on, but it has never had any tests. We were asked to write unit tests for this class. Our manager strictly requires the code coverage to be 100%. Let&#8217;s do it then. We will go line by line, analyze the business logic and add the tests. Below, you can see the results of running those tests (you can find the tests code <a href="https://gist.github.com/dsibinski/cfc8d36cf7fe45bb9114b950fa898766">here</a>):</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="839" height="427" data-attachment-id="4840" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/1-unit-tests-initial/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?fit=839%2C427&amp;ssl=1" data-orig-size="839,427" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1-unit-tests-initial" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?fit=839%2C427&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?resize=839%2C427&#038;ssl=1" alt="Unit tests before using mutation testing. We have 8 unit tests, all passing. Our code coverage (line, functions, statements, branches) is 100%" class="wp-image-4840" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?w=839&amp;ssl=1 839w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?resize=768%2C391&amp;ssl=1 768w" sizes="(max-width: 839px) 100vw, 839px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Wow, that&#8217;s awesome! We did a great job. We have <strong>8 unit tests which provide 100% statements, branch, functions and lines coverage</strong>!</p>



<p class="wp-block-paragraph">So now we are really safe, aren&#8217;t we? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Yeah&#8230; until you know what mutation testing is <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">What Is Mutation Testing?</h2>



<p class="wp-block-paragraph">The idea of mutation testing is to <em>mutate</em> (change) our code. Mutation testing tools introduce changes into our production code. These changes can be really anything &#8211; from reverting a condition of an <code>if</code> statement, to changing some operators or changing a <code>string</code> value. For instance, here are some logical mutations <a href="https://stryker-mutator.io/">Stryker Mutator</a> is able to introduce (you can find the list of all mutations supported by Stryker <a href="https://stryker-mutator.io/docs/mutation-testing-elements/supported-mutators/">here</a>):</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" decoding="async" width="445" height="320" data-attachment-id="4845" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/2-stryker-logical-mutations/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?fit=445%2C320&amp;ssl=1" data-orig-size="445,320" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2-stryker-logical-mutations" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?fit=445%2C320&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?resize=445%2C320&#038;ssl=1" alt="Logical operator mutations supported by Stryker Mutator" class="wp-image-4845"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">In effect, they generate modified versions of our code, which are called <em>mutants</em>. Makes sense <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Each mutant contains a single modification in our source code. What happens next is crucial. Mutation testing tool takes this mutant (it is used as the code under tests now) and executes all of our unit tests against it. The result may be twofold:</p>



<ul class="wp-block-list">
<li>all tests have passed. In other words, the <em>mutant has</em> <em>survived</em>. <strong>This is a bad situation</strong>. It implies that the modification of our source code was not detected by our tests</li>



<li>at least one test has failed. In other words, the <em>mutant has been killed</em>. <strong>This is a good scenario</strong>. It means that our tests detect changes in the production code and efficiently cover this particular scenario.</li>
</ul>



<p class="wp-block-paragraph">The flow is more or less like this <a href="https://peterevans.dev/posts/mutation-testing/">schema from Peter Evans&#8217; blog</a> presents:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img data-recalc-dims="1" decoding="async" width="353" height="580" data-attachment-id="4847" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/3-mutation-test-schema/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?fit=353%2C580&amp;ssl=1" data-orig-size="353,580" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3-mutation-test-schema" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?fit=353%2C580&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?resize=353%2C580&#038;ssl=1" alt="Schema of mutation testing" class="wp-image-4847" style="width:353px;height:auto"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">But why would anyone change the production code on purpose by introducing some stupid changes? It may seem counterintuitive for now, but let&#8217;s see how we can use it to our leverage.</p>



<h2 class="wp-block-heading">Mutation Testing with Stryker Mutator</h2>



<p class="wp-block-paragraph">Let&#8217;s clearly state what we are starting with:</p>



<p class="wp-block-paragraph"><strong>8 unit tests, 100% code coverage</strong></p>



<p class="wp-block-paragraph">Let&#8217;s now run mutation testing on our code. We are using TypeScript here, so let&#8217;s go with <a href="https://stryker-mutator.io/">Stryker Mutator</a>.</p>



<p class="wp-block-paragraph">Here&#8217;s the result of running Stryker with <code>npx stryker run</code> on our code:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="958" height="163" data-attachment-id="4854" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/4-stryker-mutator-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?fit=958%2C163&amp;ssl=1" data-orig-size="958,163" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="4-stryker-mutator-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?fit=958%2C163&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?resize=958%2C163&#038;ssl=1" alt="Mutation test result - first run. Mutation score 78%, survived mutants 15" class="wp-image-4854" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?w=958&amp;ssl=1 958w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?resize=768%2C131&amp;ssl=1 768w" sizes="auto, (max-width: 958px) 100vw, 958px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">As you can see, 53 mutants were killed, but 15 of them survived. This gives us a mutation score of 78%. Let&#8217;s call it <em>mutation coverage</em> from now on. So to make it clear, this is our starting situation:</p>



<p class="wp-block-paragraph"><strong>8 unit tests, 100% code coverage, 78% mutation coverage</strong></p>



<p class="wp-block-paragraph">Let&#8217;s now see how to kill those remaining mutants.</p>



<h2 class="wp-block-heading">Killing First Mutants</h2>



<p class="wp-block-paragraph">In order to kill the mutants and improve our mutation score, we need to write more unit tests. Sounds logical, doesn&#8217;t it?</p>



<p class="wp-block-paragraph">If still not, let&#8217;s take a deeper look at mutation tests results in VS Code. Stryker lists details of every survived mutant, for example this one:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="864" height="198" data-attachment-id="4855" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/5-stryker-mutant-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?fit=864%2C198&amp;ssl=1" data-orig-size="864,198" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="5-stryker-mutant-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?fit=864%2C198&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?resize=864%2C198&#038;ssl=1" alt="First mutant generated by Stryker" class="wp-image-4855" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?w=864&amp;ssl=1 864w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?resize=768%2C176&amp;ssl=1 768w" sizes="auto, (max-width: 864px) 100vw, 864px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Stryker changed the greater or equal (<code>>=</code>) operator to greater operator (<code>></code>). This is a very common and very useful mutation. It usually means that our tests don&#8217;t cover the edge case associated with this particular condition.</p>



<p class="wp-block-paragraph">In this case, the edge case value seems to be <code>5</code>. More precisely, what happens if the number of business class tickets is <em>exactly 5</em>? We don&#8217;t know, because there is no test for this particular edge case!</p>



<p class="wp-block-paragraph">Let&#8217;s add it:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist133063837" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-ticketspricecalculator_edgecase-test-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="ticketsPriceCalculator_edgeCase.test.ts content, created by dsibinski on 05:23PM on October 01, 2024."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="ticketsPriceCalculator_edgeCase.test.ts">
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC1" class="blob-code blob-code-inner js-file-line">  test(&quot;should apply 10% discount if there are exactly 5 business class tickets&quot;, () =&gt; {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC2" class="blob-code blob-code-inner js-file-line">    const tickets = Array.from({ length: 5 }, () =&gt; ({</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC3" class="blob-code blob-code-inner js-file-line">      price: 10,</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC4" class="blob-code blob-code-inner js-file-line">      isBusinessClass: true,</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC5" class="blob-code blob-code-inner js-file-line">    }));</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC6" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC7" class="blob-code blob-code-inner js-file-line">    const totalPrice = calculator.calculateTotalTicketsPrice(tickets);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC8" class="blob-code blob-code-inner js-file-line">    expect(totalPrice).toBe(45); // 10% discount</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC9" class="blob-code blob-code-inner js-file-line">  });</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/ee04a5c91df633a66935ed6a663f3ae1/raw/836811b2f5ba7f306346a9c11f4fe7de42ce2b89/ticketsPriceCalculator_edgeCase.test.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/ee04a5c91df633a66935ed6a663f3ae1#file-ticketspricecalculator_edgecase-test-ts" class="Link--inTextBlock">
          ticketsPriceCalculator_edgeCase.test.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">The test passes. Let&#8217;s run mutation tests again:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="961" height="166" data-attachment-id="4856" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/6-stryker-mutator-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?fit=961%2C166&amp;ssl=1" data-orig-size="961,166" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="6-stryker-mutator-2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?fit=961%2C166&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?resize=961%2C166&#038;ssl=1" alt="Struker Mutator second run - already 14 mutants survived and almost 80% mutation coverage" class="wp-image-4856" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?w=961&amp;ssl=1 961w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?resize=768%2C133&amp;ssl=1 768w" sizes="auto, (max-width: 961px) 100vw, 961px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">That&#8217;s it! We have a new unit test and 1 more mutant killed <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" />  Current state:</p>



<p class="wp-block-paragraph"><strong>9 (+1) unit tests, 100% code coverage, 79% mutation coverage</strong></p>



<p class="wp-block-paragraph">I think you&#8217;re now getting what this is all about. We should be adding unit tests to cover the edge cases detected by mutations until all (or most) mutants are killed.</p>



<h2 class="wp-block-heading">Mutation Testing &#8211; Free Unit Tests Generator</h2>



<p class="wp-block-paragraph">After adding 1 more test, the results look as follows:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="960" height="164" data-attachment-id="4859" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/7-stryker-mutator-3/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?fit=960%2C164&amp;ssl=1" data-orig-size="960,164" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="7-stryker-mutator-3" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?fit=960%2C164&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?resize=960%2C164&#038;ssl=1" alt="Struker mutator with 10 tests - 86% mutation coverage" class="wp-image-4859" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?w=960&amp;ssl=1 960w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?resize=768%2C131&amp;ssl=1 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><strong>10 (+2) unit tests, 100% code coverage, 86% mutation coverage</strong></p>



<p class="wp-block-paragraph">Finally, this is what we managed to get after a few minutes of work:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="959" height="165" data-attachment-id="4860" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/8-stryker-mutator-4/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?fit=959%2C165&amp;ssl=1" data-orig-size="959,165" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="8-stryker-mutator-4" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?fit=959%2C165&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?resize=959%2C165&#038;ssl=1" alt="" class="wp-image-4860" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?w=959&amp;ssl=1 959w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?resize=768%2C132&amp;ssl=1 768w" sizes="auto, (max-width: 959px) 100vw, 959px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">And we now have 17 unit tests in our suite! The final score looks like that:</p>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f38a.png" alt="🎊" class="wp-smiley" style="height: 1em; max-height: 1em;" /><strong>17 (+9) unit tests, 100% code coverage, 96% mutation coverage</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f38a.png" alt="🎊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Notice what happened here. <strong>We started with 8 unit tests and finished with 17! This is awesome! That&#8217;s how mutation testing is a free unit tests generator</strong>. And you don&#8217;t even need AI for that <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">What&#8217;s more, the generated mutations even forced me to make a little tweak to the production code. It exposed some things that didn&#8217;t make sense. I could make this change to the production code, because my tests&#8217; suite was already quite substantial.</p>



<p class="wp-block-paragraph">Note that I didn&#8217;t push to gain 100% mutation coverage. The 3 mutants that survived don&#8217;t make much sense in our case. I encourage you to <a href="https://github.com/dsibinski/codejourney/tree/main/mutation-testing">get the code</a> and execute <code>npx stryker run</code> in the application folder to see for yourself <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">The percentage value doesn&#8217;t matter in that case. What matters is that we got 9 new unit tests and our tests&#8217; suite is more robust. Now we can go and tell our manager that the business-critical code is well tested <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">So What Now?</h2>



<p class="wp-block-paragraph">I hope you see how valuable mutation testing is. It&#8217;s not a perfect tool that suits all cases. For example, it&#8217;s not easy to use mutation testing for complex legacy code. However, if your logic is nicely isolated, it could be a great tool. Especially if your production code heavily depends on calculations and many conditions. You may be surprised how many edge cases mutation testing can find.</p>



<p class="wp-block-paragraph">I also love using mutation testing with TDD. These two techniques nicely complement each other.</p>



<p class="wp-block-paragraph">I encourage you to go and try mutation testing. There are different mutation tools for various programming languages:</p>



<ul class="wp-block-list">
<li>C#, JavaScript, TypeScript, Scala: <a href="https://stryker-mutator.io/">Stryker Mutator</a></li>



<li>Ruby: <a href="https://github.com/mbj/mutant">mutant</a></li>



<li>Java: <a href="https://pitest.org/">pitest</a></li>



<li>PHP: <a href="https://infection.github.io/">Infection</a></li>



<li>C++: <a href="https://github.com/nlohmann/mutate_cpp">Mutate++</a></li>
</ul>



<p class="wp-block-paragraph">&#8230;and probably many more. Just do some research for the language you work with and give it a try <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Because <a href="https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/">testing</a> is cool, isn&#8217;t it? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">You can find the full source code used in this article <a href="https://github.com/dsibinski/codejourney/tree/main/mutation-testing">here</a>.</p>
<p>The post <a href="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/">What is Mutation Testing and Why Should You Use It?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4825</post-id>	</item>
		<item>
		<title>5 Reasons To Not Use C# IDE For TypeScript Development</title>
		<link>https://www.codejourney.net/5-reasons-to-not-use-c-ide-for-typescript-development/</link>
					<comments>https://www.codejourney.net/5-reasons-to-not-use-c-ide-for-typescript-development/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 04 Nov 2023 07:12:15 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[rider]]></category>
		<category><![CDATA[road-to-dotnet-full-stack]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[visual studio]]></category>
		<category><![CDATA[visual studio code]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4684</guid>

					<description><![CDATA[<p>I know a few fellow devs who still use Visual Studio or Rider as their IDE for Typescript. If you&#8217;re one of them, this is going to be a little rant on you all 😄 In this short article, I will give you my 5 reasons why the backend code editor might not be the&#8230;</p>
<p>The post <a href="https://www.codejourney.net/5-reasons-to-not-use-c-ide-for-typescript-development/">5 Reasons To Not Use C# IDE For TypeScript Development</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I know a few fellow devs who still use Visual Studio or Rider as their IDE for Typescript. If you&#8217;re one of them, this is going to be a little rant on you all <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f604.png" alt="😄" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<p class="wp-block-paragraph">In this short article, I will give you my 5 reasons why the backend code editor might not be the best IDE for frontend development <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph"><em>NOTE: calling this post a &#8220;rant&#8221; is obviously humorous <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> This article is my own opinion, not a hate on anyone using different IDEs than I do.</em></p>



<span id="more-4684"></span>



<h2 class="wp-block-heading">1. Rider and Visual Studio are slow</h2>



<p class="wp-block-paragraph">While I consider Rider much faster than Visual Studio, even the JetBrains editor is too heavy for TypeScript development. Both of these apps are not good candidates for an IDE for TypeScript. They were designed to work with complex, backend solutions. These IDEs include a lot of features by default that can&#8217;t be turned off, most of which are not needed when working with frontend code.</p>



<p class="wp-block-paragraph">This gets even worse if the solution you open contains both backend C# project and React app&#8217;s code, as it is in <a href="https://learn.microsoft.com/en-us/visualstudio/javascript/tutorial-asp-net-core-with-react?view=vs-2022">Visual Studio&#8217;s .NET+React template</a>. With time, even loading such a solution takes a lot of time. Especially if you use Visual Studio with <a href="https://www.jetbrains.com/resharper">ReSharper</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f648.png" alt="🙈" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">2. Less IntelliSense and tooling support</h2>



<p class="wp-block-paragraph">From my experience, Visual Studio doesn&#8217;t show as much <a href="https://en.wikipedia.org/wiki/Intelligent_code_completion">IntelliSense info</a> as, for instance, Visual Studio Code does. The navigation in TypeScript code doesn&#8217;t feel as smooth as it should. </p>



<p class="wp-block-paragraph">When I tried to use Rider or Visual Studio as IDE for TypeScript, I had issues working with popular frontend tooling like <a href="https://prettier.io/">Prettier</a> and <a href="https://eslint.org/">ESLint</a>. Theoretically, there are plugins for both of these IDEs, but in my experience they don&#8217;t always work properly. For instance, the &#8220;Format on save&#8221; feature of Prettier often doesn&#8217;t work in Rider for me. ESLint makes Visual Studio even slower (is that even possible?! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" />).</p>



<p class="wp-block-paragraph">It&#8217;s hard to fully explain if you only worked with TypeScript in Rider or Visual Studio, but I promise you that switching to VS Code makes a huge difference <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92a.png" alt="🤪" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Read on to get to know why!</p>



<h2 class="wp-block-heading">3. Confusion of concepts</h2>



<p class="wp-block-paragraph">Let me explain my approach to frontend and backend first. To me, as a full stack developer, working on a frontend app requires a different mindset than working on backend. For instance, developing a React app requires me to think <em>The React Way</em> (we discussed it already in an article about <a href="https://www.codejourney.net/react-state-management-basics/">React state management</a>).</p>



<p class="wp-block-paragraph">In my view, editing both frontend and backend code in the same editor makes you confuse concepts. If you learned JavaScript/TypeScript after working with C# for some time, you probably experienced trying to use <code>let</code> in C# or declaring C# types with colon (<code>:</code>) <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> But this is only a tip of the iceberg.</p>



<p class="wp-block-paragraph">I think having a separate IDE for TypeScript makes you nicely switch context when working on the frontend app. Opening my TypeScript code editor, I immediately start <em>thinking in frontend</em>. It instantly switches my approach to writing code. I somehow start to behave like a frontend developer, not a full stack one. </p>



<p class="wp-block-paragraph">I think such approach is beneficial. For instance, it lets me work on my frontend code as I would be a real consumer of the backend API, not the person who can implement the backend in whichever way I want. Thanks to that <em>switching of viewpoint</em>, I can focus on designing my frontend code properly, without worrying about the backend.</p>



<p class="wp-block-paragraph">I also tend to make less assumptions like <em>oh no worries, I will do it on the server</em>. At that moment, with my IDE for TypeScript open, I am a frontend developer. It often leads to better API design later on, because I don&#8217;t make any assumptions about the backend. Working on a frontend part of the app, I usually use API mocks first, knowing only the shape of data that should come from the API. Only later, when I&#8217;m done with the frontend part, I switch to Rider to actually implement the API.</p>



<p class="wp-block-paragraph">Of course, this can also work the other way around. You can first work on the backend, design your API according to the best practices (again &#8211; without even thinking about your frontend app) and finally switch to the frontend IDE, build the UI and consume the API instead of using mock in the first place.</p>



<p class="wp-block-paragraph">I hope you got what I mean here, but it&#8217;s not easy to clearly explain <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92a.png" alt="🤪" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<h2 class="wp-block-heading">4. Temptation to sneak C# concepts to TS</h2>



<p class="wp-block-paragraph">This point is a consequence of the previous one.  If your IDE for TypeScript is the same as your C# code editor, you will be tempted to sneak C# concepts into TypeScript. I often see .NET developers entering TypeScript world using <code>var</code> by default (which is kinda deprecated in JavaScript and considered a bad practice today) or enforcing C# brackets formatting style in their frontend code. I also noticed overuse of classes and inheritance in TypeScript, as well as confusing passing value/reference data directly into components instead of properly using <a href="https://www.codejourney.net/react-state-management-basics/"><code>state</code> and <code>props</code> in React</a>.</p>



<p class="wp-block-paragraph">To sum it up: isolating yourself as a frontend developer by using a TypeScript-specific IDE (like VS Code) will help you learn good frontend practices quicker <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">5. Because VS Code is better <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<p class="wp-block-paragraph">Last, but not least: the main reason to not use <a href="https://visualstudio.microsoft.com/">Visual Studio</a> or <a href="https://www.jetbrains.com/rider/">Rider</a> for TypeScript development is simple: <strong><a href="https://code.visualstudio.com/">Visual Studio Code</a> is better!</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">VS Code is industry standard for frontend development today. According to <a href="https://survey.stackoverflow.co/2023/#section-most-popular-technologies-integrated-development-environment">Stack Overflow Developer Survey 2023</a>, over 70% of all developers use Visual Studio Code:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="928" height="340" data-attachment-id="4695" data-permalink="https://www.codejourney.net/5-reasons-to-not-use-c-ide-for-typescript-development/stack-overflow-survey-2023-vs-code/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/11/stack-overflow-survey-2023-vs-code.png?fit=928%2C340&amp;ssl=1" data-orig-size="928,340" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="stack-overflow-survey-2023-vs-code" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/11/stack-overflow-survey-2023-vs-code.png?fit=928%2C340&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/11/stack-overflow-survey-2023-vs-code.png?resize=928%2C340&#038;ssl=1" alt="Visual Studio Code is the most widely used IDE for TypeScript (and IDE in general)" class="wp-image-4695" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/11/stack-overflow-survey-2023-vs-code.png?w=928&amp;ssl=1 928w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/11/stack-overflow-survey-2023-vs-code.png?resize=768%2C281&amp;ssl=1 768w" sizes="auto, (max-width: 928px) 100vw, 928px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">VS Code is lightweight. It doesn&#8217;t have all heavy features included by default. If you want something additional, it must be installed as an extension. By the way, the extensions are really great and actively developed by the community.</p>



<p class="wp-block-paragraph">VS Code is mostly written in TypeScript, which makes is somewhat designed for TypeScript. It has great search features, awesome IntelliSense for TypeScript and works really fast. Especially compared to Visual Studio or even Rider.</p>



<p class="wp-block-paragraph">Visual Studio Code can also be run on any platform. It even has a <a href="https://vscode.dev/">fully-featured web version</a>. The IDE is also completely free and open-source.</p>



<p class="wp-block-paragraph">I think I won&#8217;t continue listing numerous advantages of VS Code here. If you&#8217;re reading this, and you are still not encouraged to switch to VS Code for TypeScript development, please give it a try <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Or another try if you already tried, but it didn&#8217;t click. This time, first <a href="https://www.youtube.com/playlist?list=PLj6YeMhvp2S5UgiQnBfvD7XgOMKs3O_G6">watch some introductory videos</a> with tips on how to get started and get the most of the editor. You can also check the <a href="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/">VS Code extensions I use on a daily basis</a> to make your work with this editor easier.</p>



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



<p class="wp-block-paragraph">That&#8217;s it! I really wanted to write this article one day. Do you know that feeling when you learned something new or made significant progress in some area of your life, and you see people still struggling with what you have overcome? It&#8217;s this moment when you would really love to give these people all of your knowledge and make them magically change their lives &#8211; the same way you did <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I feel exactly that when I see fellow developers struggling (it&#8217;s a matter of opinion, I know <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" />) with Typescript in Visual Studio <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f648.png" alt="🙈" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">I know I can&#8217;t change you and your beliefs and I don&#8217;t want to do that. But the great thing is that I can share my point of view and try to encourage you to alter yours a little. At least try and let me know what are your thoughts on that <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Also, if you&#8217;re a frontend or full stack developer working in a backend IDE like Rider or Visual Studio, let me know why! I&#8217;m really curious. Did you try VS Code? If yes, what didn&#8217;t fit?</p>
<p>The post <a href="https://www.codejourney.net/5-reasons-to-not-use-c-ide-for-typescript-development/">5 Reasons To Not Use C# IDE For TypeScript Development</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/5-reasons-to-not-use-c-ide-for-typescript-development/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4684</post-id>	</item>
		<item>
		<title>React State Management Basics</title>
		<link>https://www.codejourney.net/react-state-management-basics/</link>
					<comments>https://www.codejourney.net/react-state-management-basics/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sun, 29 Oct 2023 04:39:10 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[react]]></category>
		<category><![CDATA[road-to-dotnet-full-stack]]></category>
		<category><![CDATA[typescript]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4591</guid>

					<description><![CDATA[<p>If I were to point out a single concept that is critical to understand in React development, it would be state management. So what is React state management? How is it different from managing data in C# or Java? Let&#8217;s find out! 🙂 State If you are a backend or desktop developer, you may have&#8230;</p>
<p>The post <a href="https://www.codejourney.net/react-state-management-basics/">React State Management Basics</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">If I were to point out a single concept that is critical to understand in React development, it would be state management.</p>



<p class="wp-block-paragraph">So what is React state management? How is it different from managing data in C# or Java? Let&#8217;s find out! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4591"></span>



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



<p class="wp-block-paragraph">If you are a backend or desktop developer, you may have never come across the term of state. At least, I never used it before learning frontend web development. Surely not in the context it is used in frameworks like React. The term more familiar to me at that time was <em>data binding</em> known from <a href="https://learn.microsoft.com/en-us/dotnet/desktop/wpf/overview">WPF</a> or <a href="https://learn.microsoft.com/en-us/dotnet/desktop/winforms/overview">WinForms</a>.</p>



<p class="wp-block-paragraph">This is what <a href="https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data">WPF documentation</a> says:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"></p>
<cite>Data binding is the process that establishes a connection between the app UI and the data it displays. If the binding has the correct settings and the data provides the proper notifications, when the data changes its value, the elements that are bound to the data reflect changes automatically</cite></blockquote>



<p class="wp-block-paragraph">In case of WPF, the crucial part to me is <em><strong>If the binding has the correct settings and the data provides the proper notifications</strong></em> <strong><em>(&#8230;)</em></strong>. If you have ever worked with WPF, you know how frustrating can these <em>notifications</em> be (any <code>INotifyPropertyChanged</code> fans here?).</p>



<p class="wp-block-paragraph">WPF&#8217;s state management it not that bad. However, React has something better <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">React introduces us to a concept of <em>state</em>. In React components, you do not set anything directly, like calling some code to update an input&#8217;s value (this is possible, we&#8217;re still in <a href="https://www.codejourney.net/10-most-shocking-javascript-features-for-csharp-developers/">JavaScript world</a>, but it&#8217;s not a <em>React way</em> of doing stuff). You don&#8217;t directly bind your UI controls with data like you would in WPF or WinForms. Instead, you keep the data in memory, which is a current <em>state </em>of the UI (the whole app or a piece of it). </p>



<p class="wp-block-paragraph"><strong>When the state changes, your UI is updated by React</strong>. In other words &#8211; <strong>in React, UI is a function of state</strong>:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-markup code-embed-pre"  data-start="1" data-line-offset="0"><code class="language-markup code-embed-code">UI = fn(state)</code></pre> <div class="code-embed-infos"> </div> </div></div>



<p class="wp-block-paragraph">It means that your React app (or its individual pieces called <em>components</em>) take some state and output the actual, rendered UI.</p>



<p class="wp-block-paragraph">This is React state management in a nutshell. Let&#8217;s explore it a bit more <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph"><em>Small disclaimer:</em> <em>I will focus on state in React functional componets. I consider <a href="https://react.dev/reference/react/Component">class components somewhat legacy</a>. I think this meme summarizes it best <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" />:</em></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://www.freecodecamp.org/news/functional-setstate-is-the-future-of-react-374f30401b6b/"><img data-recalc-dims="1" loading="lazy" decoding="async" width="500" height="381" data-attachment-id="4669" data-permalink="https://www.codejourney.net/react-state-management-basics/react-setstate-meme/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/react-setstate-meme.jpg?fit=500%2C381&amp;ssl=1" data-orig-size="500,381" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="react-setstate-meme" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/react-setstate-meme.jpg?fit=500%2C381&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/react-setstate-meme.jpg?resize=500%2C381&#038;ssl=1" alt="" class="wp-image-4669"/></a></figure>
</div>


<h3 class="wp-block-heading">The Naive Way</h3>



<p class="wp-block-paragraph">Let&#8217;s try to approach React state management as C# developer. In React, the basic piece of UI we create is a component. Let&#8217;s add one:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">import Button from &quot;react-bootstrap/Button&quot;;<br/><br/>export const NaiveComponent = () =&gt; {<br/>  return (<br/>    &lt;&gt;<br/>      &lt;div&gt;I am a naive component&lt;/div&gt;<br/>      &lt;Button variant=&quot;success&quot;&gt;Click me!&lt;/Button&gt;<br/>    &lt;/&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">NaiveComponent.tsx</span> </div> </div></div>



<p class="wp-block-paragraph">For now, we render some text and a button which does nothing. What we want is to have some data displayed, like a number, which is incremented on every button click. Let&#8217;s try to implement that naively:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export const NaiveComponent = () =&gt; {<br/>  let myCount = 0;<br/><br/>  return (<br/>    &lt;&gt;<br/>      &lt;div&gt;I am a naive component&lt;/div&gt;<br/>      &lt;div&gt;Current count: {myCount}&lt;/div&gt;<br/>      &lt;Button<br/>        variant=&quot;success&quot;<br/>        onClick={() =&gt; {<br/>          myCount＋＋;<br/>        }}<br/>      &gt;<br/>        Click me!<br/>      &lt;/Button&gt;<br/>    &lt;/&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">NaiveComponent.tsx &#8211; the naive counter incrementing</span> </div> </div></div>



<p class="wp-block-paragraph">Now, let&#8217;s check if it works:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="536" height="285" data-attachment-id="4602" data-permalink="https://www.codejourney.net/react-state-management-basics/chrome_wkzlxfcktf/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_wkZlXfCKTf.gif?fit=536%2C285&amp;ssl=1" data-orig-size="536,285" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="chrome_wkZlXfCKTf" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_wkZlXfCKTf.gif?fit=536%2C285&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_wkZlXfCKTf.gif?resize=536%2C285&#038;ssl=1" alt="" class="wp-image-4602"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">It looks nothing happens <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f979.png" alt="🥹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> To investigate that, we can add a <code>console.log</code> (the most common debugging technique in JavaScript world <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" />) to the <code>onClick</code> event:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">onClick={() =&gt; {<br/>          myCount＋＋;<br/>          console.log(myCount);<br/>        }}</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">onClick with console.log</span> </div> </div></div>



<p class="wp-block-paragraph">How does that look in the console now?</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1071" height="591" data-attachment-id="4603" data-permalink="https://www.codejourney.net/react-state-management-basics/chrome_g62ao8n7fw/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_g62ao8n7FW.gif?fit=1071%2C591&amp;ssl=1" data-orig-size="1071,591" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="chrome_g62ao8n7FW" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_g62ao8n7FW.gif?fit=1071%2C591&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_g62ao8n7FW.gif?resize=1071%2C591&#038;ssl=1" alt="React state management - naive way (like C# dev), not working" class="wp-image-4603" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_g62ao8n7FW.gif?w=1071&amp;ssl=1 1071w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_g62ao8n7FW.gif?resize=768%2C424&amp;ssl=1 768w" sizes="auto, (max-width: 1071px) 100vw, 1071px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Woooow, something is really going wrong here! The data is updated in memory, but not reflected in the UI <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Why does that happen? Because <code>myCount</code> is not a state. It&#8217;s just some variable we created hoping that it will work fine as part of the UI. Remember what we have discussed in the previous section &#8211; we need to start <em>thinking in React</em>. This is <em>The</em> <em>React way</em>, not <em>Java way </em>or <em>C# way </em>anymore.</p>



<h3 class="wp-block-heading">The React Way</h3>



<p class="wp-block-paragraph">So, how to use React state management properly in our example? We need to make <code>myCount</code> be a part of component&#8217;s state. The simplest way to do that looks as follows:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="2,11" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export const TheReactWayComponent = () =&gt; {<br/>  const [myCount, setMyCount] = useState(0);<br/><br/>  return (<br/>    &lt;&gt;<br/>      &lt;div&gt;I am a React Way component&lt;/div&gt;<br/>      &lt;div&gt;Current count: {myCount}&lt;/div&gt;<br/>      &lt;Button<br/>        variant=&quot;success&quot;<br/>        onClick={() =&gt; {<br/>          setMyCount(myCount ＋ 1);<br/>        }}<br/>      &gt;<br/>        Click me!<br/>      &lt;/Button&gt;<br/>    &lt;/&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">TheReactWayComponent.tsx &#8211; The React Way</span> </div> </div></div>



<p class="wp-block-paragraph">First, instead of declaring a &#8220;normal&#8221; variable for storing our UI-related data, we used the <code>useState</code> <a href="https://react.dev/reference/react#state-hooks">hook</a>. As you can see, it returns an array with two things: our state variable (<code>myCount) </code>and a function to update its value<code> </code>(<code>setMyCount</code>). We also set the initial value to <code>0</code>. A good practice is to always use a construct like <code>[myCount, setMyCount]</code> to destructure what <code>useState</code> returns into named, separate objects.</p>



<p class="wp-block-paragraph">Now we are managing our component&#8217;s state <em>The React Way</em>. Does it work? Let&#8217;s see:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="464" height="215" data-attachment-id="4624" data-permalink="https://www.codejourney.net/react-state-management-basics/chrome_ojmhjudmmd/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_OJMhjuDMmd.gif?fit=464%2C215&amp;ssl=1" data-orig-size="464,215" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="chrome_OJMhjuDMmd" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_OJMhjuDMmd.gif?fit=464%2C215&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_OJMhjuDMmd.gif?resize=464%2C215&#038;ssl=1" alt="React state management - The React Way" class="wp-image-4624"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Great! We have just learned how the basic form of state management works in React. That was easy, wasn&#8217;t it? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<p class="wp-block-paragraph">Now, let us discuss one more aspect related to the state itself.</p>



<h3 class="wp-block-heading">Reference vs value</h3>



<p class="wp-block-paragraph">We know the React Way for state management now. We feel confident. However, we are also used to how data is managed in C# or Java, especially in terms of <a href="https://www.codejourney.net/net-internals-02-stack-and-heap-net-data-structures/">handling reference and value types</a>. This knowledge will come very handy now <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Let&#8217;s try to create a bit more complex component:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">type Person = {<br/>  id: number;<br/>  name: string;<br/>  age: number;<br/>};<br/><br/>export const ObjectHolderComponent = () =&gt; {<br/>  const johnInitialValue: Person = {<br/>    id: 1,<br/>    name: &quot;John Doe&quot;,<br/>    age: 30,<br/>  };<br/><br/>  const [john, setJohn] = useState&lt;Person&gt;(johnInitialValue);<br/><br/>  return (<br/>    &lt;&gt;<br/>      &lt;div&gt;ID: {john.id}&lt;/div&gt;<br/>      &lt;div&gt;Name: {john.name}&lt;/div&gt;<br/>      &lt;div&gt;Age: {john.age}&lt;/div&gt;<br/>      &lt;Button<br/>        variant=&quot;success&quot;<br/>        onClick={() =&gt; {<br/>          const currentJohnObject = john;<br/>          currentJohnObject.age = currentJohnObject.age ＋ 1;<br/>          console.log(currentJohnObject);<br/>          setJohn(currentJohnObject);<br/>        }}<br/>      &gt;<br/>        Make John older<br/>      &lt;/Button&gt;<br/>    &lt;/&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">ObjectHolderComponent.tsx</span> </div> </div></div>



<p class="wp-block-paragraph">Now, instead of storing a single value in our component&#8217;s state, we store a whole object of type <code>Person</code>. The object has a few properties: <code>id</code>, <code>name</code> and <code>age</code>.</p>



<p class="wp-block-paragraph">There is also a button. We want this button to take the current <code>john</code> object, increment the value of <code>age</code> on it and update the state. We do it The React Way using <code>setJohn</code> function returned by <code>useState</code>. Just to be sure, we also have the <code>console.log(john)</code> just before updating the state. Does that work as we expected?</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="873" height="656" data-attachment-id="4626" data-permalink="https://www.codejourney.net/react-state-management-basics/chrome_hlgfththbt/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_hlgFthtHBT.gif?fit=873%2C656&amp;ssl=1" data-orig-size="873,656" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="chrome_hlgFthtHBT" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_hlgFthtHBT.gif?fit=873%2C656&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_hlgFthtHBT.gif?resize=873%2C656&#038;ssl=1" alt="Changing an object's (reference) internal variable does not trigger a re-render, even we use useState" class="wp-image-4626" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_hlgFthtHBT.gif?w=873&amp;ssl=1 873w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_hlgFthtHBT.gif?resize=768%2C577&amp;ssl=1 768w" sizes="auto, (max-width: 873px) 100vw, 873px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Eh, what&#8217;s happening here this time? We can clearly see that <code>age</code> is updated on the object on each click, but why isn&#8217;t the UI re-rendered? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">As I mentioned before, it&#8217;s critical to understand the difference between reference and value types here. If you don&#8217;t know it, <a href="https://www.codejourney.net/net-internals-02-stack-and-heap-net-data-structures/">go and make up for it now</a>.</p>



<p class="wp-block-paragraph">The reason it does not work is that we haven&#8217;t updated the actual content of <code>john</code> state variable by calling <code>setJohn(currentJohnObject)</code>. <strong>What is really being hold in <code>john</code> variable is the reference (pointer, address in memory) to the actual object</strong>. And this is what React tracks. We didn&#8217;t really update it, because we assigned the same instance of the object to the state. It doesn&#8217;t matter that we updated its internal property <code>age</code> &#8211; the reference itself wasn&#8217;t updated.</p>



<p class="wp-block-paragraph">How do we solve that? Well, in current solution we&#8217;d need to create a copy of <code>john</code> object before using <code>setJohn</code> to alter the state. In effect, we&#8217;ll get a new instance of the object in memory and <code>john</code> variable will hold a new reference (address) to it.</p>



<p class="wp-block-paragraph">So, if we only change our <code>onClick</code> implementation to this one:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">onClick={() =&gt; {<br/>          const johnCopy = { ...john };<br/>          johnCopy.age = john.age ＋ 1;<br/>          setJohn(johnCopy);<br/>        }}</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">ObjectHolderComponent.tsx &#8211; onClick implementation with copying the original object</span> </div> </div></div>



<p class="wp-block-paragraph">Everything starts to work as expected:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="333" height="236" data-attachment-id="4627" data-permalink="https://www.codejourney.net/react-state-management-basics/chrome_yfmhz6z0xn/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_yfmHz6z0Xn.gif?fit=333%2C236&amp;ssl=1" data-orig-size="333,236" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="chrome_yfmHz6z0Xn" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_yfmHz6z0Xn.gif?fit=333%2C236&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/chrome_yfmHz6z0Xn.gif?resize=333%2C236&#038;ssl=1" alt="Changing a reference state by creating a copy of it works fine in React" class="wp-image-4627"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">I think you now understand how React state management works. I also hope that you see the issues managing state in such a way can bring. Even in this trivial example, we create a new instance of an object on every button click. Apart from memory usage considerations, this just looks ugly. Imagine manually creating copies of much more complex objects, like classes storing arrays or dictionaries. This gets pretty wild <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92a.png" alt="🤪" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">We will see how this issue can be addressed by the end of this article. But first, let&#8217;s discuss <code>props</code> &#8211; another concept critical to really understand React state management.</p>



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



<p class="wp-block-paragraph">Apart from <code>state</code>, we also use <code>props</code> to control the state of our React components. The name is a short for <em>properties</em>, which quite well describes its purpose. <code>Props</code> are the data input provided to a component from outside (from a parent component). They are immutable and cannot be changed inside the component which receives them. Let&#8217;s see some examples.</p>



<h3 class="wp-block-heading">Sharing state between components</h3>



<p class="wp-block-paragraph">The most common usage for <code>props</code> is sharing state between components. Imagine that you have an input, where the user manually enters some data. You want to use the current value of this input in two other components. This is where you need to share your component&#8217;s state (the value of the input) with these two other components. We often call it <em>lifting the state up</em> &#8211; you keep your state higher in the components tree, so the child components can use it.</p>



<p class="wp-block-paragraph">Let&#8217;s try to see an example of connecting <code>state</code> with <code>props</code>:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="4,9,27,28" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export const PersonData = () =&gt; {<br/>  const minimumAge = 5;<br/>  const maximumAge = 100;<br/>  const [age, setAge] = useState&lt;number&gt;(minimumAge);<br/><br/>  const handleAgeChange = (event: React.ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {<br/>    const enteredAge = parseInt(event.target.value);<br/>    if (enteredAge &gt;= minimumAge &amp;&amp; enteredAge &lt;= maximumAge) {<br/>      setAge(enteredAge);<br/>    }<br/>  };<br/><br/>  return (<br/>    &lt;&gt;<br/>      &lt;Form&gt;<br/>        &lt;Form.Group controlId=&quot;age&quot;&gt;<br/>          &lt;Form.Label&gt;Your age&lt;/Form.Label&gt;<br/>          &lt;Form.Control<br/>            type=&quot;number&quot;<br/>            value={age}<br/>            onChange={handleAgeChange}<br/>            min={minimumAge}<br/>            max={maximumAge}<br/>          /&gt;<br/>        &lt;/Form.Group&gt;<br/>      &lt;/Form&gt;<br/>      &lt;DaysLiving currentAge={age} /&gt;<br/>      &lt;YearsUntilCentenarian currentAge={age} /&gt;<br/>    &lt;/&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">PersonData.tsx &#8211; state and props in practice</span> </div> </div></div>



<p class="wp-block-paragraph">As you can see, at lines 4 and 9 we manage the state variable <code>age</code>. This is the old stuff we have already seen.</p>



<p class="wp-block-paragraph">However, at lines 27 and 28 we are passing the <code>age</code> state variable into <code>DaysLiving</code> and <code>YearsUntilCentenarian</code> children components as <code>currentAge</code> prop. This is how the <code>DaysLiving</code> component is implemented:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">type DaysLivingProps = {<br/>  currentAge: number;<br/>};<br/><br/>export const DaysLiving = (props: DaysLivingProps) =&gt; {<br/>  const daysLived = props.currentAge * 365;<br/><br/>  return (<br/>    &lt;div&gt;<br/>      &lt;p&gt;You have lived for {daysLived} days.&lt;/p&gt;<br/>    &lt;/div&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">DaysLiving.tsx</span> </div> </div></div>



<p class="wp-block-paragraph">Notice that <code>props</code> is simply a typed object you pass to a function component. To make things easier, you can also use object destructuring and accept the props in the following way:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export const DaysLiving = ({currentAge}: DaysLivingProps) =&gt; {<br/>  const daysLived = currentAge * 365;<br/>  /// ... rest of the code</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">DaysLiving.tsx &#8211; props with object destructuring</span> </div> </div></div>



<p class="wp-block-paragraph">That way, you don&#8217;t need to write <code>props.currentAge</code> every time you want to use this property inside the component.</p>



<h3 class="wp-block-heading">Does changing props always trigger a re-render?</h3>



<p class="wp-block-paragraph">Well, generally the answer to this question is <em>yes</em>. Every time a prop of a component changes, this component will get re-rendered. However, this is not <em>entirely</em> true <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92a.png" alt="🤪" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">To make this belief true, we need to assume that this prop is changed <em>in a React way</em>. So, to take things literally, consider this component we saw before:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export const DaysLiving = ({currentAge}: DaysLivingProps) =&gt; {<br/>  const daysLived = currentAge * 365;<br/><br/>  return (<br/>    &lt;div&gt;<br/>      &lt;p&gt;You have lived for {daysLived} days.&lt;/p&gt;<br/>    &lt;/div&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">DaysLiving.tsx</span> </div> </div></div>



<p class="wp-block-paragraph">From its perspective only, it accepts a <code>currentAge</code> property. For this component to re-render, it&#8217;s not enough that the <code>currentAge</code> property changes in any way. <strong>Its value must be changed by mutating the state in the parent component</strong>.</p>



<p class="wp-block-paragraph">So, if the value provided as <code>currentAge</code> to <code>DaysLiving</code> component changes in the parent component by properly mutating the state (with <code>setAge</code> mutation callback, in our case):</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="7,14" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export const PersonData = () =&gt; {<br/>  // ...<br/>  const [age, setAge] = useState&lt;number&gt;(minimumAge);<br/><br/>  const handleAgeChange = (event: React.ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {<br/>      // ...<br/>      setAge(enteredAge);<br/>    }<br/>  };<br/><br/>  return (<br/>    &lt;&gt;<br/>      // ...<br/>      &lt;DaysLiving currentAge={age} /&gt;<br/>      // ...<br/>    &lt;/&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">PersonData.tsx &#8211; mutating the state for children components</span> </div> </div></div>



<p class="wp-block-paragraph">the child component (<code>DaysLiving</code>) will get re-rendered.</p>



<p class="wp-block-paragraph">This is because when a parent component changes, React by default re-renders the parent component itself and all of its children.</p>



<p class="wp-block-paragraph">If you modified the <code>age</code> variable in the parent compont directly, without using <code>setAge</code> (which we already know it&#8217;s incorrect), the <code>currentAge</code> prop would technically change, but the <code>DaysLiving</code> component will not get re-rendered.</p>



<h3 class="wp-block-heading">state vs props</h3>



<p class="wp-block-paragraph">This is a question that people oftern ask: what&#8217;s the difference between <code>props</code> and <code>state</code> in React? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">I would start with addressing this differently: what do <code>props</code> and <code>state</code> have in common?</p>



<p class="wp-block-paragraph">As you already know, both are used for React state management. Both of them influence when the components will be re-rendered by React. Props and state are the absolute foundations of React.</p>



<p class="wp-block-paragraph">The main difference is that <code>state</code> is used internally in a component, while <code>props</code> are used to pass information from parent to children components. <code>State</code> is also naturally mutable within a component where it&#8217;s defined, but <code>props</code> are immutable and cannot be changed in a component that receives and uses them.</p>



<h2 class="wp-block-heading">React state management libraries</h2>



<p class="wp-block-paragraph">That&#8217;s basically everything you need to know to be able to comfortably work with React state management. However, I mentioned before that managing state using only built-in React mechanisms actually sucks <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92a.png" alt="🤪" class="wp-smiley" style="height: 1em; max-height: 1em;" /> That&#8217;s why I&#8217;d like to make a short point on state management libraries.</p>



<p class="wp-block-paragraph">Maybe you heard about <a href="https://redux.js.org/">Redux</a>, <a href="https://github.com/pmndrs/zustand">Zustand</a> or <a href="https://mobx.js.org/README.html">MobX</a>. All of them are state management libraires for React. But why would you even need one? And should you learn one now?</p>



<p class="wp-block-paragraph">In my opinion, you can easily start working with React using the built-in state management mechanisms we discussed today. It&#8217;s good to know how it works in practice. However, the truth is that as your application grows and you want to keep it scalable and maintenable, you will need a state management library at some point. As soon as your components tree gets bigger, sharing data and state will not be as easy as &#8220;passing props to a children component&#8221;. You will need to share state between multiple components in the tree, sometimes not only between parent and children, but also with another components defined on the same level or even in a totally different place of the tree.</p>



<p class="wp-block-paragraph">This is where React state management libraries come very handy. They solve many of the React&#8217;s issues that come to the surface as your state gets complex. But even if you use one, you will still always need <code>state</code> and <code>props</code>. That&#8217;s why it&#8217;s critical to understand these two basic concepts first and play with them for some time.</p>



<p class="wp-block-paragraph">If you&#8217;re starting out, it&#8217;s good to know that state management libraries exist and that one day you will have to get your hands on one (or more <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" />) of them. I hope to share my thoughts on state management libraries in a separate article one day.</p>



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



<p class="wp-block-paragraph">That&#8217;s it! Now you should know how React manages state of its components. Of course, we didn&#8217;t cover everything related to state management in React, but I hope you got the basics <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">You can find all of the source code used in this article <a href="https://github.com/dsibinski/codejourney/tree/main/react-state-management">here</a>.</p>



<p class="wp-block-paragraph"><strong>How do you manage state in your React apps? Do you use a state management library? If yes, which one and why? Let me know in the comments below!</strong></p>
<p>The post <a href="https://www.codejourney.net/react-state-management-basics/">React State Management Basics</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/react-state-management-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4591</post-id>	</item>
		<item>
		<title>TypeScript Compiler Explained</title>
		<link>https://www.codejourney.net/typescript-compiler-explained/</link>
					<comments>https://www.codejourney.net/typescript-compiler-explained/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 17 Oct 2023 04:08:05 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[road-to-dotnet-full-stack]]></category>
		<category><![CDATA[typescript]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4530</guid>

					<description><![CDATA[<p>As a frontend developer, one of the things you should know is how TypeScript compiler works. Sooner or later you will work with this language (which I sincerely wish you!), so it&#8217;s good to know your stuff 😉 In this article, I will explain TypeScript compiler to you in simple terms. We will avoid complex&#8230;</p>
<p>The post <a href="https://www.codejourney.net/typescript-compiler-explained/">TypeScript Compiler Explained</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">As a frontend developer, one of the things you should know is how TypeScript compiler works. Sooner or later you will work with this language (which I sincerely wish you!), so it&#8217;s good to know your stuff <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<p class="wp-block-paragraph">In this article, I will explain TypeScript compiler to you in simple terms. We will avoid complex stuff &#8211; only what you need for your everyday frontend developer&#8217;s work. We will not explore the inner workings of the TypeScript compiler Instead, we&#8217;ll see some practical implications of its workings for TypeScript developer. Let&#8217;s dive in <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4530"></span>



<h2 class="wp-block-heading">Few basic facts about TypeScript</h2>



<p class="wp-block-paragraph">For starters, let&#8217;s establish some quick facts about TypeScript as a language.</p>



<h3 class="wp-block-heading">TypeScript is a superset of JavaScript</h3>



<p class="wp-block-paragraph">You may have heard that TypeScript is a superset of JavaScript. In other words, every JavaScript code is a valid TypeScript code. In  case of TypeScript, being a &#8220;superset&#8221; means adding types information on top of perfectly legit JavaScript code.</p>



<p class="wp-block-paragraph">Why is TypeScript only adding its types on top of JavaScript? In order to be able to remove them easily <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> But why would it do that?!</p>



<h3 class="wp-block-heading">Browser doesn&#8217;t understand TypeScript</h3>



<p class="wp-block-paragraph">The answer is that TypeScript cannot be run directly by a web browser (or NodeJS).</p>



<p class="wp-block-paragraph">Let&#8217;s take this trivial TypeScript code:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">let age : number = 27;</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">Trivial TypeScript code</span> </div> </div></div>



<p class="wp-block-paragraph">and try to paste it into Google Chrome&#8217;s console in order to execute it:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="438" height="145" data-attachment-id="4535" data-permalink="https://www.codejourney.net/typescript-compiler-explained/typescript-in-chrome-console/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/TypeScript-in-chrome-console.png?fit=438%2C145&amp;ssl=1" data-orig-size="438,145" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TypeScript-in-chrome-console" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/TypeScript-in-chrome-console.png?fit=438%2C145&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/TypeScript-in-chrome-console.png?resize=438%2C145&#038;ssl=1" alt="TypeScript code cannot be understood by a web browser" class="wp-image-4535"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">As you can see, it fails. The <code>number</code> type annotation is unknown to the browser. It means that <strong>before any TypeScript code is run in the browser, the information about types must be stripped out</strong>. In the end, browsers and NodeJS environments can only execute JavaScript. This is in short what TypeScript compiler does, and we&#8217;ll get into the details soon. For now, this leads us to another conclusion, that&#8230;</p>



<h3 class="wp-block-heading">TypeScript is for developers</h3>



<p class="wp-block-paragraph">As we have just discovered, types must be removed by the TypeScript compiler before the code can be executed by the browser. In fact, this line of TypeScript:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">let age : number = 27;</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">TypeScript code before compilation</span> </div> </div></div>



<p class="wp-block-paragraph">produces the following JavaScript output when processed by the TypeScript compiler:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-javascript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-javascript code-embed-code">var age = 27;</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">JavaScript code after TypeScript compilation</span> </div> </div></div>



<p class="wp-block-paragraph">This is effectively the same code we wrote in TypeScript, but without type annotations.</p>



<p class="wp-block-paragraph">Wrong data types assignments will only be detected at compile time:</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="576" height="241" data-attachment-id="4549" data-permalink="https://www.codejourney.net/typescript-compiler-explained/tsc-compilation-error/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/tsc-compilation-error.png?fit=576%2C241&amp;ssl=1" data-orig-size="576,241" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="tsc-compilation-error" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/tsc-compilation-error.png?fit=576%2C241&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/tsc-compilation-error.png?resize=576%2C241&#038;ssl=1" alt="" class="wp-image-4549"/></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">but as soon as it&#8217;s compiled, this protection is not there anymore <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f937-200d-2642-fe0f.png" alt="🤷‍♂️" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<p class="wp-block-paragraph">This discovery means that <strong>TypeScript is for developers</strong>. Its job is to make our lives easier. Of course, in the end it also improves the end users&#8217; experience, because <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">programming in TypeScript is much better than using pure JS</a>. But you can already see that TypeScript it not present at runtime at all. It only protects us until the compilation step by static types checking.</p>



<p class="wp-block-paragraph">The philosophy is more or less as follows <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" />:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://anjulashanaka.medium.com/say-goodbye-to-runtime-errors-with-typescript-7afbae84e75f"><img data-recalc-dims="1" loading="lazy" decoding="async" width="602" height="333" data-attachment-id="4551" data-permalink="https://www.codejourney.net/typescript-compiler-explained/typescript-no-runtime-errors-if-code-does-not-compile-meme/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/typescript-no-runtime-errors-if-code-does-not-compile-meme.jpg?fit=602%2C333&amp;ssl=1" data-orig-size="602,333" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="typescript-no-runtime-errors-if-code-does-not-compile-meme" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/typescript-no-runtime-errors-if-code-does-not-compile-meme.jpg?fit=602%2C333&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/typescript-no-runtime-errors-if-code-does-not-compile-meme.jpg?resize=602%2C333&#038;ssl=1" alt="TypeScript compiler only protects you at runtime (during compilation)" class="wp-image-4551"/></a></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">What&#8217;s worth mentioning, as the <a href="https://www.typescriptlang.org/docs/handbook/typescript-from-scratch.html">language&#8217;s specification</a> says, &#8220;TypeScript never changes the runtime behavior of JavaScript code&#8221;.</p>



<h2 class="wp-block-heading">TypeScript compiler in practice</h2>



<h3 class="wp-block-heading">tsc </h3>



<p class="wp-block-paragraph">TypeScript compiler is actually a CLI tool called <code>tsc</code>. It can be installed globally on your machine and used directly or built into your IDE. Refer to <a href="https://www.typescriptlang.org/download">official documentation</a> for installation details.</p>



<p class="wp-block-paragraph">The compiler can also be installed locally in your project. It can then be set up as part of the build pipeline, which is supported by many <a href="https://www.codejourney.net/what-is-a-javascript-bundler/">bundlers</a>. That&#8217;s why, when working on a TypeScript project, you may never encounter any direct usages of the <code>tsc</code> command. </p>



<h3 class="wp-block-heading">tsconfig.json</h3>



<p class="wp-block-paragraph">In order to make working with TypeScript compiler easier, you should use a <code>tsconfig.json</code> file. It&#8217;s a JSON file containing all compilation settings. This is quite important, because, in opposite to C# or Java compilers,  the TypeScript&#8217;s one allows for quite extensive (and flexible) configuration. </p>



<p class="wp-block-paragraph">When you use the <code>tsc</code> command, it looks for <code>tsconfig.json</code> file in the current directory or any of the parent directories until it finds one. You can also provide a custom <code>tsconfig.json</code> location via <code>--project</code> parameter.</p>



<p class="wp-block-paragraph">The simplest <code>tsconfig.json</code> file you get after initializing a new TypeScript project with <code>tsc --init</code> looks as follows:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">{<br/>  &quot;compilerOptions&quot;: {<br/>    &quot;target&quot;: &quot;es2016&quot;,<br/>    &quot;module&quot;: &quot;commonjs&quot;,<br/>    &quot;forceConsistentCasingInFileNames&quot;: true,<br/>    &quot;strict&quot;: true,<br/>    &quot;skipLibCheck&quot;: true<br/>  }<br/>}</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">Default tsconfig.json</span> </div> </div></div>



<p class="wp-block-paragraph">We will not explore all the individual settings in this article. The <a href="https://www.typescriptlang.org/docs/handbook/compiler-options.html">official documentation does a great job</a>.</p>



<h3 class="wp-block-heading">TypeScript compiler &#8211; example</h3>



<p class="wp-block-paragraph">Let&#8217;s now see how it works.</p>



<p class="wp-block-paragraph">Having a bit more complex TypeScript file as an example:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">class Person {<br/>  private name: string;<br/>  private age: number;<br/><br/>  constructor(name: string, age: number) {<br/>    this.name = name;<br/>    this.age = age;<br/>  }<br/><br/>  public getName(): string {<br/>    return this.name;<br/>  }<br/><br/>  public getAge(): number {<br/>    return this.age;<br/>  }<br/>}<br/><br/>const person = new Person(&quot;John&quot;, 27);<br/>console.log(person.getName()); // Output: John<br/>console.log(person.getAge()); // Output: 27</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">test.ts</span> </div> </div></div>



<p class="wp-block-paragraph">Notice the <code>.ts</code> extension. This tells the compiler that this file contains TypeScript code.</p>



<p class="wp-block-paragraph">Having <code>tsc</code> installed globally, we can compile it by executing the following command:</p>



<pre class="wp-block-code"><code>tsc test.ts</code></pre>



<p class="wp-block-paragraph">For the file given above, the output of this command is the following JavaScript file:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-javascript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-javascript code-embed-code">var Person = /** @class */ (function () {<br/>  function Person(name, age) {<br/>    this.name = name;<br/>    this.age = age;<br/>  }<br/>  Person.prototype.getName = function () {<br/>    return this.name;<br/>  };<br/>  Person.prototype.getAge = function () {<br/>    return this.age;<br/>  };<br/>  return Person;<br/>})();<br/>var person = new Person(&quot;John&quot;, 27);<br/>console.log(person.getName()); // Output: John<br/>console.log(person.getAge()); // Output: 27</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">test.js</span> </div> </div></div>



<p class="wp-block-paragraph">Few things to note:</p>



<ul class="wp-block-list">
<li>there is no information about types in the <code>.js</code> file. As we discussed before, this is intentional &#8211; only pure JavaScript code can be understood by the browser</li>



<li>notice there is no <code>class</code> keyword used in the compiled JS code, even though classes were introduced in ES2015. This is one of TypeScript compiler&#8217;s features &#8211; to produce code which is supported in most of the browsers and JS engines, without having to wait for support of new JavaScript versions</li>



<li>comments are left untouched</li>
</ul>



<p class="wp-block-paragraph">This explains how the TypeScript compiler works. It also confirms what we stated before, that TypeScript is for programmers. As soon as your code is deployed to production, the types you added in <code>.ts</code> files are absent. The way this process is built gives a lot of advantages, but it may also be a source of confusion &#8211; let&#8217;s see how exactly.</p>



<h2 class="wp-block-heading">TypeScript compilation flaws</h2>



<p class="wp-block-paragraph">Finally, knowing how TS -&gt; JS compilation works, let&#8217;s quickly explore some of its common flaws.</p>



<h3 class="wp-block-heading">No runtime protection</h3>



<p class="wp-block-paragraph">As you now know, TypeScript stripes out the types during compilation. It means that the information about types is not present at runtime (when our code executes). Because of that,<strong> we are not protected by TypeScript at runtime</strong>. Consequently, if an input comes from a user and the inputs themselves are not well validated, we may still get runtime type errors. Imagine that your code expects a <code>number</code>, but the user enters a <code>string</code> because of lack of proper input validation. TypeScript will not protect you here.</p>



<p class="wp-block-paragraph">The same applies to validating API responses. Most data from HTTP APIs comes in a form of JSON. In TypeScript, we can represent such data as <code>type</code> or <code>interface</code>. Based on those expected shapes of data, we use objects of a given type and assume that given properties are present on them or not. However, APIs may change, and TypeScript will again not protect us at runtime. We still need to <a href="https://www.codejourney.net/typing-api-responses-with-zod/">resort to alternative solutions for runtime types validation</a>.</p>



<p class="wp-block-paragraph">To be completely clear &#8211; I don&#8217;t think that no runtime protection is something TypeScript lacks. On the contrary &#8211; I love the flexibility of TypeScript which this approach gives. It&#8217;s just how the language has been designed, and we should be aware of that <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Debugging complexity</h3>



<p class="wp-block-paragraph">When working on a TypeScript project, the code you see on production is different from the one in your IDE. Sometimes not only types are stripped out by TypeScript compiler, but as you saw earlier it may also convert some constructs to the other (like changing a <code>class</code> to a <code>function</code>). It makes debugging, especially directly on production, more complex.</p>



<p class="wp-block-paragraph">In order to place breakpoints and actually have them hit in your TypeScript code, you need <a href="https://code.visualstudio.com/docs/typescript/typescript-debugging#_javascript-source-map-support">source maps</a>. It does the job in most cases, but adds to the complexity at the same time, not always working seamlessly.</p>



<h3 class="wp-block-heading">TypeScript is sometimes too strict</h3>



<p class="wp-block-paragraph">If you decide to <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">migrate your JS project to TypeScript</a>, you will quickly get frustrated by how strict this new language can be. Especially if you are coming from JavaScript world where <a href="https://www.codejourney.net/10-most-shocking-javascript-features-for-csharp-developers/">everything is allowed</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">There are countless memes about that, but here is the one I like:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://devs.lol/meme/for-any-emergency-in-typescript-222"><img data-recalc-dims="1" loading="lazy" decoding="async" width="576" height="505" data-attachment-id="4554" data-permalink="https://www.codejourney.net/typescript-compiler-explained/typescript-any-type-meme/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/typescript-any-type-meme.jpg?fit=576%2C505&amp;ssl=1" data-orig-size="576,505" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="typescript-any-type-meme" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/typescript-any-type-meme.jpg?fit=576%2C505&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/10/typescript-any-type-meme.jpg?resize=576%2C505&#038;ssl=1" alt="TypeScript compiler will often let you go with any type" class="wp-image-4554"/></a></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Joking apart, most things TypeScript complaints about can be configured/turned off in <code>tsconfig.json</code> file. This is actually what I like about TypeScript. It brings static typing into JavaScript world, but lets you control how strict you want it to be. So, if you get frustrated with TypeScript compiler&#8217;s complaints, remember about <a href="https://www.typescriptlang.org/docs/handbook/compiler-options.html">configuration options</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



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



<p class="wp-block-paragraph">I hope that now you feel more comfortable working with TypeScript compiler <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">If you&#8217;re a .NET developer, and you enjoyed this article, I think you may also find my free guide useful:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://mailchi.mp/055b94b02391/net-full-stack-web-developer-guide" target="_blank" rel=" noreferrer noopener"><img data-recalc-dims="1" loading="lazy" decoding="async" width="300" height="300" data-attachment-id="4950" data-permalink="https://www.codejourney.net/how-to-become-dotnet-full-stack-in-2025-300-300/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?fit=300%2C300&amp;ssl=1" data-orig-size="300,300" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="How-to-become-dotnet-full-stack-in-2025-300-300" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?fit=300%2C300&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?resize=300%2C300&#038;ssl=1" alt="16 Steps to become .NET full stack developer in 2025 - download a free guide" class="wp-image-4950" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?w=300&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?resize=50%2C50&amp;ssl=1 50w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></figure>
</div><p>The post <a href="https://www.codejourney.net/typescript-compiler-explained/">TypeScript Compiler Explained</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/typescript-compiler-explained/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4530</post-id>	</item>
		<item>
		<title>What Is A JavaScript Bundler?</title>
		<link>https://www.codejourney.net/what-is-a-javascript-bundler/</link>
					<comments>https://www.codejourney.net/what-is-a-javascript-bundler/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 02 Sep 2023 08:16:11 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[road-to-dotnet-full-stack]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4453</guid>

					<description><![CDATA[<p>If you asked me 5 years ago what a JavaScript bundler is, I&#8217;d probably tell you it&#8217;s something people fight with for hours, just to get a simple web app set up 🤪 While this might have been closer to the truth in 2018, a lot has changed in JavaScript ecosystem until today. If you&#8217;re&#8230;</p>
<p>The post <a href="https://www.codejourney.net/what-is-a-javascript-bundler/">What Is A JavaScript Bundler?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">If you asked me 5 years ago what a JavaScript bundler is, I&#8217;d probably tell you it&#8217;s something people fight with for hours, just to get a simple web app set up <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92a.png" alt="🤪" class="wp-smiley" style="height: 1em; max-height: 1em;" /> While this might have been closer to the truth in 2018, a lot has changed in JavaScript ecosystem until today.</p>



<p class="wp-block-paragraph">If you&#8217;re starting your web development journey, or maybe have already dived into it, but are not really sure what JS bundlers are and what&#8217;s their role, you&#8217;re reading a proper piece of explanation <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4453"></span>



<h2 class="wp-block-heading">Chaos and complexity &#8211; the issues</h2>



<p class="wp-block-paragraph">Let&#8217;s consider a very simple JavaScript app. We have just one page <code>index.html</code>. Our HTML is hydrated with <code>index.js</code> file, which adds some interactivity to it. In order to use it, we need to import <code>index.js</code> script in <code>index.html</code> file. We also decided to use an external library (Bootstrap), so we should also link the necessary CSS.</p>



<p class="wp-block-paragraph">We are linking the <code>index.js</code> with a <code>script</code> tag in <code>head</code> section:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-markup code-embed-pre line-numbers"  data-line="2" data-start="1" data-line-offset="0"><code class="language-markup code-embed-code">&lt;head&gt;<br/>    &lt;script type=&quot;module&quot; src=&quot;index.js&quot;&gt;&lt;/script&gt;<br/>    &lt;link<br/>      href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css&quot;<br/>      rel=&quot;stylesheet&quot;<br/>      integrity=&quot;sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65&quot;<br/>      crossorigin=&quot;anonymous&quot;<br/>    /&gt;<br/>    &lt;meta charset=&quot;UTF-8&quot; /&gt;<br/>    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;<br/>    &lt;title&gt;My WebPage&lt;/title&gt;<br/>  &lt;/head&gt;</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">Linking internal scripts and external library files in HTML page</span> </div> </div></div>



<p class="wp-block-paragraph">Of course, as we are building a web application, we won&#8217;t put all the JavaScript code in <code>index.js</code>. That&#8217;s why we created two separate files with some functionalities: <code>my-utils.js</code> and <code>navigation.js</code>. </p>



<p class="wp-block-paragraph">For instance, the <code>my-utils.js</code> exports a few functions:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-javascript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-javascript code-embed-code">export function doSomethingNice() {<br/>  alert(&quot;Nice!&quot;);<br/>}<br/><br/>export function notUsedFunctionA() {<br/>  alert(&quot;Not used function A&quot;);<br/>}<br/><br/>export function notUsedFunctionB() {<br/>  alert(&quot;Not used function B&quot;);<br/>}<br/><br/>export function notUsedFunctionC() {<br/>  alert(&quot;Not used function C&quot;);<br/>}</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">Functions exported from a JavaScript module file</span> </div> </div></div>



<p class="wp-block-paragraph">Notice the not used functions there &#8211; we&#8217;ll get to the point of them soon.</p>



<p class="wp-block-paragraph">Next, our <code>index.js</code> file imports what it needs and adds some interactivity to the HTML elements:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-javascript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-javascript code-embed-code">import { doSomethingNice } from &quot;./my-utils.js&quot;;<br/>import { reloadThePage } from &quot;./navigation.js&quot;;<br/><br/>document<br/>  .getElementById(&quot;reload-page-btn&quot;)<br/>  .addEventListener(&quot;click&quot;, reloadThePage);<br/><br/>document<br/>  .getElementById(&quot;say-sth-nice-btn&quot;)<br/>  .addEventListener(&quot;click&quot;, doSomethingNice);</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">index.js &#8211; adding interactivity to index.html</span> </div> </div></div>



<p class="wp-block-paragraph">If we now open our webpage, we can see the network activity when the page is loaded:</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1131" height="330" data-attachment-id="4464" data-permalink="https://www.codejourney.net/what-is-a-javascript-bundler/html-loading-javascript-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/html-loading-javascript-1.png?fit=1131%2C330&amp;ssl=1" data-orig-size="1131,330" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="html-loading-javascript-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/html-loading-javascript-1.png?fit=1131%2C330&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/html-loading-javascript-1.png?resize=1131%2C330&#038;ssl=1" alt="" class="wp-image-4464" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/html-loading-javascript-1.png?w=1131&amp;ssl=1 1131w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/html-loading-javascript-1.png?resize=768%2C224&amp;ssl=1 768w" sizes="auto, (max-width: 1131px) 100vw, 1131px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Notice that all 3 JavaScript files are fetched separately: <code>index.js</code>, <code>my-utils.js</code> and <code>navigation.js</code>.</p>



<p class="wp-block-paragraph">What&#8217;s more, if you check the contents of <code>my-utils.js</code>, it obviously loads the whole script, containing even the not used functions:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="558" height="300" data-attachment-id="4465" data-permalink="https://www.codejourney.net/what-is-a-javascript-bundler/html-utils-fetching-content/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/html-utils-fetching-content.png?fit=558%2C300&amp;ssl=1" data-orig-size="558,300" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="html-utils-fetching-content" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/html-utils-fetching-content.png?fit=558%2C300&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/html-utils-fetching-content.png?resize=558%2C300&#038;ssl=1" alt="" class="wp-image-4465"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">I think you might already feel that this can get a little problematic <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Imagine managing this when you have hundreds of your own JavaScript files plus dozens of external libraries. Not only will your app be making hundreds of network requests to fetch every single file, but it will always fetch everything &#8211; even the stuff your page doesn&#8217;t use.</p>



<p class="wp-block-paragraph">Here&#8217;s where a JavaScript bundler comes into the field. </p>



<p class="wp-block-paragraph">You can find full source code of this JavaScript app <a href="https://github.com/dsibinski/codejourney/tree/main/javascript-bundlers/no-bundler-app">here</a>.</p>



<h2 class="wp-block-heading">What does a JavaScript bundler do?</h2>



<p class="wp-block-paragraph">JavaScript bundler produces <em>bundles</em> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> But what is a bundle? It&#8217;s basically a static file, optimized to be served to the client (in our case: a web browser). The main goal is to produce a single bundle file from multiple dependencies. In effect, the user&#8217;s browser doesn&#8217;t need to fetch so many files separately. But how is such a bundle created?</p>



<p class="wp-block-paragraph">First, a JavaScript bundler needs to know the <em>entry point</em>. It&#8217;s a kind of root in which our &#8220;code tree&#8221; begins. In the case of our sample JavaScript application from the previous paragraph, a perfect candidate for an entry point would be the <code>index.js</code> file. Modern bundlers support multiple entry points. It can be very useful if you&#8217;re building a multipage application, so each page can have its own entry point.</p>



<p class="wp-block-paragraph">The next step is to create a dependency graph. The JavaScript bundler is basically starting from the root (entry point) and traverses all dependencies referenced from it, as well as all of these dependencies&#8217; dependencies. Having the dependency graph, bundler knows what is exactly used by what and in which place of our app. </p>



<p class="wp-block-paragraph">This is how you can imagine the graph of dependencies:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><a href="https://paulallies.medium.com/webpack-managing-javascript-and-css-dependencies-3b4913f49c58"><img data-recalc-dims="1" loading="lazy" decoding="async" width="786" height="344" data-attachment-id="4469" data-permalink="https://www.codejourney.net/what-is-a-javascript-bundler/webpack-dependency-graph/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-dependency-graph.webp?fit=786%2C344&amp;ssl=1" data-orig-size="786,344" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="webpack-dependency-graph" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-dependency-graph.webp?fit=786%2C344&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-dependency-graph.webp?resize=786%2C344&#038;ssl=1" alt="" class="wp-image-4469" style="width:858px;height:348px" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-dependency-graph.webp?w=786&amp;ssl=1 786w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-dependency-graph.webp?resize=768%2C336&amp;ssl=1 768w" sizes="auto, (max-width: 786px) 100vw, 786px" /></a></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Module bundlers like <a href="https://webpack.js.org/">webpack</a> not only know the dependencies of your entry point. These tools even check what each dependency uses. Thanks to building such a detailed dependency graph, the bundler can introduce multiple optimizations into the bundle file.</p>



<p class="wp-block-paragraph">Finally, JavaScript bundler outputs the actual bundles. As I mentioned, bundles can be highly optimized by applying techniques like <a href="https://webpack.js.org/guides/code-splitting/">code splitting</a>, <a href="https://vitejs.dev/guide/features.html#css">CSS inlining</a>, <a href="https://parceljs.org/features/development/#hot-reloading">HMR</a> and various performance optimizations.</p>



<p class="wp-block-paragraph">JavaScript bundler might also ensure the backwards-compatibility with older web browsers by converting some newer JavaScript constructs used in your code to their equivalents from previous JS versions.</p>



<p class="wp-block-paragraph">What&#8217;s interesting, modern bundlers can handle not only JS files, but also CSS, HTML and even images.</p>



<h2 class="wp-block-heading">JavaScript bundler in action</h2>



<p class="wp-block-paragraph">Currently, the most popular JavaScript bundles is (still) <a href="https://webpack.js.org/">webpack</a>. It has been the first really advanced bundler created for both the browser and NodeJS. </p>



<p class="wp-block-paragraph">You might have heard unpleasant things about webpack and in fact, its configuration can get really <em>spaghetti</em> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92a.png" alt="🤪" class="wp-smiley" style="height: 1em; max-height: 1em;" /> There are simpler alternatives out there, but let&#8217;s start with what&#8217;s the most common tool used in web development today. </p>



<h3 class="wp-block-heading">Adding webpack to a JavaScript app</h3>



<p class="wp-block-paragraph">Our sample app already has a <code>package.json</code> file (we used JavaScript modules), so we can install webpack with this command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
npm install --save-dev webpack webpack-cli
</pre></div>


<p class="wp-block-paragraph">Now we should reorganize the files a bit. Let&#8217;s put all scripts in <code>src</code> folder and move <code>index.html</code> to <code>dist</code> folder. Finally, it looks like that:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="241" height="217" data-attachment-id="4475" data-permalink="https://www.codejourney.net/what-is-a-javascript-bundler/webpack-app-structure/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-structure.png?fit=241%2C217&amp;ssl=1" data-orig-size="241,217" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="webpack-app-structure" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-structure.png?fit=241%2C217&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-structure.png?resize=241%2C217&#038;ssl=1" alt="" class="wp-image-4475"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Using the folder named <code>dist</code> is very common. It stands for <em>distributable</em>, which means the code ready to be distributed = served to the public. This is where our bundles will be located. As the <code>index.html</code> is directly served to the public, we also place it there.</p>



<p class="wp-block-paragraph">With such a folders structure, there&#8217;s nothing more we need to configure for webpack to work. By default, webpack looks for <code>src/index.js</code> file which we already have and outputs bundles into the <code>dist</code> folder. To use more advanced features or multiple entry points, a <a href="https://dev.to/typescripttv/6-ways-to-configure-webpack-5a33">configuration file should be added</a>.</p>



<p class="wp-block-paragraph">In our case, let&#8217;s go with the zero-config approach. The only thing we need is to add a <code>script</code> entry to <code>package.json</code>:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-javascript code-embed-pre line-numbers"  data-line="2" data-start="1" data-line-offset="0"><code class="language-javascript code-embed-code">  &quot;scripts&quot;: {<br/>    &quot;build&quot;: &quot;webpack&quot;,<br/>    &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;<br/>  },</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">package.json with webpack build script</span> </div> </div></div>



<p class="wp-block-paragraph">Let&#8217;s now run <code>npm run build</code> and see what happens:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="483" height="154" data-attachment-id="4476" data-permalink="https://www.codejourney.net/what-is-a-javascript-bundler/webpack-build-output/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-build-output.png?fit=483%2C154&amp;ssl=1" data-orig-size="483,154" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="webpack-build-output" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-build-output.png?fit=483%2C154&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-build-output.png?resize=483%2C154&#038;ssl=1" alt="" class="wp-image-4476"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">It seems that webpack created the <code>main.js</code> asset (bundle):</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="351" height="245" data-attachment-id="4477" data-permalink="https://www.codejourney.net/what-is-a-javascript-bundler/webpack-main-bundle/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-main-bundle.png?fit=351%2C245&amp;ssl=1" data-orig-size="351,245" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="webpack-main-bundle" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-main-bundle.png?fit=351%2C245&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-main-bundle.png?resize=351%2C245&#038;ssl=1" alt="" class="wp-image-4477"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Let&#8217;s make sure that our <code>index.html</code> page links this bundle file properly:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-markup code-embed-pre line-numbers"  data-line="4" data-start="1" data-line-offset="0"><code class="language-markup code-embed-code">&lt;!DOCTYPE html&gt;<br/>&lt;html lang=&quot;en&quot;&gt;<br/>  &lt;head&gt;<br/>    &lt;script type=&quot;module&quot; src=&quot;main.js&quot;&gt;&lt;/script&gt;</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">index.html &#8211; linking main.js bundle</span> </div> </div></div>



<p class="wp-block-paragraph">Now, let&#8217;s open our <code>index.html</code> page and see how the network requests look like now:</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1138" height="283" data-attachment-id="4478" data-permalink="https://www.codejourney.net/what-is-a-javascript-bundler/webpack-app-bundle-fetching-network/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-bundle-fetching-network.png?fit=1138%2C283&amp;ssl=1" data-orig-size="1138,283" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="webpack-app-bundle-fetching-network" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-bundle-fetching-network.png?fit=1138%2C283&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-bundle-fetching-network.png?resize=1138%2C283&#038;ssl=1" alt="" class="wp-image-4478" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-bundle-fetching-network.png?w=1138&amp;ssl=1 1138w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-bundle-fetching-network.png?resize=768%2C191&amp;ssl=1 768w" sizes="auto, (max-width: 1138px) 100vw, 1138px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Wow, that&#8217;s something different from what we had previously! Notice that now only 1 script, the <code>main.js</code> file, is fetched by the webpage. There were 3 before: <code>index.js</code>, <code>my-utils.js</code> and <code>navigation.js</code>. Of course, the web page works exactly as before.</p>



<p class="wp-block-paragraph">Let us also examine the contents of the fetched <code>main.js</code> file:</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="942" height="248" data-attachment-id="4479" data-permalink="https://www.codejourney.net/what-is-a-javascript-bundler/webpack-app-main-bundle-content/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-main-bundle-content.png?fit=942%2C248&amp;ssl=1" data-orig-size="942,248" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="webpack-app-main-bundle-content" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-main-bundle-content.png?fit=942%2C248&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-main-bundle-content.png?resize=942%2C248&#038;ssl=1" alt="" class="wp-image-4479" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-main-bundle-content.png?w=942&amp;ssl=1 942w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/08/webpack-app-main-bundle-content.png?resize=768%2C202&amp;ssl=1 768w" sizes="auto, (max-width: 942px) 100vw, 942px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Pay attention what happened here. Webpack has nicely inlined all the external code we used directly into the <code>main.js</code> bundle. What&#8217;s more, the exported, but not used functions from <code>my-utils.js</code> are not present here at all! When building the dependency graph, webpack noticed that those functions are not used, so it didn&#8217;t include them<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">This is basically how webpack and most JavaScript bundlers work. Their role is to deliver the smallest and the most optimized bundles possible. This ultimately saves a lot of bandwidth by avoiding unnecessary network requests the client browser would otherwise need to make. Cutting out the unused code makes the bundles smaller, again reducing the network usage.</p>



<p class="wp-block-paragraph">You can find full source code of the webpack app <a href="https://github.com/dsibinski/codejourney/tree/main/javascript-bundlers/webpack-app">here</a>.</p>



<h3 class="wp-block-heading">Webpack has a lot more to offer</h3>



<p class="wp-block-paragraph">From all the JavaScript bundlers used today, webpack is the most advanced one. It&#8217;s the most mature one as well. It offers dozens of customizations, <a href="https://webpack.js.org/concepts/#plugins">plugins</a> and <a href="https://webpack.js.org/concepts/#loaders">loaders</a>. You can also easily add <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">TypeScript</a> support. </p>



<p class="wp-block-paragraph">You can do really crazy stuff with webpack <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> However, if you are starting your web development journey, don&#8217;t get overwhelmed by learning it all. Just be aware that webpack can do almost everything you might need. It&#8217;s just a matter of <a href="https://stackoverflow.com/questions/tagged/webpack">searching StackOverflow</a> or asking <a href="https://github.com/features/copilot">Copilot</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Alternatives to webpack</h3>



<p class="wp-block-paragraph">In recent years, developers created a few other amazing JavaScript bundlers. I recommend you to pay attention to them, because webpack doesn&#8217;t have to be your first choice today. Webpack is still <a href="https://create-react-app.dev/">used in CRA</a>, which is believed to be a default way of creating new React applications. This is what makes it very widely used, but you don&#8217;t need to follow this path <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">I recommend checking <a href="https://parceljs.org/">Parcel</a>, <a href="https://esbuild.github.io/">esbuild</a> and <a href="https://vitejs.dev/">ViteJS</a>. These are modern bundlers created to, among others, eliminate some of webpack&#8217;s burdens. If you&#8217;re starting out and don&#8217;t want to get yourself busy with bundling configuration, I especially recommend creating your next app with Parcel.</p>



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



<p class="wp-block-paragraph">That&#8217;s all that you need to know about JavaScript bundlers to be able to work with them and understand what&#8217;s happening when executing this magic <code>npm run build</code> script <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">If you&#8217;re a .NET developer, and you enjoyed this article, I think you may also find my free guide useful:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://mailchi.mp/055b94b02391/net-full-stack-web-developer-guide" target="_blank" rel=" noreferrer noopener"><img data-recalc-dims="1" loading="lazy" decoding="async" width="300" height="300" data-attachment-id="4950" data-permalink="https://www.codejourney.net/how-to-become-dotnet-full-stack-in-2025-300-300/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?fit=300%2C300&amp;ssl=1" data-orig-size="300,300" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="How-to-become-dotnet-full-stack-in-2025-300-300" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?fit=300%2C300&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?resize=300%2C300&#038;ssl=1" alt="16 Steps to become .NET full stack developer in 2025 - download a free guide" class="wp-image-4950" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?w=300&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2025/01/How-to-become-dotnet-full-stack-in-2025-300-300.jpg?resize=50%2C50&amp;ssl=1 50w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></figure>
</div>


<p class="wp-block-paragraph"></p>
<p>The post <a href="https://www.codejourney.net/what-is-a-javascript-bundler/">What Is A JavaScript Bundler?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/what-is-a-javascript-bundler/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4453</post-id>	</item>
		<item>
		<title>How (And Why?) To Wrap External Libraries?</title>
		<link>https://www.codejourney.net/how-and-why-to-wrap-external-libraries/</link>
					<comments>https://www.codejourney.net/how-and-why-to-wrap-external-libraries/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Mon, 20 Feb 2023 09:00:00 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[npm]]></category>
		<category><![CDATA[road-to-dotnet-full-stack]]></category>
		<category><![CDATA[typescript]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4346</guid>

					<description><![CDATA[<p>If you use external libraries in your application, wrapping them may be very helpful. How to wrap external libraries and why it&#8217;s worth doing that? Today we&#8217;re going to dive into that, based on a TypeScript web app example 😉 Why? You probably know what a&#160;wrapper is. As its name suggests, it&#8217;s a practice of&#8230;</p>
<p>The post <a href="https://www.codejourney.net/how-and-why-to-wrap-external-libraries/">How (And Why?) To Wrap External Libraries?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">If you use external libraries in your application, wrapping them may be very helpful. How to wrap external libraries and why it&#8217;s worth doing that? Today we&#8217;re going to dive into that, based on a TypeScript web app example <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4346"></span>



<h2 class="wp-block-heading">Why?</h2>



<p class="wp-block-paragraph">You probably know what a&nbsp;<em>wrapper</em> is. As its name suggests, it&#8217;s a practice of putting another layer on a piece of something. In our case, <em>wrapping</em>&nbsp;a piece of code in another piece of code <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">But why would you do that? To make your life easier! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4aa.png" alt="💪" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>Wrapping external libraries lets you abstract your code from their implementation details. In effect, it makes your life a lot easier when you want to keep the behavior, but change the library providing it. This approach also lets you use only those features from a given external dependency that you actually need.<br>Let&#8217;s see that with an example.</p>



<h2 class="wp-block-heading">Wrapping HTTP client</h2>



<p class="wp-block-paragraph">A very good example is HTTP client&nbsp;wrapper. HTTP calls are used in almost every web application. In order to perform them, we need to choose an HTTP client. We can either use <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">fetch</a></code>, or something more sophisticated like&nbsp;<code><a href="https://axios-http.com/docs/intro">axios</a></code>.</p>



<p class="wp-block-paragraph">However, with time, we may decide to replace it with something else. There might be many reasons for that &#8211; either the library stops to be maintained or something new and better is out there. It would be a shame if we&#8217;d now need to change the code in those thousands of places where the current library is being used. This would take a lot of time and might be error-prone. We can definitely prepare better for such cases <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Create HttpClient wrapper for axios</h3>



<p class="wp-block-paragraph">Let&#8217;s say that, for now, we will go with <code>axios</code>. Instead of <a href="https://axios-http.com/docs/example">calling it directly from our code</a>:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="2,10-11" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">import { useEffect, useState } from &quot;react&quot;;<br/>import axios from &quot;axios&quot;;<br/>import { Product } from &quot;../types/product&quot;;<br/>import { DummyJsonProductsResult } from &quot;../types/dummyJsonProductsResult&quot;;<br/><br/>export const ProductsList = () =&gt; {<br/>  const [products, setProducts] = useState&lt;Product[] | null&gt;(null);<br/><br/>  useEffect(() =&gt; {<br/>    axios<br/>      .get&lt;DummyJsonProductsResult&gt;(&quot;https://dummyjson.com/products&quot;)<br/>      .then((result) =&gt; {<br/>        setProducts(result.data.products);<br/>      });<br/>  }, []);<br/> <br/> // ...<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">ProductsList.tsx &#8211; calling axios directly from component&#039;s code</span> </div> </div></div>



<p class="wp-block-paragraph">I will create an <em>HttpClient</em> wrapper for it and use it instead.</p>



<p class="wp-block-paragraph">First, I create <code>httpClient.ts</code> file in <code>wrappers</code> folder. I like to have such a catalog in my React projects and keep all the wrappers there.</p>



<p class="wp-block-paragraph">I start writing all wrappers with an interface. In that case, I treat the interface as a <em>contract</em>. It should say what I need this small wrapper to do, without worrying about implementation details.</p>



<p class="wp-block-paragraph"><code>IHttpClient</code> interface initially looks as follows:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">interface IHttpClient {<br/>  get&lt;TResponse&gt;(url: string): Promise&lt;TResponse&gt;;<br/>}</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">httpClient.ts &#8211; IHttpClient interface (get only)</span> </div> </div></div>



<p class="wp-block-paragraph">That&#8217;s what we have so far. We just need to retrieve the data with <code>GET</code> method.</p>



<p class="wp-block-paragraph">Next step is to create the actual implementation of <code>IHttpClient</code> using <code>axios</code>. This is pretty straightforward using a <code>class</code> implementing <code>IHttpClient</code> interface and taking a look at <a href="https://axios-http.com/docs/instance"><code>axios</code>&#8216;s documentation</a>:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">class AxiosHttpClient implements IHttpClient {<br/>  private instance: AxiosInstance | null = null;<br/><br/>  private get axiosClient(): AxiosInstance {<br/>    return this.instance ?? this.initAxiosClient();<br/>  }<br/><br/>  private initAxiosClient() {<br/>    return axios.create();<br/>  }<br/><br/>  get&lt;TResponse&gt;(url: string): Promise&lt;TResponse&gt; {<br/>    return new Promise&lt;TResponse&gt;((resolve, reject) =&gt; {<br/>      this.axiosClient<br/>        .get&lt;TResponse, AxiosResponse&lt;TResponse&gt;&gt;(url)<br/>        .then((result) =&gt; {<br/>          resolve(result.data);<br/>        })<br/>        .catch((error: Error | AxiosError) =&gt; {<br/>          reject(error);<br/>        });<br/>    });<br/>  }<br/>}</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">httpClient.ts &#8211; AxiosHttpClient implementation (get only)</span> </div> </div></div>



<p class="wp-block-paragraph">This implementation lets us encapsulate a simple singleton inside the class.</p>



<p class="wp-block-paragraph">The last step here is to expose the instance of our HTTP client. Remember to <strong>always export the interface type variable</strong>:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export const httpClient: IHttpClient = new AxiosHttpClient();</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">httpClient.ts &#8211; exporting AxiosHttpClient as IHttpClient singleton instance</span> </div> </div></div>



<p class="wp-block-paragraph">That&#8217;s basically how we wrap external libraries in TypeScript. Easy-peasy <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Using the wrapper</h3>



<p class="wp-block-paragraph">I can now use our wrapper in <code>ProductsList.tsx</code> component:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="2,10-11" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">import { useEffect, useState } from &quot;react&quot;;<br/>import { httpClient } from &quot;../wrappers/httpClient&quot;; // we don&#039;t import axios here anymore<br/>import { Product } from &quot;../types/product&quot;;<br/>import { DummyJsonProductsResult } from &quot;../types/dummyJsonProductsResult&quot;;<br/><br/>export const ProductsList = () =&gt; {<br/>  const [products, setProducts] = useState&lt;Product[] | null&gt;(null);<br/><br/>  useEffect(() =&gt; {<br/>    httpClient // instead of axios, we use our wrapper in components<br/>      .get&lt;DummyJsonProductsResult&gt;(&quot;https://dummyjson.com/products&quot;)<br/>      .then((result) =&gt; {<br/>        setProducts(result.data.products);<br/>      });<br/>  }, []);<br/> <br/> // ...<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">ProductsList.tsx &#8211; using IHttpClient wrapper</span> </div> </div></div>



<p class="wp-block-paragraph">Notice how easy that was. Since now, we only import stuff from <code>axios</code> package in <code>httpClient.ts</code> file. Only this single file is dependent on <a href="https://www.npmjs.com/package/axios"><code>axios</code> npm package</a>. None of our components (and other project files) know about <code>axios</code>. Our IDE only knows that the wrapper is an object instance fulfilling <code>IHttpClient</code> contract:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="537" height="332" data-attachment-id="4361" data-permalink="https://www.codejourney.net/how-and-why-to-wrap-external-libraries/1_usingwrapperinterface/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/1_UsingWrapperInterface.png?fit=537%2C332&amp;ssl=1" data-orig-size="537,332" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1_UsingWrapperInterface" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/1_UsingWrapperInterface.png?fit=537%2C332&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/1_UsingWrapperInterface.png?resize=537%2C332&#038;ssl=1" alt="Interface-implementing wrapper instance usage in Visual Studio Code" class="wp-image-4361"/></figure>
</div>


<h3 class="wp-block-heading">Extra wrapper features</h3>



<p class="wp-block-paragraph">Apart from nicely isolating us from dependencies, wrappers have more advantages. One of them is a possibility to configure the library in a single place. In our example with <code>axios</code> &#8211; imagine that one day you want to add custom headers to each HTTP request. Having all API calls going via <code>AxiosHttpClient</code>, you can configure such things there, in a single place. That way, you follow the <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY principle</a> and keep all the logic related to <code>axios</code> (or to any other external dependency) in a single place. It also comes with benefits like easy testability etc.</p>



<p class="wp-block-paragraph">For clarity, I also added <code>post</code> support to our <code>IHttpClient</code>. You can <a href="https://github.com/dsibinski/codejourney/commit/200f31ba0c5483f3e834a5ec4cd82566887e3d98">check it here</a>.</p>



<h2 class="wp-block-heading">Replacing the wrapped library</h2>



<p class="wp-block-paragraph">Ok, it&#8217;s time to have our solution battle-tested. We have the HTTP client nicely wrapped and exposed as an instance of <code>IHttpClient</code>. However, we came to the conclusion that <code>axios</code> is not good enough, and we want to have it replaced with <code>fetch</code>.</p>



<p class="wp-block-paragraph">Remember that in the real web application, you would have hundreds or thousands of usages of <code>IHttpClient</code> instance. That&#8217;s where the power of wrappers comes into play <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">So how do I make sure those thousands of usages will now use <code>fetch</code> instead of <code>axios</code>? That&#8217;s actually pretty straightforward. I&#8217;ll simply add a new class &#8211; <code>FetchHttpClient</code> implementing <code>IHttpClient</code> interface:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="4,23" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">class FetchHttpClient implements IHttpClient {<br/>  get&lt;TResponse&gt;(url: string): Promise&lt;TResponse&gt; {<br/>    return new Promise&lt;TResponse&gt;((resolve, reject) =&gt; {<br/>      fetch(url)<br/>        .then((response) =&gt;<br/>          response<br/>            .json()<br/>            .then((responseJson) =&gt; {<br/>              resolve(responseJson as TResponse);<br/>            })<br/>            .catch((error: Error) =&gt; {<br/>              reject(`Response JSON parsing error: ${error}`);<br/>            })<br/>        )<br/>        .catch((error: Error) =&gt; {<br/>          reject(error);<br/>        });<br/>    });<br/>  }<br/><br/>  post&lt;TResponse&gt;(url: string, data?: object): Promise&lt;TResponse&gt; {<br/>    return new Promise&lt;TResponse&gt;((resolve, reject) =&gt; {<br/>      fetch(url, {<br/>        method: &quot;POST&quot;,<br/>        headers: {<br/>          &quot;Content-Type&quot;: &quot;application/json&quot;,<br/>        },<br/>        body: JSON.stringify(data),<br/>      })<br/>        .then((response) =&gt;<br/>          response<br/>            .json()<br/>            .then((responseJson) =&gt; {<br/>              resolve(responseJson as TResponse);<br/>            })<br/>            .catch((error: Error) =&gt; {<br/>              reject(`Response JSON parsing error: ${error}`);<br/>            })<br/>        )<br/>        .catch((error: Error) =&gt; {<br/>          reject(error);<br/>        });<br/>    });<br/>  }<br/>}</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">httpClient.ts &#8211; new FetchHttpClient using fetch for get and post</span> </div> </div></div>



<p class="wp-block-paragraph">For completion, I included <code>POST</code> here as well.</p>



<p class="wp-block-paragraph">The one last thing I have to do to make our new <code>FetchHttpClient</code> be used in the whole app in place of <code>AxiosHttpClient</code> is to change a single line with export:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export const httpClient: IHttpClient = new FetchHttpClient(); // instead of new AxiosHttpClient()</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">httpClient.ts &#8211; AxiosHttpClient replaced with FetchHttpClient</span> </div> </div></div>



<p class="wp-block-paragraph">and that&#8217;s it! Our whole application now uses <code>fetch</code> for <code>GET</code> and <code>POST</code> HTTP requests <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> And it even still works <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



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



<p class="wp-block-paragraph">I hope that now you see how important it is to wrap external libraries. We have seen that on JavaScript/TypeScript app example, but this is applicable to any programming language and framework. </p>



<p class="wp-block-paragraph">It&#8217;s always good to be as independent as possible of 3rd party stuff. Too many times I&#8217;ve been in a situation that some <code>npm</code> package is so extensively used in a project, directly in the source code in hundreds of places, that it cannot be replaced without spending several days on it. Creating wrappers forces us to think abstract, which is another great advantage.</p>



<p class="wp-block-paragraph">You can find the complete source code here: <a href="https://github.com/dsibinski/codejourney/tree/main/wrapping-external-libraries">https://github.com/dsibinski/codejourney/tree/main/wrapping-external-libraries</a></p>


<script>(function() {
	window.mc4wp = window.mc4wp || {
		listeners: [],
		forms: {
			on: function(evt, cb) {
				window.mc4wp.listeners.push(
					{
						event   : evt,
						callback: cb
					}
				);
			}
		}
	}
})();
</script><!-- Mailchimp for WordPress v4.13.0 - https://wordpress.org/plugins/mailchimp-for-wp/ --><form id="mc4wp-form-1" class="mc4wp-form mc4wp-form-2612" method="post" data-id="2612" data-name="Download a free guide form" ><div class="mc4wp-form-fields"><table bgcolor="#f2f6f5"><tr><td> <p><p>
    <label>
<h1 style="">
  <center>GET A FREE GUIDE <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f381.png" alt="🎁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></center>
      </h1>        
      <h2 style="font-family: Helvetica">
        <center>16 STEPS TO BECOME <br/>.NET FULL STACK WEB DEVELOPER </br>IN 2025</center>
      </h2>
</p>
  <center><div>
	<input type="email" name="EMAIL" placeholder="Email address" required />
    <p>
    <input type="text" name="FNAME" placeholder="Your name"
    required="">
  </p>
  </div>
    <center>

	<center><input type="submit" value="DOWNLOAD THE FREE GUIDE" style="color: #7b1fa2; font-weight:bold; font-size: 20px" /></center>
<p style="font-size: 12px; font-style: italic;">After you sign up, I may be sending you some emails with additional free content from time to time.
<br/>No spam, only awesome stuff</p>
</p></td></tr></table>

</div><label style="display: none !important;">Leave this field empty if you're human: <input type="text" name="_mc4wp_honeypot" value="" tabindex="-1" autocomplete="off" /></label><input type="hidden" name="_mc4wp_timestamp" value="1781713174" /><input type="hidden" name="_mc4wp_form_id" value="2612" /><input type="hidden" name="_mc4wp_form_element_id" value="mc4wp-form-1" /><div class="mc4wp-response"></div></form><!-- / Mailchimp for WordPress Plugin -->
<p>The post <a href="https://www.codejourney.net/how-and-why-to-wrap-external-libraries/">How (And Why?) To Wrap External Libraries?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/how-and-why-to-wrap-external-libraries/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4346</post-id>	</item>
		<item>
		<title>Adding Meatballs Menu To React-Table Rows</title>
		<link>https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/</link>
					<comments>https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Mon, 06 Feb 2023 08:16:17 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bootstrap]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[react]]></category>
		<category><![CDATA[react-table]]></category>
		<category><![CDATA[typescript]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4302</guid>

					<description><![CDATA[<p>Meatballs menu (⋯), also called three horizontal dots menu, is a great way of providing contextual options for grid rows. In this article, I will show you how to add the meatballs menu to a table built with @tanstack/react-table. After reading this article, you will know how to add such a menu to your React&#8230;</p>
<p>The post <a href="https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/">Adding Meatballs Menu To React-Table Rows</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Meatballs menu (⋯), also called <em>three horizontal dots menu</em>, is a great way of providing contextual options for grid rows. In this article, I will show you how to add the meatballs menu to a table built with <a href="https://www.npmjs.com/package/@tanstack/react-table">@tanstack/react-table</a>.</p>



<p class="wp-block-paragraph">After reading this article, you will know how to add such a menu to your React app. The end result will look as in the highlighted picture of this article <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4302"></span>



<h2 class="wp-block-heading">Creating a table with row selection support</h2>



<p class="wp-block-paragraph">First, let&#8217;s define a type of data that we want to display. For our example, we will display a list of <code>Car</code>s:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">export type Car = {<br/>  id: string;<br/>  brand: string;<br/>  model: string;<br/>  productionYear: number;<br/>  isAvailable: boolean;<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">Car.ts</span> </div> </div></div>



<p class="wp-block-paragraph">Next, we create a new component called <code>CarsTable</code>, responsible for rendering the table. We will use <a href="https://www.npmjs.com/package/@tanstack/react-table">@tanstack/react-table</a> for the table behavior and <a href="https://www.npmjs.com/package/react-bootstrap">react-bootstrap</a> for UI elements.</p>



<p class="wp-block-paragraph">I implemented the <code>CarsTable</code> component in <a href="https://tanstack.com/table/v8/docs/examples/react/basic">quite a standard way according to react-table docs</a>, so I won&#8217;t copy-paste it here. You can check the whole component&#8217;s code <a href="https://github.com/dsibinski/react-table-context-menu/blob/faccde72b4be060c9dbca3d59d7b1506bc9f9b01/src/components/CarsTable.tsx">here</a>. What&#8217;s interesting is that I added support for row selection in a way that makes our table a <a href="https://reactjs.org/docs/forms.html#controlled-components">controlled React component</a>:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="2-3,10,14,16" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">type CarsTableProps = {<br/>  selectedCar: Car | null;<br/>  onCarSelected: (car: Car) =&gt; void;<br/>};<br/>export const CarsTable = (props: CarsTableProps) =&gt; {<br/>  return (<br/>    // ...<br/>    &lt;tbody&gt;<br/>        {table.getRowModel().rows.map((row) =&gt; {<br/>          const isActive = row.original.id === props.selectedCar?.id;<br/>          return (<br/>            &lt;tr<br/>              key={row.id}<br/>              style={isActive === true ? { backgroundColor: &quot;#3a7a11&quot; } : undefined}<br/>              onClick={() =&gt; {<br/>                props.onCarSelected(row.original);<br/>              }}<br/>            &gt;<br/>              {row.getVisibleCells().map((cell) =&gt; (<br/>                &lt;td key={cell.id}&gt;<br/>                  {flexRender(cell.column.columnDef.cell, cell.getContext())}<br/>                &lt;/td&gt;<br/>              ))}<br/>            &lt;/tr&gt;<br/>          );<br/>        })}<br/>      &lt;/tbody&gt;<br/>    // ...<br/>  )<br/>}</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">CarsTable.tsx &#8211; controlled row selection</span> </div> </div></div>



<p class="wp-block-paragraph">As you can see, <code>selectedCar</code> and <code>onCarSelected</code> are managed from outside. Line 14 shows how the row color gets changed for the currently selected car. I recently had to deal with such a case in one of my projects.</p>



<p class="wp-block-paragraph">So far, so good. This is how it looks, populated with sample data:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="991" height="440" data-attachment-id="4312" data-permalink="https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/1_initialtable/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/1_InitialTable.png?fit=991%2C440&amp;ssl=1" data-orig-size="991,440" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1_InitialTable" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/1_InitialTable.png?fit=991%2C440&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/1_InitialTable.png?resize=991%2C440&#038;ssl=1" alt="react-table table with row selection support" class="wp-image-4312" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/1_InitialTable.png?w=991&amp;ssl=1 991w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/1_InitialTable.png?resize=768%2C341&amp;ssl=1 768w" sizes="auto, (max-width: 991px) 100vw, 991px" /></figure>
</div>


<h2 class="wp-block-heading">Adding meatballs menu</h2>



<p class="wp-block-paragraph">Ok, we have a table. Now we want to add the meatballs menu. We need a three dots icon and a dropdown menu to open on clicking it.</p>



<p class="wp-block-paragraph">After quickly <a href="https://react-bootstrap.github.io/components/dropdowns/">going through the react-bootstrap docs</a>, let&#8217;s create a new component for that:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">import { Dropdown } from &quot;react-bootstrap&quot;;<br/>import { Car } from &quot;../types/Car&quot;;<br/>import CustomDivToggle from &quot;./CustomDivToggle&quot;;<br/>import { BsThreeDots } from &quot;react-icons/bs&quot;;<br/><br/>export const CarRowContextMenu = ({ carRow }: { carRow: Car }) =&gt; {<br/>  return (<br/>    &lt;Dropdown key={carRow.id}&gt;<br/>      &lt;Dropdown.Toggle as={CustomDivToggle} style={{ cursor: &quot;pointer&quot; }}&gt;<br/>        &lt;BsThreeDots /&gt;<br/>      &lt;/Dropdown.Toggle&gt;<br/>      &lt;Dropdown.Menu&gt;<br/>        &lt;Dropdown.Item&gt;Option 1&lt;/Dropdown.Item&gt;<br/>        &lt;Dropdown.Item&gt;Option 2&lt;/Dropdown.Item&gt;<br/>      &lt;/Dropdown.Menu&gt;<br/>    &lt;/Dropdown&gt;<br/>  );<br/>};</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">CarRowContextMenu.tsx</span> </div> </div></div>



<p class="wp-block-paragraph">As we want our dropdown toggle to have custom style, I had to provide <code>CustomDivToggle</code> as a <a href="https://react-bootstrap.github.io/components/dropdowns/#custom-dropdown-components">custom dropdown component</a>. It&#8217;s nothing very interesting, but you can check its implementation <a href="https://github.com/dsibinski/react-table-context-menu/blob/c98687413a28eecfc5fa4175a4b55a79dee8300f/src/components/CustomDivToggle.tsx">here</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Next, as we&#8217;d like our meatballs menu to be an additional column in the grid, it seems natural to <a href="https://tanstack.com/table/v8/docs/guide/column-defs#column-def-types">use <code>react-table</code>&#8216;s display column</a>. Let&#8217;s try adding it:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">columnHelper.display({<br/>      id: &quot;context-menu&quot;,<br/>      cell: (cellContext) =&gt; {<br/>        const row = cellContext.row.original;<br/>        return &lt;CarRowContextMenu carRow={row} /&gt;;<br/>      },<br/>    }),</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">CarsTable.tsx &#8211; adding meatballs menu with display-type column</span> </div> </div></div>



<p class="wp-block-paragraph">It looks we have it:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="984" height="442" data-attachment-id="4316" data-permalink="https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/3_contextmenuaddedv1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/3_ContextMenuAddedV1.png?fit=984%2C442&amp;ssl=1" data-orig-size="984,442" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3_ContextMenuAddedV1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/3_ContextMenuAddedV1.png?fit=984%2C442&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/3_ContextMenuAddedV1.png?resize=984%2C442&#038;ssl=1" alt="Meatballs menu added to the table with react-tabe's display column" class="wp-image-4316" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/3_ContextMenuAddedV1.png?w=984&amp;ssl=1 984w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/3_ContextMenuAddedV1.png?resize=768%2C345&amp;ssl=1 768w" sizes="auto, (max-width: 984px) 100vw, 984px" /></figure>
</div>


<p class="wp-block-paragraph">However, after clicking through it for a while, it seems we have an issue. The toggle only opens on every 2nd click:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1140" height="498" data-attachment-id="4317" data-permalink="https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/4_contextmenudoubleclickissue/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/4_ContextMenuDoubleClickIssue.gif?fit=1153%2C504&amp;ssl=1" data-orig-size="1153,504" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="4_ContextMenuDoubleClickIssue" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/4_ContextMenuDoubleClickIssue.gif?fit=1153%2C504&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/4_ContextMenuDoubleClickIssue.gif?resize=1140%2C498&#038;ssl=1" alt="Meatballs menu with react-table's display column. Double-click issue" class="wp-image-4317" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/4_ContextMenuDoubleClickIssue.gif?w=1153&amp;ssl=1 1153w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/4_ContextMenuDoubleClickIssue.gif?resize=768%2C336&amp;ssl=1 768w" sizes="auto, (max-width: 1140px) 100vw, 1140px" /></figure>
</div>


<p class="wp-block-paragraph">Why is that? The reason is our controlled <code>CarsTable</code> component. On clicking a new row, the change event occurs, which triggers the re-render of the <code>CarsTable</code> component (because <code>selectedCar</code> <em>actually</em> changes). It makes <code>react-table</code> re-render the table, with the meatballs menu in its default state (collapsed). On clicking the menu in the same row again, the change event occurs, but the <code>selectedCar</code> <em>does not actually change</em>, which <em>does not</em> trigger the re-render. Initially, it took me a while to figure that out <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Fixing double-click issue</h2>



<p class="wp-block-paragraph">In our case, a fix for the double click issue is quite simple. Instead of adding the column with the menu using <code>columnHelper.display()</code> function from <code>react-table</code>, we can render it <em>manually</em>. To do that, we should simply add a new <code>&lt;td&gt;</code> to each row of the table:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="17-19" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">&lt;tbody&gt;<br/>        {table.getRowModel().rows.map((row) =&gt; {<br/>          const isActive = row.original.id === props.selectedCar?.id;<br/>          return (<br/>            &lt;tr<br/>              key={row.id}<br/>              style={isActive === true ? { backgroundColor: &quot;#3a7a11&quot; } : undefined}<br/>              onClick={() =&gt; {<br/>                props.onCarSelected(row.original);<br/>              }}<br/>            &gt;<br/>              {row.getVisibleCells().map((cell) =&gt; (<br/>                &lt;td key={cell.id}&gt;<br/>                  {flexRender(cell.column.columnDef.cell, cell.getContext())}<br/>                &lt;/td&gt;<br/>              ))}<br/>              &lt;td&gt;<br/>                &lt;CarRowContextMenu carRow={row.original} /&gt;<br/>              &lt;/td&gt;<br/>            &lt;/tr&gt;<br/>          );<br/>        })}<br/>&lt;/tbody&gt;</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">CarsTable.tsx &#8211; context menu added as a separate &lt;td&gt;</span> </div> </div></div>



<p class="wp-block-paragraph">Additionally, to make it work, we need an additional table&#8217;s header placeholder:</p>


<div class="wp-block-wab-pastacode">
	<div class="code-embed-wrapper"> <pre class="language-typescript code-embed-pre line-numbers"  data-line="14-15" data-start="1" data-line-offset="0"><code class="language-typescript code-embed-code">&lt;thead&gt;<br/>        {table.getHeaderGroups().map((headerGroup) =&gt; (<br/>          &lt;tr key={headerGroup.id}&gt;<br/>            {headerGroup.headers.map((header) =&gt; (<br/>              &lt;th key={header.id}&gt;<br/>                {header.isPlaceholder<br/>                  ? null<br/>                  : flexRender(<br/>                      header.column.columnDef.header,<br/>                      header.getContext()<br/>                    )}<br/>              &lt;/th&gt;<br/>            ))}<br/>            {/* placeholder header for context menu */}<br/>            &lt;th&gt;&lt;/th&gt;<br/>          &lt;/tr&gt;<br/>        ))}<br/>&lt;/thead&gt;</code></pre> <div class="code-embed-infos"> <span class="code-embed-name">CarsTable.tsx &#8211; placeholder &lt;th&gt; for context menu</span> </div> </div></div>



<p class="wp-block-paragraph">That&#8217;s it! Our `react-table` table with row selection support and the meatballs menu works like a charm now:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1140" height="493" data-attachment-id="4322" data-permalink="https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/5_contextmenufinalversion-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/5_ContextMenuFinalVersion-1.gif?fit=1150%2C497&amp;ssl=1" data-orig-size="1150,497" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="5_ContextMenuFinalVersion-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/5_ContextMenuFinalVersion-1.gif?fit=1150%2C497&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/5_ContextMenuFinalVersion-1.gif?resize=1140%2C493&#038;ssl=1" alt="react-table table with row selection and meatballs menu - final version" class="wp-image-4322" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/5_ContextMenuFinalVersion-1.gif?w=1150&amp;ssl=1 1150w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/02/5_ContextMenuFinalVersion-1.gif?resize=768%2C332&amp;ssl=1 768w" sizes="auto, (max-width: 1140px) 100vw, 1140px" /></figure>
</div>


<h2 class="wp-block-heading">Meatballs menu with react-table &#8211; source code</h2>



<p class="wp-block-paragraph">You can find the complete <a href="https://github.com/dsibinski/react-table-context-menu">source code here</a>. I hope you find it useful! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>


<script>(function() {
	window.mc4wp = window.mc4wp || {
		listeners: [],
		forms: {
			on: function(evt, cb) {
				window.mc4wp.listeners.push(
					{
						event   : evt,
						callback: cb
					}
				);
			}
		}
	}
})();
</script><!-- Mailchimp for WordPress v4.13.0 - https://wordpress.org/plugins/mailchimp-for-wp/ --><form id="mc4wp-form-2" class="mc4wp-form mc4wp-form-2612" method="post" data-id="2612" data-name="Download a free guide form" ><div class="mc4wp-form-fields"><table bgcolor="#f2f6f5"><tr><td> <p><p>
    <label>
<h1 style="">
  <center>GET A FREE GUIDE <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f381.png" alt="🎁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></center>
      </h1>        
      <h2 style="font-family: Helvetica">
        <center>16 STEPS TO BECOME <br/>.NET FULL STACK WEB DEVELOPER </br>IN 2025</center>
      </h2>
</p>
  <center><div>
	<input type="email" name="EMAIL" placeholder="Email address" required />
    <p>
    <input type="text" name="FNAME" placeholder="Your name"
    required="">
  </p>
  </div>
    <center>

	<center><input type="submit" value="DOWNLOAD THE FREE GUIDE" style="color: #7b1fa2; font-weight:bold; font-size: 20px" /></center>
<p style="font-size: 12px; font-style: italic;">After you sign up, I may be sending you some emails with additional free content from time to time.
<br/>No spam, only awesome stuff</p>
</p></td></tr></table>

</div><label style="display: none !important;">Leave this field empty if you're human: <input type="text" name="_mc4wp_honeypot" value="" tabindex="-1" autocomplete="off" /></label><input type="hidden" name="_mc4wp_timestamp" value="1781713174" /><input type="hidden" name="_mc4wp_form_id" value="2612" /><input type="hidden" name="_mc4wp_form_element_id" value="mc4wp-form-2" /><div class="mc4wp-response"></div></form><!-- / Mailchimp for WordPress Plugin -->
<p>The post <a href="https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/">Adding Meatballs Menu To React-Table Rows</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/adding-meatballs-menu-to-react-table-rows/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4302</post-id>	</item>
		<item>
		<title>10 VS Code Extensions I Couldn&#8217;t Live Without</title>
		<link>https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/</link>
					<comments>https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Thu, 19 Jan 2023 18:57:07 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[react]]></category>
		<category><![CDATA[road-to-dotnet-full-stack]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[vscode]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4232</guid>

					<description><![CDATA[<p>I love VS Code 😍 There&#8217;s no better web code editor out there for me. Today, I&#8217;m going to share with you the 10 VS Code extensions that make my life easier. I can&#8217;t imagine coding without them. Let&#8217;s dive into it! Prettier My number one. I was a bit skeptical initially, but today I&#8230;</p>
<p>The post <a href="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/">10 VS Code Extensions I Couldn&#8217;t Live Without</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I love VS Code <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60d.png" alt="😍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> There&#8217;s no better web code editor out there for me. Today, I&#8217;m going to share with you the 10 VS Code extensions that make my life easier. I can&#8217;t imagine coding without them. Let&#8217;s dive into it!</p>



<span id="more-4232"></span>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">Prettier</a></h2>



<p class="wp-block-paragraph">My number one. I was a bit skeptical initially, but today I can&#8217;t imagine my life without Prettier <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> For those unfamiliar with the tool, Prettier is an <em>opinionated</em> code formatted. Opinionated, because it allows for almost no configuration. It reformats your code automatically based on its own rules.</p>



<p class="wp-block-paragraph">It may sound scary and limiting, but it really frees your mind. Suddenly you forget about all those <em>spaces vs tabs wars</em> and discussions on which column shall the code be wrapped. Prettier does that all automatically. It can even be done on saving the file! Just take a look, how beautiful that is:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="917" height="637" data-attachment-id="4236" data-permalink="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/1_vscode_prettier/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/1_VSCode_Prettier.gif?fit=917%2C637&amp;ssl=1" data-orig-size="917,637" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1_VSCode_Prettier" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/1_VSCode_Prettier.gif?fit=917%2C637&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/1_VSCode_Prettier.gif?resize=917%2C637&#038;ssl=1" alt="Gif presenting Prettier auto-formatting on saving the file in VS Code" class="wp-image-4236"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">It is also very easy to <a href="https://prettier.io/docs/en/precommit.html">execute prettier formatting with pre-commit git hook</a>, so the checked-in code is always formatted, even if some team members don&#8217;t use it in their IDE.</p>



<p class="wp-block-paragraph">Never again without Prettier! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets">ES7+ React/Redux/React-Native snippets</a></h2>



<p class="wp-block-paragraph">This is one of the first VS Code extensions I installed. It&#8217;s simple, yet very powerful! This plugin adds multiple JavaScript/React snippets. I create many new components every day. Snippets make it very easy:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="932" height="487" data-attachment-id="4239" data-permalink="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/2_vscode_react_snippets/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/2_VSCode_React_snippets.gif?fit=932%2C487&amp;ssl=1" data-orig-size="932,487" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2_VSCode_React_snippets" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/2_VSCode_React_snippets.gif?fit=932%2C487&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/2_VSCode_React_snippets.gif?resize=932%2C487&#038;ssl=1" alt="One of the VS Code extensions that adds React snipets" class="wp-image-4239"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">I recommend trying this extension out and exploring its built-in snippets.</p>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=adrianwilczynski.csharp-to-typescript">C# to TypeScript</a></h2>



<p class="wp-block-paragraph">This one is a time-saver for .NET developers working with TypeScript. It allows generating TypeScript interfaces from C# classes. You can simply copy a C# <code>class</code> and paste is as a TypeScript&#8217;s <code>interface</code> in Visual Studio Code:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1005" height="431" data-attachment-id="4241" data-permalink="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/3_vscode_csharp_to_typescript-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/3_VSCode_CSharp_to_TypeScript-1.gif?fit=1005%2C431&amp;ssl=1" data-orig-size="1005,431" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3_VSCode_CSharp_to_TypeScript-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/3_VSCode_CSharp_to_TypeScript-1.gif?fit=1005%2C431&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/3_VSCode_CSharp_to_TypeScript-1.gif?resize=1005%2C431&#038;ssl=1" alt="" class="wp-image-4241"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">You can also paste using keyboard shortcuts. There&#8217;s even <a href="https://www.nuget.org/packages/CSharpToTypeScript.CLITool/">a CLI tool</a> available in case you&#8217;d want to automate this process. This extension doesn&#8217;t support all scenarios (especially no support for <code>records</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" />), but it still covers most simple copy-paste cases. By the way, synchronizing C# with TypeScript types is one of the challenges for full stack .NET developers.</p>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=mattpocock.ts-error-translator">Total TypeScript</a></h2>



<p class="wp-block-paragraph">From all VS Code extensions I use, this is the only one that actually helps me learn on the job. It was called <em>TypeScript Error Translator</em> before, and this is what I initially used it for. It basically provides more meaningful, crowdsourced translations for often enigmatic TypeScript errors:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="821" height="280" data-attachment-id="4243" data-permalink="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/4_vscode_errorstranslator/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/4_VSCode_ErrorsTranslator.png?fit=821%2C280&amp;ssl=1" data-orig-size="821,280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="4_VSCode_ErrorsTranslator" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/4_VSCode_ErrorsTranslator.png?fit=821%2C280&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/4_VSCode_ErrorsTranslator.png?resize=821%2C280&#038;ssl=1" alt="TypeScript error translator shows nice explanation of TS error" class="wp-image-4243" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/4_VSCode_ErrorsTranslator.png?w=821&amp;ssl=1 821w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/4_VSCode_ErrorsTranslator.png?resize=300%2C102&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/4_VSCode_ErrorsTranslator.png?resize=768%2C262&amp;ssl=1 768w" sizes="auto, (max-width: 821px) 100vw, 821px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">When a translation is missing, you can always contribute one. Additionally, as its new name suggests, it also lets you learn programming concepts directly inside your code. As soon as it finds a new concept in the code, a brief explanation is shown:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="485" data-attachment-id="4244" data-permalink="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/5_vscode_totaltypescriptlearning/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/5_VSCode_TotalTypescriptLearning.png?fit=2082%2C986&amp;ssl=1" data-orig-size="2082,986" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="5_VSCode_TotalTypescriptLearning" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/5_VSCode_TotalTypescriptLearning.png?fit=1024%2C485&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/5_VSCode_TotalTypescriptLearning.png?resize=1024%2C485&#038;ssl=1" alt="" class="wp-image-4244" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/5_VSCode_TotalTypescriptLearning.png?resize=1024%2C485&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/5_VSCode_TotalTypescriptLearning.png?resize=300%2C142&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/5_VSCode_TotalTypescriptLearning.png?resize=768%2C364&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/5_VSCode_TotalTypescriptLearning.png?resize=1536%2C727&amp;ssl=1 1536w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/5_VSCode_TotalTypescriptLearning.png?resize=2048%2C970&amp;ssl=1 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">It will stop highlighting this particular type of concept as soon as you mark it as learned. I think it&#8217;s a quite interesting way of learning on the job <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint">ESLint</a></h2>



<p class="wp-block-paragraph">This is the extension for integrating the most well-known linter for JavaScript into Visual Studio Code. <a href="https://eslint.org/">ESLint</a> is a static analyzer of your source code which helps you find problems quickly. It will highlight issues in your code for all loaded files from your workspace. I don&#8217;t feel there&#8217;s much to write about here &#8211; just <a href="https://eslint.org/">check their website</a> and give this extension a try <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=rangav.vscode-thunder-client">Thunder Client</a></h2>



<p class="wp-block-paragraph">Thunder Client is like <a href="https://www.postman.com/">Postman</a>, but built into VS Code. It lets you easily play with HTTP APIs. You can create your own collections of requests and export them to JSON, which can be checked into the source control.</p>



<p class="wp-block-paragraph">Yet another very useful extension! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f44d.png" alt="👍" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=zenclabs.previewjs">Preview.js</a></h2>



<p class="wp-block-paragraph">This is one of my recent discoveries. Preview.js allows to live-preview React, Solid or Vue components directly in VS Code. It also generates the initial props data, sometimes even for complex objects:</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1140" height="593" data-attachment-id="4261" data-permalink="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/6_vscode_previewjs-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/6_VSCode_PreviewJS-2.gif?fit=1467%2C763&amp;ssl=1" data-orig-size="1467,763" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="6_VSCode_PreviewJS-2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/6_VSCode_PreviewJS-2.gif?fit=1467%2C763&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/6_VSCode_PreviewJS-2.gif?resize=1140%2C593&#038;ssl=1" alt="" class="wp-image-4261" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/6_VSCode_PreviewJS-2.gif?w=1467&amp;ssl=1 1467w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/6_VSCode_PreviewJS-2.gif?resize=768%2C399&amp;ssl=1 768w" sizes="auto, (max-width: 1140px) 100vw, 1140px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">The plugin is also configurable for custom scenarios like external dependencies. You can find more information <a href="https://previewjs.com/docs/config">in the documentation</a>.</p>


<script>(function() {
	window.mc4wp = window.mc4wp || {
		listeners: [],
		forms: {
			on: function(evt, cb) {
				window.mc4wp.listeners.push(
					{
						event   : evt,
						callback: cb
					}
				);
			}
		}
	}
})();
</script><!-- Mailchimp for WordPress v4.13.0 - https://wordpress.org/plugins/mailchimp-for-wp/ --><form id="mc4wp-form-3" class="mc4wp-form mc4wp-form-2612" method="post" data-id="2612" data-name="Download a free guide form" ><div class="mc4wp-form-fields"><table bgcolor="#f2f6f5"><tr><td> <p><p>
    <label>
<h1 style="">
  <center>GET A FREE GUIDE <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f381.png" alt="🎁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></center>
      </h1>        
      <h2 style="font-family: Helvetica">
        <center>16 STEPS TO BECOME <br/>.NET FULL STACK WEB DEVELOPER </br>IN 2025</center>
      </h2>
</p>
  <center><div>
	<input type="email" name="EMAIL" placeholder="Email address" required />
    <p>
    <input type="text" name="FNAME" placeholder="Your name"
    required="">
  </p>
  </div>
    <center>

	<center><input type="submit" value="DOWNLOAD THE FREE GUIDE" style="color: #7b1fa2; font-weight:bold; font-size: 20px" /></center>
<p style="font-size: 12px; font-style: italic;">After you sign up, I may be sending you some emails with additional free content from time to time.
<br/>No spam, only awesome stuff</p>
</p></td></tr></table>

</div><label style="display: none !important;">Leave this field empty if you're human: <input type="text" name="_mc4wp_honeypot" value="" tabindex="-1" autocomplete="off" /></label><input type="hidden" name="_mc4wp_timestamp" value="1781713174" /><input type="hidden" name="_mc4wp_form_id" value="2612" /><input type="hidden" name="_mc4wp_form_element_id" value="mc4wp-form-3" /><div class="mc4wp-response"></div></form><!-- / Mailchimp for WordPress Plugin -->



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=WakaTime.vscode-wakatime">WakaTime</a></h2>



<p class="wp-block-paragraph">If you like analytics, you should check this VS Code extension. WakaTime measures how much time you spend actually writing code. It shows exactly in which language you programmed for how much time. It also divides time entries into projects you worked on:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1140" height="1018" data-attachment-id="4264" data-permalink="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/7_wakatime_samplestats/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/7_WakaTime_SampleStats.png?fit=2062%2C1842&amp;ssl=1" data-orig-size="2062,1842" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="7_WakaTime_SampleStats" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/7_WakaTime_SampleStats.png?fit=2062%2C1842&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/7_WakaTime_SampleStats.png?resize=1140%2C1018&#038;ssl=1" alt="" class="wp-image-4264" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/7_WakaTime_SampleStats.png?w=2062&amp;ssl=1 2062w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/7_WakaTime_SampleStats.png?resize=768%2C686&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/7_WakaTime_SampleStats.png?resize=1536%2C1372&amp;ssl=1 1536w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/7_WakaTime_SampleStats.png?resize=2048%2C1829&amp;ssl=1 2048w" sizes="auto, (max-width: 1140px) 100vw, 1140px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">It&#8217;s interesting to get such insights &#8220;for free&#8221; and see how little time we spend <em>actually</em> coding <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" />Try it for yourself and let me know your results!</p>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme">One Dark Pro</a></h2>



<p class="wp-block-paragraph">Who never started a new project by installing fancy tools, text editors or choosing the best color theme for your IDE? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f604.png" alt="😄" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Of course &#8211; good colors = smooth -and pleasant &#8211; coding <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /> One Dark Pro is a must-have theme for my Visual Studio Code. I love it, it makes source code much more readable for me. What&#8217;s your favorite color theme for VS Code? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading"><a href="https://marketplace.visualstudio.com/items?itemName=vscode-icons-team.vscode-icons">vscode-icons</a></h2>



<p class="wp-block-paragraph">Last but not least, a good friend to the One Dard Pro theme, legendary VS Code icons set. It has over 13M installs! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92f.png" alt="🤯" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Apart from getting +100 to fanciness <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" />, it makes icons more explicit in the explorer:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="599" height="612" data-attachment-id="4265" data-permalink="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/8_vscodeicons/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/8_VSCodeIcons.png?fit=599%2C612&amp;ssl=1" data-orig-size="599,612" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="8_VSCodeIcons" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/8_VSCodeIcons.png?fit=599%2C612&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/8_VSCodeIcons.png?resize=599%2C612&#038;ssl=1" alt="" class="wp-image-4265" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/8_VSCodeIcons.png?w=599&amp;ssl=1 599w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2023/01/8_VSCodeIcons.png?resize=50%2C50&amp;ssl=1 50w" sizes="auto, (max-width: 599px) 100vw, 599px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">As you can see, it even guesses the folder type based on its name &#8211; see <code>types</code> or <code>utils</code> folders&#8217; icons above.</p>



<p class="wp-block-paragraph">Not critical, yet helpful. Undeniably adds a million to your professionalism as a web developer <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



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



<p class="wp-block-paragraph">So, that&#8217;s it! The list of my 10 favorite Visual Studio Code extensions. </p>



<p class="wp-block-paragraph">What about you? What are your must-have VS Code extensions? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/">10 VS Code Extensions I Couldn&#8217;t Live Without</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/10-vs-code-extensions-i-couldnt-live-without/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4232</post-id>	</item>
		<item>
		<title>How To Fix Visual Studio Code IntelliSense Loading Infinitely</title>
		<link>https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/</link>
					<comments>https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sun, 09 Oct 2022 08:57:31 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[intellisense]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[visual studio code]]></category>
		<category><![CDATA[vscode]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4188</guid>

					<description><![CDATA[<p>Continuing with weird errors you might encounter in JavaScript world, I have another one: Visual Studio Code IntelliSense loading infinitely 😀 Solution included, of course! The symptoms of this issue are putting your mouse on something where you&#8217;d expect the IntelliSense guidelines, but instead you only see the &#8220;Loading&#8230;&#8221; text. In this short article, I&#8217;m&#8230;</p>
<p>The post <a href="https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/">How To Fix Visual Studio Code IntelliSense Loading Infinitely</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Continuing with <a href="https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/">weird errors you might encounter in JavaScript world</a>, I have another one: <strong>Visual Studio Code IntelliSense loading infinitely</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Solution included, of course!</p>



<p class="wp-block-paragraph">The symptoms of this issue are putting your mouse on something where you&#8217;d expect the IntelliSense guidelines, but instead you only see the &#8220;Loading&#8230;&#8221; text.</p>



<p class="wp-block-paragraph">In this short article, I&#8217;m sharing the reason of this issue and my way of fixing it.</p>



<span id="more-4188"></span>



<h2 class="wp-block-heading">How VS Code Infinite IntelliSense Loading Looks Like</h2>



<p class="wp-block-paragraph">This is what I struggled with:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="4195" data-permalink="https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/2_vscodeloadingissue/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/2_VSCodeLoadingIssue.gif?fit=497%2C907&amp;ssl=1" data-orig-size="497,907" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2_VSCodeLoadingIssue" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/2_VSCodeLoadingIssue.gif?fit=497%2C907&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/2_VSCodeLoadingIssue.gif?resize=497%2C907&#038;ssl=1" alt="Visual Studio Code IntelliSense Loading Infinitely - a gif animation" class="wp-image-4195" style="width:497px;height:907px" width="497" height="907"/></figure>
</div>


<p class="wp-block-paragraph">As you can see, I didn&#8217;t get any IntelliSense while hovering my mouse on various elements in the editor.</p>



<p class="wp-block-paragraph">A similar thing happened when I tried to use <code>Go to References</code> (or <code>Shift</code> + <code>F12</code> on Windows) for any object:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="509" height="907" data-attachment-id="4197" data-permalink="https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/3_vscode_find_references_loading/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/3_VSCode_find_references_loading.gif?fit=509%2C907&amp;ssl=1" data-orig-size="509,907" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3_VSCode_find_references_loading" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/3_VSCode_find_references_loading.gif?fit=509%2C907&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/3_VSCode_find_references_loading.gif?resize=509%2C907&#038;ssl=1" alt="Visual Studio Code IntelliSense Loading Infinitely for Go to References - a gif animation" class="wp-image-4197"/></figure>
</div>


<p class="wp-block-paragraph">As you can see, the loading bar at the top of VS Code was showing progress infinitely.</p>



<p class="wp-block-paragraph">Let&#8217;s now see how to fix this annoying issue <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Fixing Visual Studio Code IntelliSense Loading Infinitely</h2>



<p class="wp-block-paragraph">After quite long investigation, I finally found the reason. It turned out that <strong><a href="https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions">sometimes your Visual Studio Code might be using a different TypeScript version than your workspace uses</a></strong>. In my case, it was exactly the cause of the infinite loading problem <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9d0.png" alt="🧐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">In order to fix it, use <code>TypeScript: Select TypeScript Version...</code> command. You can access commands with <code>Ctrl + Shift + P</code> on Windows or <code>⇧⌘P</code> on Mac:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="600" height="262" data-attachment-id="4199" data-permalink="https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/5_selecttypescriptversion/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/5_SelectTypeScriptVersion.png?fit=600%2C262&amp;ssl=1" data-orig-size="600,262" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="5_SelectTypeScriptVersion" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/5_SelectTypeScriptVersion.png?fit=600%2C262&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/5_SelectTypeScriptVersion.png?resize=600%2C262&#038;ssl=1" alt="Visual Studio Code: command palette view, &quot;TypeScript: Select TypeScript Version&quot; command" class="wp-image-4199" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/5_SelectTypeScriptVersion.png?w=600&amp;ssl=1 600w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/5_SelectTypeScriptVersion.png?resize=300%2C131&amp;ssl=1 300w" sizes="auto, (max-width: 600px) 100vw, 600px" /></figure>
</div>


<p class="wp-block-paragraph">Select this command and tell Visual Studio Code to use the workspace version of TypeScript:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="627" height="139" data-attachment-id="4200" data-permalink="https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/6_selecttypescriptversion_useworkspaceversion/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/6_SelectTypeScriptVersion_UseWorkspaceVersion.png?fit=627%2C139&amp;ssl=1" data-orig-size="627,139" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="6_SelectTypeScriptVersion_UseWorkspaceVersion" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/6_SelectTypeScriptVersion_UseWorkspaceVersion.png?fit=627%2C139&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/6_SelectTypeScriptVersion_UseWorkspaceVersion.png?resize=627%2C139&#038;ssl=1" alt="Visual Studio Code: command palette view, &quot;TypeScript: Select TypeScript Version&quot; command, telling VS Code to use workspace version of TypeScript" class="wp-image-4200" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/6_SelectTypeScriptVersion_UseWorkspaceVersion.png?w=627&amp;ssl=1 627w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/10/6_SelectTypeScriptVersion_UseWorkspaceVersion.png?resize=300%2C67&amp;ssl=1 300w" sizes="auto, (max-width: 627px) 100vw, 627px" /></figure>
</div>


<p class="wp-block-paragraph">As you can see on the screenshot above, in my case the VS Code&#8217;s TypeScript version was <code>4.8.2</code>, while the workspace version was <code>4.8.3</code>. Changing it to use the newer, workspace version solved the problem. Visual Studio Code IntelliSense loading infinitely issue was gone <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">If it doesn&#8217;t work straightaway, you might need restarting your VS Code editor.</p>



<p class="wp-block-paragraph">I hope that worked for you and saved you some hours of debugging and exploring StackOverflow <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>


<script>(function() {
	window.mc4wp = window.mc4wp || {
		listeners: [],
		forms: {
			on: function(evt, cb) {
				window.mc4wp.listeners.push(
					{
						event   : evt,
						callback: cb
					}
				);
			}
		}
	}
})();
</script><!-- Mailchimp for WordPress v4.13.0 - https://wordpress.org/plugins/mailchimp-for-wp/ --><form id="mc4wp-form-4" class="mc4wp-form mc4wp-form-2612" method="post" data-id="2612" data-name="Download a free guide form" ><div class="mc4wp-form-fields"><table bgcolor="#f2f6f5"><tr><td> <p><p>
    <label>
<h1 style="">
  <center>GET A FREE GUIDE <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f381.png" alt="🎁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></center>
      </h1>        
      <h2 style="font-family: Helvetica">
        <center>16 STEPS TO BECOME <br/>.NET FULL STACK WEB DEVELOPER </br>IN 2025</center>
      </h2>
</p>
  <center><div>
	<input type="email" name="EMAIL" placeholder="Email address" required />
    <p>
    <input type="text" name="FNAME" placeholder="Your name"
    required="">
  </p>
  </div>
    <center>

	<center><input type="submit" value="DOWNLOAD THE FREE GUIDE" style="color: #7b1fa2; font-weight:bold; font-size: 20px" /></center>
<p style="font-size: 12px; font-style: italic;">After you sign up, I may be sending you some emails with additional free content from time to time.
<br/>No spam, only awesome stuff</p>
</p></td></tr></table>

</div><label style="display: none !important;">Leave this field empty if you're human: <input type="text" name="_mc4wp_honeypot" value="" tabindex="-1" autocomplete="off" /></label><input type="hidden" name="_mc4wp_timestamp" value="1781713174" /><input type="hidden" name="_mc4wp_form_id" value="2612" /><input type="hidden" name="_mc4wp_form_element_id" value="mc4wp-form-4" /><div class="mc4wp-response"></div></form><!-- / Mailchimp for WordPress Plugin -->
<p>The post <a href="https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/">How To Fix Visual Studio Code IntelliSense Loading Infinitely</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/how-to-fix-visual-studio-code-intellisense-loading-infinitely/feed/</wfw:commentRss>
			<slash:comments>20</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4188</post-id>	</item>
		<item>
		<title>Typing API Responses With Zod</title>
		<link>https://www.codejourney.net/typing-api-responses-with-zod/</link>
					<comments>https://www.codejourney.net/typing-api-responses-with-zod/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Mon, 11 Jul 2022 07:00:00 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[zod]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4093</guid>

					<description><![CDATA[<p>Have you ever needed to synchronize types in your frontend app with the backend API? If you ever had an API action defined like that in your controller: and fetched this data using TypeScript in the following way: at some point, you probably also experienced the desynchronization of backend (C#, in our example) and frontend&#8230;</p>
<p>The post <a href="https://www.codejourney.net/typing-api-responses-with-zod/">Typing API Responses With Zod</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Have you ever needed to synchronize types in your frontend app with the backend API?</p>



<p class="wp-block-paragraph">If you ever had an API action defined like that in your controller:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117275988" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-aspnetcontrollersample-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="AspNetControllerSample.cs content, created by dsibinski on 02:22PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="AspNetControllerSample.cs">
        <tr>
          <td id="file-aspnetcontrollersample-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-aspnetcontrollersample-cs-LC1" class="blob-code blob-code-inner js-file-line">public record UserViewModel(Guid Id, string Name, string LastName, string Login, </td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-aspnetcontrollersample-cs-LC2" class="blob-code blob-code-inner js-file-line">    bool IsActive, int LoyaltyPoints, AddressViewModel? Address = null);</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-aspnetcontrollersample-cs-LC3" class="blob-code blob-code-inner js-file-line">    </td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-aspnetcontrollersample-cs-LC4" class="blob-code blob-code-inner js-file-line">// &#8230;</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-aspnetcontrollersample-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-aspnetcontrollersample-cs-LC6" class="blob-code blob-code-inner js-file-line">public List&lt;UserViewModel&gt; AllUsers()</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-aspnetcontrollersample-cs-LC7" class="blob-code blob-code-inner js-file-line">{</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-aspnetcontrollersample-cs-LC8" class="blob-code blob-code-inner js-file-line">    var usersViewModels = TestDataGenerator.GetTestUsers();</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-aspnetcontrollersample-cs-LC9" class="blob-code blob-code-inner js-file-line">    return usersViewModels.OrderBy(uvm =&gt; uvm.Name).ToList();</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-aspnetcontrollersample-cs-LC10" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/bf658760106de7269ebf3d0f351c0411/raw/2336445c10cd9b76b7a5b9af3a747eeaddfb75c4/AspNetControllerSample.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/bf658760106de7269ebf3d0f351c0411#file-aspnetcontrollersample-cs" class="Link--inTextBlock">
          AspNetControllerSample.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">and fetched this data using TypeScript in the following way:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276011" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-apifetchsample-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="ApiFetchSample.ts content, created by dsibinski on 02:23PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="ApiFetchSample.ts">
        <tr>
          <td id="file-apifetchsample-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-apifetchsample-ts-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-en>getAllUsers</span> <span class=pl-c1>=</span> <span class=pl-k>async</span> <span class=pl-kos>(</span><span class=pl-kos>)</span>: <span class=pl-smi>Promise</span><span class=pl-c1>&lt;</span><span class=pl-smi>UserViewModel</span><span class=pl-kos>[</span><span class=pl-kos>]</span><span class=pl-c1>&gt;</span> <span class=pl-c1>=&gt;</span> <span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-apifetchsample-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-apifetchsample-ts-LC2" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>const</span> <span class=pl-s1>url</span> <span class=pl-c1>=</span> <span class=pl-s>`<span class=pl-s1><span class=pl-kos>${</span><span class=pl-smi>this</span><span class=pl-kos>.</span><span class=pl-c1>apiEndpoint</span><span class=pl-kos>}</span></span>/AllUsers`</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-apifetchsample-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-apifetchsample-ts-LC3" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>const</span> <span class=pl-s1>response</span> <span class=pl-c1>=</span> <span class=pl-k>await</span> <span class=pl-en>fetch</span><span class=pl-kos>(</span><span class=pl-s1>url</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-apifetchsample-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-apifetchsample-ts-LC4" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>const</span> <span class=pl-s1>users</span> <span class=pl-c1>=</span> <span class=pl-kos>(</span><span class=pl-k>await</span> <span class=pl-s1>response</span><span class=pl-kos>.</span><span class=pl-en>json</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>)</span> <span class=pl-k>as</span> <span class=pl-smi>UserViewModel</span><span class=pl-kos>[</span><span class=pl-kos>]</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-apifetchsample-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-apifetchsample-ts-LC5" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>return</span> <span class=pl-s1>users</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-apifetchsample-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-apifetchsample-ts-LC6" class="blob-code blob-code-inner js-file-line">  <span class=pl-kos>}</span><span class=pl-kos>;</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/44438baa3b6ece08a191b0e918c01a77/raw/5eb52ec2972eae06d298fd6fecca1aadb568ac13/ApiFetchSample.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/44438baa3b6ece08a191b0e918c01a77#file-apifetchsample-ts" class="Link--inTextBlock">
          ApiFetchSample.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">at some point, you probably also experienced the desynchronization of backend (C#, in our example) and frontend (TypeScript) types definitions. What if someone has changed the C# version of <code>UserViewModel</code>, but no one corrected its TypeScript&#8217;s equivalent? </p>



<p class="wp-block-paragraph">Your TypeScript fetching code will tell nothing about that. <strong>There will be no error, even though the fetched data doesn&#8217;t match the expected <code>UserViewModel</code> type</strong>.</p>



<p class="wp-block-paragraph">I&#8217;ll try to address this issue in this article <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Let&#8217;s see how typing API responses with <code>zod</code> can help us here.</p>



<span id="more-4093"></span>



<h2 class="wp-block-heading">Synchronization of Backend and Frontend API Typings</h2>



<p class="wp-block-paragraph">First, why would we want to keep the backend and frontend models in sync?</p>



<p class="wp-block-paragraph">For me, that&#8217;s the purpose of using TypeScript. <strong>We want our code to be as well-typed as possible</strong>. For instance, we normally want the data displayed to the user to be fully typed. TypeScript enhances our programming experience by providing us with typing information. Thanks to that, we know <em>what is what</em> and <em>what contains</em> <em>what</em>. We also express what types of data we expect in particular cases.</p>



<p class="wp-block-paragraph">The APIs mostly return JSON data, which can be anything. Because of that, it is much easier to have the data returned from the API fully typed in TypeScript. Thanks to that, <strong>we know what properties are available on the data models received from the API and whether we can use and display them to the users</strong>.</p>



<p class="wp-block-paragraph">The sample code used within this article is available <a href="https://github.com/dsibinski/DotNetReactZodApp">on GitHub</a>. We will use ASP.NET Core (C#) and React (TypeScript) apps as examples.</p>



<h3 class="wp-block-heading">Models synchronization example</h3>



<p class="wp-block-paragraph">As we saw in the beginning, a classic example is an API controller that returns a strongly-typed data:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276293" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-aspnetcontrolleraction-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="AspNetControllerAction.cs content, created by dsibinski on 02:57PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="AspNetControllerAction.cs">
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-aspnetcontrolleraction-cs-LC1" class="blob-code blob-code-inner js-file-line">public List&lt;UserViewModel&gt; AllUsers()</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-aspnetcontrolleraction-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-aspnetcontrolleraction-cs-LC3" class="blob-code blob-code-inner js-file-line">    var usersViewModels = TestDataGenerator.GetTestUsers();</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-aspnetcontrolleraction-cs-LC4" class="blob-code blob-code-inner js-file-line">    return usersViewModels.OrderBy(uvm =&gt; uvm.Name).ToList();</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-aspnetcontrolleraction-cs-LC5" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/237ce046ebdfcae6b4b7485f8c8c2006/raw/f71478548ff7ccf10fe92893a8c1aedf3ead32e3/AspNetControllerAction.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/237ce046ebdfcae6b4b7485f8c8c2006#file-aspnetcontrolleraction-cs" class="Link--inTextBlock">
          AspNetControllerAction.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">The returned data type is a collection of <code>UserViewModel</code> objects. Here&#8217;s the C# definition of this type:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276303" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="UserViewModel.cs content, created by dsibinski on 02:58PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="UserViewModel.cs">
        <tr>
          <td id="file-userviewmodel-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel-cs-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-k>public</span> <span class=pl-k>record</span> <span class=pl-smi>UserViewModel</span><span class=pl-kos>(</span><span class=pl-smi>Guid</span> <span class=pl-s1>Id</span><span class=pl-kos>,</span> <span class=pl-smi>string</span> <span class=pl-s1>Name</span><span class=pl-kos>,</span> <span class=pl-smi>string</span> <span class=pl-s1>LastName</span><span class=pl-kos>,</span> </td>
        </tr>
        <tr>
          <td id="file-userviewmodel-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel-cs-LC2" class="blob-code blob-code-inner js-file-line">    <span class=pl-smi>string</span> <span class=pl-s1>Login</span><span class=pl-kos>,</span> <span class=pl-smi>bool</span> <span class=pl-s1>IsActive</span><span class=pl-kos>,</span> <span class=pl-smi>int</span> <span class=pl-s1>LoyaltyPoints</span><span class=pl-kos>,</span> <span class=pl-smi>AddressViewModel</span><span class=pl-c1>?</span> <span class=pl-s1>Address</span> <span class=pl-c1>=</span> <span class=pl-c1>null</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/a6921cad261fb274900c991956a18f5a/raw/646dc5ed47ba33b0d663d20716697c1da6933fd3/UserViewModel.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/a6921cad261fb274900c991956a18f5a#file-userviewmodel-cs" class="Link--inTextBlock">
          UserViewModel.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Its equivalent is also defined on TypeScript side:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276311" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="userViewModel.ts content, created by dsibinski on 02:59PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="userViewModel.ts">
        <tr>
          <td id="file-userviewmodel-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel-ts-LC1" class="blob-code blob-code-inner js-file-line">export interface UserViewModel {</td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel-ts-LC2" class="blob-code blob-code-inner js-file-line">  id: Guid;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-userviewmodel-ts-LC3" class="blob-code blob-code-inner js-file-line">  name: string;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-userviewmodel-ts-LC4" class="blob-code blob-code-inner js-file-line">  lastName: string;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-userviewmodel-ts-LC5" class="blob-code blob-code-inner js-file-line">  login: string;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-userviewmodel-ts-LC6" class="blob-code blob-code-inner js-file-line">  isActive: boolean;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-userviewmodel-ts-LC7" class="blob-code blob-code-inner js-file-line">  loyaltyPoints: number;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-userviewmodel-ts-LC8" class="blob-code blob-code-inner js-file-line">  address: AddressViewModel | null;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-userviewmodel-ts-LC9" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/d03ea25ba0be55e645a0b6fe35595f47/raw/5d93472032cf0339bc34e88bb76c6be66f17241c/userViewModel.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/d03ea25ba0be55e645a0b6fe35595f47#file-userviewmodel-ts" class="Link--inTextBlock">
          userViewModel.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<h3 class="wp-block-heading">Usage in TypeScript</h3>



<p class="wp-block-paragraph">Cool. With this simple code, we can create a <code>usersService.ts</code> file and fetch our users&#8217; data from the API. Notice how we make this call strongly typed:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276316" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-usersservice-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="usersService.ts content, created by dsibinski on 03:00PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="usersService.ts">
        <tr>
          <td id="file-usersservice-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-usersservice-ts-LC1" class="blob-code blob-code-inner js-file-line">export class UsersService {</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-usersservice-ts-LC2" class="blob-code blob-code-inner js-file-line">  private apiEndpoint: string;</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-usersservice-ts-LC3" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-usersservice-ts-LC4" class="blob-code blob-code-inner js-file-line">  constructor() {</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-usersservice-ts-LC5" class="blob-code blob-code-inner js-file-line">    this.apiEndpoint = &quot;https://localhost:7131/Users&quot;;</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-usersservice-ts-LC6" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-usersservice-ts-LC7" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-usersservice-ts-LC8" class="blob-code blob-code-inner js-file-line">  getAllUsers = async (): Promise&lt;UserViewModel[]&gt; =&gt; {</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-usersservice-ts-LC9" class="blob-code blob-code-inner js-file-line">    const url = `${this.apiEndpoint}/AllUsers`;</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-usersservice-ts-LC10" class="blob-code blob-code-inner js-file-line">    const response = await fetch(url);</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-usersservice-ts-LC11" class="blob-code blob-code-inner js-file-line">    const users = (await response.json()) as UserViewModel[];</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-usersservice-ts-LC12" class="blob-code blob-code-inner js-file-line">    return users;</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-usersservice-ts-LC13" class="blob-code blob-code-inner js-file-line">  };</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-usersservice-ts-LC14" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/b49678cb4bb3d9ed23b9e59ecd58b595/raw/7cd1a292499e4610a6f85f20678496f1592192b8/usersService.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/b49678cb4bb3d9ed23b9e59ecd58b595#file-usersservice-ts" class="Link--inTextBlock">
          usersService.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Everything looks legit. We can use the data retrieved from the API in <code>UsersList</code> component and everything is nicely typed:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="736" height="403" data-attachment-id="4108" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/1_userslisttyped/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?fit=736%2C403&amp;ssl=1" data-orig-size="736,403" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1_UsersListTyped" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?fit=736%2C403&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?resize=736%2C403&#038;ssl=1" alt="UsersList React component" class="wp-image-4108" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?w=736&amp;ssl=1 736w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?resize=300%2C164&amp;ssl=1 300w" sizes="auto, (max-width: 736px) 100vw, 736px" /></figure>
</div>


<p class="wp-block-paragraph">The data is even perfectly displayed:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="950" height="381" data-attachment-id="4109" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/2_usersdatadispayed/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?fit=950%2C381&amp;ssl=1" data-orig-size="950,381" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2_UsersDataDispayed" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?fit=950%2C381&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?resize=950%2C381&#038;ssl=1" alt="Table with users rendered on the web page" class="wp-image-4109" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?w=950&amp;ssl=1 950w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?resize=300%2C120&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?resize=768%2C308&amp;ssl=1 768w" sizes="auto, (max-width: 950px) 100vw, 950px" /></figure>
</div>


<p class="wp-block-paragraph">So, what can go wrong here? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">The Problem &#8211; Typings&#8217; Desynchronization</h2>



<p class="wp-block-paragraph">Let&#8217;s say that a backend developer implements a requirement to rename &#8220;loyalty points&#8221; into &#8220;fidelity points&#8221;. Easy. (S)he renames <code>LoyaltyPoints</code> property in the C#&#8217;s <code>UserViewModel</code> to <code>FidelityPoints</code>.</p>



<p class="wp-block-paragraph">The new C# model looks as follows:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276412" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel_renamed-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="UserViewModel_renamed.cs content, created by dsibinski on 03:12PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="UserViewModel_renamed.cs">
        <tr>
          <td id="file-userviewmodel_renamed-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel_renamed-cs-LC1" class="blob-code blob-code-inner js-file-line">public record UserViewModel(Guid Id, string Name, string LastName, </td>
        </tr>
        <tr>
          <td id="file-userviewmodel_renamed-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel_renamed-cs-LC2" class="blob-code blob-code-inner js-file-line">    string Login, bool IsActive, int FidelityPoints, AddressViewModel? Address = null);</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/7e0f39f3c7ffb2010000bb0ea1629701/raw/f40ac01938a57e487280fe35c4f07400d63b7cd9/UserViewModel_renamed.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/7e0f39f3c7ffb2010000bb0ea1629701#file-userviewmodel_renamed-cs" class="Link--inTextBlock">
          UserViewModel_renamed.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Nice! The backend dev is a very good programmer, so (s)he even launches the React web application to make sure that everything still works correctly and there are no errors in the dev console:</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="972" height="405" data-attachment-id="4111" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/3_userddatawithoutloyaltypointsdisplayed/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?fit=972%2C405&amp;ssl=1" data-orig-size="972,405" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3_UserdDataWithoutLoyaltyPointsDisplayed" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?fit=972%2C405&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?resize=972%2C405&#038;ssl=1" alt="Table of users rendered on the web page with empty &quot;Loyalty points&quot; column and no errors on Chrome DevTools console" class="wp-image-4111" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?w=972&amp;ssl=1 972w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?resize=300%2C125&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?resize=768%2C320&amp;ssl=1 768w" sizes="auto, (max-width: 972px) 100vw, 972px" /></figure>



<p class="wp-block-paragraph">After a quick look, everything looks awesome. The users list is displayed, there are no errors in the console. Apparently, these test users don&#8217;t have any loyalty points assigned &#8211; that&#8217;s why the empty values in &#8220;Loyalty points&#8221; column. What&#8217;s more, translators will update the column&#8217;s translation later. We are good! Let&#8217;s go on prod! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">I guess you already know what went wrong here. <strong>API definition changed, but TypeScript didn&#8217;t inform us about that</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f614.png" alt="😔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Our <code>UserViewModel</code> still uses the old property name:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="508" height="290" data-attachment-id="4115" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/4_tsoutdateduserviewmodel/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?fit=508%2C290&amp;ssl=1" data-orig-size="508,290" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="4_TSOutdatedUserViewModel" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?fit=508%2C290&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?resize=508%2C290&#038;ssl=1" alt="UserViewModel typescript type definition" class="wp-image-4115" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?w=508&amp;ssl=1 508w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?resize=300%2C171&amp;ssl=1 300w" sizes="auto, (max-width: 508px) 100vw, 508px" /></figure>
</div>


<p class="wp-block-paragraph">However, it still works. When rendering the <code>UsersList</code>, we simply get <code>undefined</code> in place of <code>loyaltyPoints</code>:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="661" height="313" data-attachment-id="4116" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/5_tsoldpropertyundefined/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?fit=661%2C313&amp;ssl=1" data-orig-size="661,313" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="5_TSOldPropertyUndefined" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?fit=661%2C313&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?resize=661%2C313&#038;ssl=1" alt="UsersList rendering at runtime. user.loyaltyPoints property is always undefined" class="wp-image-4116" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?w=661&amp;ssl=1 661w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?resize=300%2C142&amp;ssl=1 300w" sizes="auto, (max-width: 661px) 100vw, 661px" /></figure>
</div>


<p class="wp-block-paragraph">In the end, <em>this is <a href="https://www.codejourney.net/2018/11/10-most-shocking-javascript-features-for-csharp-developers/">all JavaScript there</a></em>. What&#8217;s interesting, the renamed <code>fidelityPoints</code> property is already there at runtime:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="441" height="239" data-attachment-id="4117" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/6_newpropertypresentatjsruntime/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?fit=441%2C239&amp;ssl=1" data-orig-size="441,239" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="6_NewPropertyPresentAtJsRuntime" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?fit=441%2C239&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?resize=441%2C239&#038;ssl=1" alt="At runtime we can see the new fidelityPoints property already present" class="wp-image-4117" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?w=441&amp;ssl=1 441w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?resize=300%2C163&amp;ssl=1 300w" sizes="auto, (max-width: 441px) 100vw, 441px" /></figure>
</div>


<p class="wp-block-paragraph">but no one cared about it <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f614.png" alt="😔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph"><strong>With the current solution, we will never be informed soon enough about API models changes in our React application</strong>. In the best case, we&#8217;ll get an <code>undefiend</code> or <code>null</code> error when clicking through the app. However, it&#8217;s usually an end user who finds such problems on production. This is definitely not what we want <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f636.png" alt="😶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">We can solve this problem by typing API responses with <a href="https://github.com/colinhacks/zod">zod</a>. Let&#8217;s now see how to do that.</p>



<h2 class="wp-block-heading">The Solution &#8211; zod</h2>



<p class="wp-block-paragraph">Our remedy &#8211; <a href="https://github.com/colinhacks/zod"><code>zod</code></a> &#8211; is quite a <a href="https://www.npmjs.com/package/zod">decent npm package</a> with with ~600k weekly downloads. Its GitHub page advertises the library as <em>TypeScript-first schema validation with static type inference</em>.</p>



<p class="wp-block-paragraph">You can definitely do many things with <code>zod</code>. It can be used together with libraries like <a href="https://react-hook-form.com/">react-hook-form</a> to perform complex forms validation. However, in our case, <strong>we&#8217;ll treat <code>zod</code> as a solution for better typings in TypeScript</strong>.</p>



<h3 class="wp-block-heading">Adding zod to React app</h3>



<p class="wp-block-paragraph">First, let&#8217;s install <code>zod</code> into our React application:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
npm i zod
</pre></div>


<h3 class="wp-block-heading">First schema definition with zod</h3>



<p class="wp-block-paragraph">With <code>zod</code>, we define our types in a slightly different way. Instead of creating a <code>type</code> or <code>interface</code> directly, we first create a <em>schema</em>. In our case, we can define a <code>UserViewModelSchema</code> using <code>z.object</code> creator function:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276653" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel_zodschema-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="UserViewModel_ZodSchema.ts content, created by dsibinski on 03:39PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="UserViewModel_ZodSchema.ts">
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel_zodschema-ts-LC1" class="blob-code blob-code-inner js-file-line">export const UserViewModelSchema = z.object({</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel_zodschema-ts-LC2" class="blob-code blob-code-inner js-file-line">  id: z.string().uuid(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-userviewmodel_zodschema-ts-LC3" class="blob-code blob-code-inner js-file-line">  name: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-userviewmodel_zodschema-ts-LC4" class="blob-code blob-code-inner js-file-line">  lastName: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-userviewmodel_zodschema-ts-LC5" class="blob-code blob-code-inner js-file-line">  login: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-userviewmodel_zodschema-ts-LC6" class="blob-code blob-code-inner js-file-line">  isActive: z.boolean(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-userviewmodel_zodschema-ts-LC7" class="blob-code blob-code-inner js-file-line">  loyaltyPoints: z.number(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-userviewmodel_zodschema-ts-LC8" class="blob-code blob-code-inner js-file-line">  address: AddressViewModelSchema.nullable(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-userviewmodel_zodschema-ts-LC9" class="blob-code blob-code-inner js-file-line">});</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/9c7759dff996babccf1b14da276d76c8/raw/959d8bf640a1f20dc10b7975c7a8fa40e62392d5/UserViewModel_ZodSchema.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/9c7759dff996babccf1b14da276d76c8#file-userviewmodel_zodschema-ts" class="Link--inTextBlock">
          UserViewModel_ZodSchema.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Few interesting parts here:</p>



<ul class="wp-block-list"><li><em>Line 2</em>: notice how <code>zod</code> helps us to define types like <code>Guid</code> with built-in schemas like <code>uuid()</code></li><li><em>Line 8</em>: first, I used <code>AddressViewModelSchema</code> here. This is a custom schema of an <code>AddressViewModel</code> object, which is another type used internally in <code>UserViewModel</code>. You can use such custom schemas in other schemas. Also notice the <code>nullable()</code> call here, which makes the <code>address</code> property nullable</li></ul>



<p class="wp-block-paragraph">First step done &#8211; we have our <code>UserViewModelSchema</code>. But can we use it instead of <code>UserViewModel</code> type? Not really. Schema is used for validation purposes only. We still need the <code>UserViewModel</code> TypeScript&#8217;s type. </p>



<h3 class="wp-block-heading">Inferring type from zod&#8217;s schema</h3>



<p class="wp-block-paragraph">Fortunately, <code>zod</code> comes with a handy <code>z.infer</code> function that allows us to <em>infer</em> the type from the schema.</p>



<p class="wp-block-paragraph">Finally, the <code>userViewModel.ts</code> file looks as follows:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276693" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel_zod-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="userViewModel_zod.ts content, created by dsibinski on 03:43PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="userViewModel_zod.ts">
        <tr>
          <td id="file-userviewmodel_zod-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel_zod-ts-LC1" class="blob-code blob-code-inner js-file-line">import { z } from &quot;zod&quot;;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel_zod-ts-LC2" class="blob-code blob-code-inner js-file-line">import { AddressViewModelSchema } from &quot;./addressViewModel&quot;;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-userviewmodel_zod-ts-LC3" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-userviewmodel_zod-ts-LC4" class="blob-code blob-code-inner js-file-line">export const UserViewModelSchema = z.object({</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-userviewmodel_zod-ts-LC5" class="blob-code blob-code-inner js-file-line">  id: z.string().uuid(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-userviewmodel_zod-ts-LC6" class="blob-code blob-code-inner js-file-line">  name: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-userviewmodel_zod-ts-LC7" class="blob-code blob-code-inner js-file-line">  lastName: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-userviewmodel_zod-ts-LC8" class="blob-code blob-code-inner js-file-line">  login: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-userviewmodel_zod-ts-LC9" class="blob-code blob-code-inner js-file-line">  isActive: z.boolean(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-userviewmodel_zod-ts-LC10" class="blob-code blob-code-inner js-file-line">  loyaltyPoints: z.number(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-userviewmodel_zod-ts-LC11" class="blob-code blob-code-inner js-file-line">  address: AddressViewModelSchema.nullable(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-userviewmodel_zod-ts-LC12" class="blob-code blob-code-inner js-file-line">});</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-userviewmodel_zod-ts-LC13" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-userviewmodel_zod-ts-LC14" class="blob-code blob-code-inner js-file-line">export type UserViewModel = z.infer&lt;typeof UserViewModelSchema&gt;;</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/64cb91fade703c4bbf6ade4c6ad84d19/raw/d45af9863a80557b643b3b04c3440287c20a923b/userViewModel_zod.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/64cb91fade703c4bbf6ade4c6ad84d19#file-userviewmodel_zod-ts" class="Link--inTextBlock">
          userViewModel_zod.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">We can use the exported <code>UserViewModel</code> type as previously used type. It&#8217;s an equivalent, inferred from <code>UserViewModelSchema</code>.</p>



<h3 class="wp-block-heading">Validating API responses with zod schema</h3>



<p class="wp-block-paragraph">One last step is to make use of <code>UserViewModelSchema</code>. Let&#8217;s modify the <code>getAllUsers</code> function from <code>usersService</code> to validate the data received from the API against our schema:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276973" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-getallusers_with_zod-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="getAllUsers_with_zod.ts content, created by dsibinski on 04:13PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="getAllUsers_with_zod.ts">
        <tr>
          <td id="file-getallusers_with_zod-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-getallusers_with_zod-ts-LC1" class="blob-code blob-code-inner js-file-line">getAllUsers = async (): Promise&lt;UserViewModel[]&gt; =&gt; {</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-getallusers_with_zod-ts-LC2" class="blob-code blob-code-inner js-file-line">  const url = `${this.apiEndpoint}/AllUsers`;</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-getallusers_with_zod-ts-LC3" class="blob-code blob-code-inner js-file-line">  const response = await fetch(url);</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-getallusers_with_zod-ts-LC4" class="blob-code blob-code-inner js-file-line">  const usersJson = await response.json();</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-getallusers_with_zod-ts-LC5" class="blob-code blob-code-inner js-file-line">  const users = z.array(UserViewModelSchema).parse(usersJson);</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-getallusers_with_zod-ts-LC6" class="blob-code blob-code-inner js-file-line">  return users;</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-getallusers_with_zod-ts-LC7" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/ac10bdf2e256f549939d6eeed68067aa/raw/d996f3ee73f81ada41ee15ac3fadf14064992acc/getAllUsers_with_zod.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/ac10bdf2e256f549939d6eeed68067aa#file-getallusers_with_zod-ts" class="Link--inTextBlock">
          getAllUsers_with_zod.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Notice the usage of <code>z.array</code>. This function call tells <code>zod</code> to validate an array of objects meeting the rules defined by <code>UserViewModelSchema</code>, not a single object.</p>



<p class="wp-block-paragraph">Now, let&#8217;s run our React app and see what happens when we click the &#8220;Fetch users&#8221; button:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="651" height="592" data-attachment-id="4121" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/7_zodschemavalidationerror/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?fit=651%2C592&amp;ssl=1" data-orig-size="651,592" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="7_ZodSchemaValidationError" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?fit=651%2C592&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?resize=651%2C592&#038;ssl=1" alt="zod throws schema validation error on Chrome dev tools console" class="wp-image-4121" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?w=651&amp;ssl=1 651w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?resize=300%2C273&amp;ssl=1 300w" sizes="auto, (max-width: 651px) 100vw, 651px" /></figure>
</div>


<p class="wp-block-paragraph">This is awesome! Exactly what we wanted &#8211; a <strong>schema validation error for API response</strong>. Notice how the <strong>error message precisely points to the missing (or wrong, in other cases) property.</strong> It tells us we expected a <code>number</code> called <code>loyaltyPoints</code>, but instead we received <code>undefined</code>. The reason for this error message is that the <code>loyaltyPoints</code> field is <code>Required</code> in our schema.</p>



<p class="wp-block-paragraph">After renaming <code>loyaltyPoints</code> to <code>fidelityPoints</code> in <code>UserViewModelSchema</code> and updating the <code>UsersList</code> component accordingly, everything works fine again. </p>



<p class="wp-block-paragraph">We are now fully typed and prepared for the future, in case an issue with desynchronization of frontend and backend typings happens again <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



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



<p class="wp-block-paragraph">Today, we&#8217;ve seen how typing API responses with <code>zod</code> can help us detect frontend and backend models desynchronization. Schema validation throws errors when the data doesn&#8217;t match its expected shape. </p>



<p class="wp-block-paragraph">Remember that <code>zod</code> is an extended library with many options. I recommend <a href="https://github.com/colinhacks/zod">exploring them</a> on your own. An interesting feature we didn&#8217;t cover in this article is <a href="https://github.com/colinhacks/zod#strict">strict mode</a>, which doesn&#8217;t allow additional fields not present in the schema definition when validating the data object. </p>



<p class="wp-block-paragraph">The open question remains whether to use schema validation on production. One could think that it&#8217;s better to not throw any validation errors, because <em>JavaScript may just work</em>. However, I think that throwing an error is always better than <em>silently</em> letting things through. An error lets programmers, automated tests or manual testers to detect the issue before the end user does <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">You can explore the complete code presented in this article <a href="https://github.com/dsibinski/DotNetReactZodApp">here</a>.</p>
<p>The post <a href="https://www.codejourney.net/typing-api-responses-with-zod/">Typing API Responses With Zod</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/typing-api-responses-with-zod/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4093</post-id>	</item>
		<item>
		<title>Write Test Progress To The Console With NUnit</title>
		<link>https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/</link>
					<comments>https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sun, 19 Jun 2022 13:07:28 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[nunit]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[unit tests]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4070</guid>

					<description><![CDATA[<p>I recently needed to write test progress to the console with NUnit. The task we want to solve here is basically the TODO part of this snippet: The title picture of this article shows the end result. If you want to know the solution, keep reading 🙂 Context The context of this need is very&#8230;</p>
<p>The post <a href="https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/">Write Test Progress To The Console With NUnit</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I recently needed to write test progress to the console with NUnit. The task we want to solve here is basically the <em>TODO</em> part of this snippet:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist116902181" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-nunit_test_progress_todo-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="NUnit_test_progress_todo.cs content, created by dsibinski on 04:54AM on June 19, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="NUnit_test_progress_todo.cs">
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-nunit_test_progress_todo-cs-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>[</span><span class=pl-c1>TestFixture</span><span class=pl-kos>]</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-nunit_test_progress_todo-cs-LC2" class="blob-code blob-code-inner js-file-line"><span class=pl-k>public</span> <span class=pl-k>class</span> <span class=pl-smi>MyTests</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-nunit_test_progress_todo-cs-LC3" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-nunit_test_progress_todo-cs-LC4" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>[</span><span class=pl-c1>Test</span><span class=pl-kos>]</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-nunit_test_progress_todo-cs-LC5" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>public</span> <span class=pl-smi>void</span> <span class=pl-en>SampleTest</span><span class=pl-kos>(</span><span class=pl-kos>)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-nunit_test_progress_todo-cs-LC6" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-nunit_test_progress_todo-cs-LC7" class="blob-code blob-code-inner js-file-line">        <span class=pl-c>// some operations here, like starting a server for tests in-memory&#8230;</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-nunit_test_progress_todo-cs-LC8" class="blob-code blob-code-inner js-file-line">        </td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-nunit_test_progress_todo-cs-LC9" class="blob-code blob-code-inner js-file-line">        <span class=pl-c>// TODO: inform the &#39;user&#39; (the one who runs the test) that the server is already running</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-nunit_test_progress_todo-cs-LC10" class="blob-code blob-code-inner js-file-line">        <span class=pl-k>while</span> <span class=pl-kos>(</span><span class=pl-c1>true</span><span class=pl-kos>)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-nunit_test_progress_todo-cs-LC11" class="blob-code blob-code-inner js-file-line">        <span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-nunit_test_progress_todo-cs-LC12" class="blob-code blob-code-inner js-file-line">            <span class=pl-c>// keep it running on purpose (e.g. for E2E tests)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-nunit_test_progress_todo-cs-LC13" class="blob-code blob-code-inner js-file-line">        <span class=pl-kos>}</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-nunit_test_progress_todo-cs-LC14" class="blob-code blob-code-inner js-file-line">        </td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-nunit_test_progress_todo-cs-LC15" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>}</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-nunit_test_progress_todo-cs-LC16" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>}</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/419247cf91eaa4bd67f820a9af5e0dd9/raw/1f387ac42e1bf490b1531fc7808de21fe2fe6aff/NUnit_test_progress_todo.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/419247cf91eaa4bd67f820a9af5e0dd9#file-nunit_test_progress_todo-cs" class="Link--inTextBlock">
          NUnit_test_progress_todo.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">The title picture of this article shows the end result. If you want to know the solution, keep reading <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4070"></span>



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



<p class="wp-block-paragraph">The context of this need is very simple. I have a unit test in which I want to perform some operations and keep the test running indefinitely afterwards. The use case might be instantiation of an <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.testhost.testserver?view=aspnetcore-6.0">in-memory test server</a>. After that, I want to inform the user (programmer or the one running the test) that the server is up and running. I want to do that <strong>before the test finishes</strong>. In other words: <strong>I want to write the test&#8217;s output while it&#8217;s still running</strong>. </p>



<p class="wp-block-paragraph">In my case, I was running two .NET Core apps in-memory. The backend server app and the ASP.NET Core web application. In the process, the web app got its IP address assigned dynamically. Meaning that the IP was different with each test run. This particular test was used to run the app in-memory and let the user manually use the application. It means the user must know the IP/URL of the in-memory web app. That&#8217;s why I needed to output the dynamic IP address into the NUnit test output <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



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



<p class="wp-block-paragraph">The solution to write test progress to the console with NUnit is very simple. To do that, use <code>TestContext.Progress.WriteLine(string)</code> method from <code>NUnit.Framework</code> namespace:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist116902272" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-nunit_test_progress-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="NUnit_test_progress.cs content, created by dsibinski on 05:05AM on June 19, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="NUnit_test_progress.cs">
        <tr>
          <td id="file-nunit_test_progress-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-nunit_test_progress-cs-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>[</span><span class=pl-c1>TestFixture</span><span class=pl-kos>]</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-nunit_test_progress-cs-LC2" class="blob-code blob-code-inner js-file-line"><span class=pl-k>public</span> <span class=pl-k>class</span> <span class=pl-smi>MyTests</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-nunit_test_progress-cs-LC3" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-nunit_test_progress-cs-LC4" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>[</span><span class=pl-c1>Test</span><span class=pl-kos>]</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-nunit_test_progress-cs-LC5" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>public</span> <span class=pl-smi>void</span> <span class=pl-en>SampleTest</span><span class=pl-kos>(</span><span class=pl-kos>)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-nunit_test_progress-cs-LC6" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-nunit_test_progress-cs-LC7" class="blob-code blob-code-inner js-file-line">        <span class=pl-c>// some operations here, like starting a server for tests in-memory&#8230;</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-nunit_test_progress-cs-LC8" class="blob-code blob-code-inner js-file-line">        </td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-nunit_test_progress-cs-LC9" class="blob-code blob-code-inner js-file-line">        <span class=pl-s1>TestContext</span><span class=pl-kos>.</span><span class=pl-s1>Progress</span><span class=pl-kos>.</span><span class=pl-en>WriteLine</span><span class=pl-kos>(</span><span class=pl-s>&quot;The server is running now! You can reach it on https://localhost:8067/&quot;</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-nunit_test_progress-cs-LC10" class="blob-code blob-code-inner js-file-line">        <span class=pl-k>while</span> <span class=pl-kos>(</span><span class=pl-c1>true</span><span class=pl-kos>)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-nunit_test_progress-cs-LC11" class="blob-code blob-code-inner js-file-line">        <span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-nunit_test_progress-cs-LC12" class="blob-code blob-code-inner js-file-line">            <span class=pl-c>// keep it running on purpose (e.g. for E2E tests)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-nunit_test_progress-cs-LC13" class="blob-code blob-code-inner js-file-line">        <span class=pl-kos>}</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-nunit_test_progress-cs-LC14" class="blob-code blob-code-inner js-file-line">        </td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-nunit_test_progress-cs-LC15" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>}</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-nunit_test_progress-cs-LC16" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>}</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/03221c21614c48cef6fdbbd5e11accb4/raw/1880d0e1f47cb145c600d96e5f1d392bf5728028/NUnit_test_progress.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/03221c21614c48cef6fdbbd5e11accb4#file-nunit_test_progress-cs" class="Link--inTextBlock">
          NUnit_test_progress.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">And that&#8217;s it! I&#8217;m publishing this simple solution, because it took me some time to find <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">I previously tried with <code>TestContext.Out.WriteLine</code>, <code>System.Diagnostics.Trace.WriteLine</code> and <code>System.Console.WriteLine</code>, but all of them output the text <em>after </em>the test finishes.</p>



<p class="wp-block-paragraph">Finally, you can also run the test from cmd using <code>dotnet test</code>:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="189" data-attachment-id="4081" data-permalink="https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/nunit_cmd_console_progress/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?fit=1119%2C206&amp;ssl=1" data-orig-size="1119,206" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="NUnit_cmd_console_progress" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?fit=1024%2C189&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?resize=1024%2C189&#038;ssl=1" alt="" class="wp-image-4081" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?resize=1024%2C189&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?resize=300%2C55&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?resize=768%2C141&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?w=1119&amp;ssl=1 1119w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">Hope it&#8217;s useful!</p>
<p>The post <a href="https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/">Write Test Progress To The Console With NUnit</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4070</post-id>	</item>
		<item>
		<title>How To Fix SqlException Database Is Not Currently Available On Azure (0x80131904)</title>
		<link>https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/</link>
					<comments>https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 17 May 2022 05:32:15 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[azure]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[microsoft azure]]></category>
		<category><![CDATA[nhibernate]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4036</guid>

					<description><![CDATA[<p>I recently deployed my .NET 6 application to Microsoft Azure. The app uses NHibernate for working with SQL Server database. After some time, I started getting an unhandled exception when opening the application: The database is not currently available was very interesting to me. I struggled a bit with solving that, so if you want&#8230;</p>
<p>The post <a href="https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/">How To Fix SqlException Database Is Not Currently Available On Azure (0x80131904)</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I recently deployed my .NET 6 application to Microsoft Azure. The app uses <a href="https://nhibernate.info/">NHibernate</a> for working with SQL Server database. After some time, I started getting an unhandled exception when opening the application:</p>



<pre class="wp-block-code"><code>NHibernate.Exceptions.GenericADOException: could not load an entity: 
...
 ---&gt; Microsoft.Data.SqlClient.SqlException (0x80131904): <strong>Database 'myappdb' on server 'myapp.database.windows.net' is not currently available</strong>.  Please retry the connection later.  If the problem persists, contact customer support, and provide them the session tracing ID of '{EB501CF2-2F21-4E28-9042-2B83EEE57B91}'.</code></pre>



<p class="wp-block-paragraph">The <em>database is</em> <em>not currently available </em>was very interesting to me. I struggled a bit with solving that, so if you want to know how I did it &#8211; continue reading <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4036"></span>



<h2 class="wp-block-heading">The problem</h2>



<p class="wp-block-paragraph">My .NET 6 app is an <a href="https://azure.microsoft.com/en-us/services/app-service/">Azure App Service</a>, and it uses SQL Server database. Quite standard Azure stuff.</p>



<p class="wp-block-paragraph">The issue was that when opening the ASP.NET web app after some time of inactivity, there was an HTTP 500 error. When I checked the logs, the full error looked as follows:</p>



<pre class="wp-block-code"><code><strong>NHibernate.Exceptions.GenericADOException: could not load an entity</strong>: &#91;MyApp.Infrastructure.DomainObjects.ApplicationUser#37931c5a376748d7a49f215ca30283a2]&#91;SQL: SELECT applicatio0_.applicationuser_key as id1_3_0_, applicatio0_1_.UserName as username2_3_0_, applicatio0_1_.NormalizedUserName as normalizedusername3_3_0_, applicatio0_1_.Email as email4_3_0_, applicatio0_1_.NormalizedEmail as normalizedemail5_3_0_, applicatio0_1_.EmailConfirmed as emailconfirmed6_3_0_, applicatio0_1_.PhoneNumber as phonenumber7_3_0_, applicatio0_1_.PhoneNumberConfirmed as phonenumberconfirmed8_3_0_, applicatio0_1_.LockoutEnabled as lockoutenabled9_3_0_, applicatio0_1_.LockoutEnd as lockoutend10_3_0_, applicatio0_1_.AccessFailedCount as accessfailedcount11_3_0_, applicatio0_1_.ConcurrencyStamp as concurrencystamp12_3_0_, applicatio0_1_.PasswordHash as passwordhash13_3_0_, applicatio0_1_.TwoFactorEnabled as twofactorenabled14_3_0_, applicatio0_1_.SecurityStamp as securitystamp15_3_0_ FROM ApplicationUsers applicatio0_ inner join dbo.AspNetUsers applicatio0_1_ on applicatio0_.applicationuser_key=applicatio0_1_.Id WHERE applicatio0_.applicationuser_key=?]
 ---&gt; Microsoft.Data.SqlClient.SqlException (0x80131904): <strong>Database 'myappdb' on server 'myapp.database.windows.net' is not currently available</strong>.  Please retry the connection later.  If the problem persists, contact customer support, and provide them the session tracing ID of '{EB501CF2-2F21-4E28-2342-2B836E35E891}'.
   at Microsoft.Data.ProviderBase.DbConnectionPool.CheckPoolBlockingPeriod(Exception e)</code></pre>



<p class="wp-block-paragraph">There were two characteristics of this error:</p>



<ul class="wp-block-list"><li>it always appeared after some time of not using the web app</li><li>I never reproduced it locally</li></ul>



<p class="wp-block-paragraph">So it must have been something wrong with Azure.</p>



<h2 class="wp-block-heading">Transient issues in Azure databases</h2>



<p class="wp-block-paragraph">First thing I did, obviously, was checking Azure App Service logs. This is what I found:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="288" data-attachment-id="4053" data-permalink="https://www.codejourney.net/azure_database_transient_problems/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?fit=1482%2C417&amp;ssl=1" data-orig-size="1482,417" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Azure_database_transient_problems" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?fit=1024%2C288&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?resize=1024%2C288&#038;ssl=1" alt="Error log when database is not currently available error occured in Azure" class="wp-image-4053" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?resize=1024%2C288&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?resize=300%2C84&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?resize=768%2C216&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?w=1482&amp;ssl=1 1482w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p class="wp-block-paragraph">The first recommended step got me curious. <em>To reduce the impact of connection issues caused by future reconfiguration, <strong>please implement retry logic in your code</strong></em>.</p>



<p class="wp-block-paragraph">So I started reading. There&#8217;s even <a href="https://docs.microsoft.com/en-us/aspnet/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/transient-fault-handling">official Microsoft documentation for that</a>. It basically says that <em>in the cloud environment you&#8217;ll find that failed and dropped database connections happen periodically.</em></p>



<p class="wp-block-paragraph">I must admit it seemed quite new to me. However, I started digging into that. I used <a href="https://github.com/App-vNext/Polly">Polly</a> to implement the retry logic in my app. I found few places where there was an NHibernate query for fetching users executed and wrapped it into the retry policy.</p>



<p class="wp-block-paragraph">Nothing worked. I was still getting the error. Then, after some talks with my coworkers, we found the real reason behind that&#8230;</p>



<h2 class="wp-block-heading">Solution: Azure database tier</h2>



<p class="wp-block-paragraph">When talking about the issue with my teammates, someone mentioned that the databases in Azure are <em>serverless</em> by default.</p>



<p class="wp-block-paragraph">I logged into the <a href="https://portal.azure.com/">Azure Portal</a> and checked the &#8220;Compute + storage&#8221; settings my SQL database my app used:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="382" data-attachment-id="4055" data-permalink="https://www.codejourney.net/azure_tier_settings_serverless/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?fit=1193%2C445&amp;ssl=1" data-orig-size="1193,445" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Azure_tier_settings_serverless" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?fit=1024%2C382&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?resize=1024%2C382&#038;ssl=1" alt="Azure Portal and Service and compute tier settings of SQL Database set to General Purpose. Reason for database is not currently available error" class="wp-image-4055" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?resize=1024%2C382&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?resize=300%2C112&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?resize=768%2C286&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?w=1193&amp;ssl=1 1193w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p class="wp-block-paragraph">Indeed, the tier selected was &#8220;General purpose (Scalable compute and storage options)&#8221; with &#8220;Serverless&#8221; compute tier selected.</p>



<p class="wp-block-paragraph">I changed it to &#8220;Basic (For less demanding workloads)&#8221;:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="507" data-attachment-id="4056" data-permalink="https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/azure_tier_settings_basic/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?fit=1188%2C588&amp;ssl=1" data-orig-size="1188,588" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Azure_tier_settings_basic" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?fit=1024%2C507&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?resize=1024%2C507&#038;ssl=1" alt="Azure Portal and tier of the SQL database changed to Basic. It made database is not currently available error disappear" class="wp-image-4056" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?resize=1024%2C507&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?resize=300%2C148&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?resize=768%2C380&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?w=1188&amp;ssl=1 1188w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p class="wp-block-paragraph">and&#8230; it worked <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92f.png" alt="🤯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> All errors saying that the database is not currently available disappeared. I also removed all Polly-related code for retry policies.</p>



<h2 class="wp-block-heading">A little explanation</h2>



<p class="wp-block-paragraph">Why do serverless databases in Azure behave like that?</p>



<p class="wp-block-paragraph">I finally found this explanation in the <a href="https://docs.microsoft.com/en-us/azure/azure-sql/database/serverless-tier-overview?view=azuresql">Microsoft documentation</a>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>If a serverless database is paused, then <strong>the first login will resume the database and return an error stating that the database is unavailable with error code 40613</strong>. Once the database is resumed, the login must be retried to establish connectivity</p></blockquote>



<p class="wp-block-paragraph">That blew my mind! It means that the <em>database is not currently available</em> exception is expected. There&#8217;s also another part there:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Database clients with connection retry logic should not need to be modified. For connection retry logic options that are built-in to the SqlClient driver, see&nbsp;<a href="https://docs.microsoft.com/en-us/sql/connect/ado-net/configurable-retry-logic">configurable retry logic in SqlClient</a>.</p></blockquote>



<p class="wp-block-paragraph">Apparently, users of ORMs like Entity Framework <a href="https://docs.microsoft.com/en-us/ef/ef6/fundamentals/connection-resiliency/retry-logic">should not have to worry about those issues</a>. Unfortunately, NHibernate doesn&#8217;t have such built-in transient errors retry logic. That&#8217;s why I experienced this particular issue and couldn&#8217;t find any straightforward solution online. Simply not many people (if anyone at all? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" />) experienced this before.</p>



<p class="wp-block-paragraph">If you want even more details and context, check out this article: <a href="https://kohera.be/azure-cloud/should-i-use-serverless-for-all-my-azure-sql-databases/">SHOULD I USE SERVERLESS FOR ALL MY AZURE SQL DATABASES?</a></p>



<h2 class="wp-block-heading">What if I want to use serverless Azure database?</h2>



<p class="wp-block-paragraph">Well&#8230; if you really want to use the serverless features of Azure, you might be struggling with NHibernate. As I mentioned, apparently there&#8217;s no built-in transient failures retry mechanism in the ORM. There&#8217;s one promising solution <a href="https://github.com/MRCollective/NHibernate.SqlAzure">here</a>. However, currently it&#8217;s build for NHibernate 3.3.1.4000, so it doesn&#8217;t work with the current version. There&#8217;s a <a href="https://github.com/MRCollective/NHibernate.SqlAzure/pull/37">Pull Request</a> and an <a href="https://github.com/MRCollective/NHibernate.SqlAzure/issues/32">issue</a> opened for upgrading it to the newest version and .NET 6/7. Let&#8217;s hope it is done soon.</p>



<p class="wp-block-paragraph">Otherwise, you can try using <a href="https://www.codejourney.net/2022/05/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/">Polly</a> as I did initially. However, I didn&#8217;t manage to make fully working.</p>



<p class="wp-block-paragraph">If you have any other idea or solution &#8211; let us know in the comments below.</p>



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



<p class="wp-block-paragraph">I hope this article saves you some hours of debugging, so you can quickly solve this <em>database is not currently available</em> error in Azure. I wish I found this article on another website few weeks ago <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/">How To Fix SqlException Database Is Not Currently Available On Azure (0x80131904)</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4036</post-id>	</item>
		<item>
		<title>How to fix: npm ERR! enoent ENOENT: no such file or directory, rename</title>
		<link>https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/</link>
					<comments>https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 04:33:47 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[npm]]></category>
		<category><![CDATA[npm ERR! enoent ENOENT]]></category>
		<category><![CDATA[npm error]]></category>
		<category><![CDATA[npm install package]]></category>
		<category><![CDATA[react]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3927</guid>

					<description><![CDATA[<p>I recently struggled for a while with an npm error thrown when executing npm install of some package. The error message was npm ERR! enoent ENOENT: no such file or directory, rename 'D:\\WebApp\\node_modules\\lz-string' -&#62; 'D:\\WebApp\\node_modules.lz-string.DELETE' Finally, I found a solution and a reason for that issue. The error occurred when I was trying to install&#8230;</p>
<p>The post <a href="https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/">How to fix: npm ERR! enoent ENOENT: no such file or directory, rename</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[


<p class="wp-block-paragraph">I recently struggled for a while with an <code>npm</code> error thrown when executing <code>npm install</code> of some package. The error message was <code>npm ERR! enoent ENOENT: no such file or directory, rename 'D:\\WebApp\\node_modules\\lz-string' -&gt; 'D:\\WebApp\\node_modules.lz-string.DELETE'</code></p>



<p class="wp-block-paragraph">Finally, I found a solution and a reason for that issue.</p>



<span id="more-3927"></span>



<p class="wp-block-paragraph">The error occurred when I was trying to install <code>@testing-library/react</code> npm package. It looked like that:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="404" data-attachment-id="3928" data-permalink="https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/npm_rename_error/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?fit=1360%2C536&amp;ssl=1" data-orig-size="1360,536" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="npm_rename_error" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?fit=1024%2C404&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?resize=1024%2C404&#038;ssl=1" alt="npm ERR! enoent ENOENT error in Visual Studio Code" class="wp-image-3928" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?resize=1024%2C404&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?resize=300%2C118&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?resize=768%2C303&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?resize=676%2C266&amp;ssl=1 676w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/npm_rename_error.png?w=1360&amp;ssl=1 1360w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>
</div>


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



<p class="wp-block-paragraph">If you ever get this error, the hotfix is to follow these steps:</p>



<ul class="wp-block-list"><li>delete <code>node-modules</code> folder</li><li>run command <code>npm cache clean --force</code></li><li>run command <code>npm install</code></li><li>install the package again with <code>npm install your-package-name</code></li></ul>



<p class="wp-block-paragraph">It should all work fine after that. </p>



<p class="wp-block-paragraph">If these commands still don&#8217;t solve your issue, and you use <code>git</code> as a source control system, you can try the unbeatable <code>git clean -fdx</code> command. After that, run <code>npm install</code> again. Beware &#8211; it removes all files not checked in to git. It may also remove your IDE settings etc., so use with care.</p>



<p class="wp-block-paragraph">But it&#8217;s only a hotfix, a solution <em>for now</em> to unblock you.</p>



<h2 class="wp-block-heading">Coldfix (solution)</h2>



<p class="wp-block-paragraph">The real reason for this issue in my case turned out to be related to <code>jest</code>. However, not to the testing library itself, but to <a href="https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest" target="_blank" rel="noreferrer noopener">jest extension for Visual Studio Code</a>.</p>



<p class="wp-block-paragraph">The reason for the issue is the jest tests runner working in the background. You can see that in the VS Code bottom bar:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="320" height="158" data-attachment-id="3929" data-permalink="https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/vscode_jest_runner/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/vsCode_jest_runner.png?fit=320%2C158&amp;ssl=1" data-orig-size="320,158" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="vsCode_jest_runner" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/vsCode_jest_runner.png?fit=320%2C158&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/vsCode_jest_runner.png?resize=320%2C158&#038;ssl=1" alt="Visual Studio Code - jest runner" class="wp-image-3929" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/vsCode_jest_runner.png?w=320&amp;ssl=1 320w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/vsCode_jest_runner.png?resize=300%2C148&amp;ssl=1 300w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
</div>


<p class="wp-block-paragraph">The real solution is to disable jest runner when installing new packages. You can do it with a <code>Jest: Stop Runner</code> command in Ctrl+Shift+P:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="777" height="246" data-attachment-id="3930" data-permalink="https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/vscode_jest_stop_runner/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/VSCode_jest_stop_runner.png?fit=777%2C246&amp;ssl=1" data-orig-size="777,246" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="VSCode_jest_stop_runner" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/VSCode_jest_stop_runner.png?fit=777%2C246&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/VSCode_jest_stop_runner.png?resize=777%2C246&#038;ssl=1" alt="npm ERR! enoent ENOENT fix in Visual Studio by stopping jest runner" class="wp-image-3930" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/VSCode_jest_stop_runner.png?w=777&amp;ssl=1 777w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/VSCode_jest_stop_runner.png?resize=300%2C95&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/VSCode_jest_stop_runner.png?resize=768%2C243&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2021/04/VSCode_jest_stop_runner.png?resize=676%2C214&amp;ssl=1 676w" sizes="auto, (max-width: 777px) 100vw, 777px" /></figure>
</div>


<p class="wp-block-paragraph">I don&#8217;t know exactly why this is an issue. I guess jest runner is blocking some files in <code>node-modules</code>, so they cannot be renamed/processed. I hope it helps you too <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/">How to fix: npm ERR! enoent ENOENT: no such file or directory, rename</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/how-to-fix-npm-err-enoent-enoent-no-such-file-or-directory-rename/feed/</wfw:commentRss>
			<slash:comments>13</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3927</post-id>	</item>
		<item>
		<title>Improve your tests with Assert Object Pattern</title>
		<link>https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/</link>
					<comments>https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Mon, 09 Nov 2020 20:42:34 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[assert object]]></category>
		<category><![CDATA[assert object pattern]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[unit tests]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3888</guid>

					<description><![CDATA[<p>The Asserts Hell Let&#8217;s consider the following unit test: What&#8217;s wrong here? Given and When sections are great single-liners. We know straightaway what&#8217;s the input and the action executed. However, Then block is too complex. It&#8217;s hard to figure out, just passing quickly through this test, what is expected. This case is even not that&#8230;</p>
<p>The post <a href="https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/">Improve your tests with Assert Object Pattern</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Today I&#8217;d like to share with you a very interesting concept in software testing &#8211; Assert Object pattern. It makes the <em>Assert</em> part of a test much simpler and more readable. Let&#8217;s dive right into it <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-3888"></span>





<h2 class="wp-block-heading">The Asserts Hell</h2>



<p class="wp-block-paragraph">Let&#8217;s consider the following unit test:</p>



<script src="https://gist.github.com/dsibinski/f8fea58079d68dd8ac0d194a33964e1b.js"></script>



<p class="wp-block-paragraph">What&#8217;s wrong here? <em>Given</em> and <em>When</em> sections are great single-liners. We know straightaway what&#8217;s the input and the action executed. However, <em>Then</em> block is too complex. It&#8217;s hard to figure out, just passing quickly through this test, what is <em>expected</em>. This case is even not that bad thanks to the usage of <a href="https://fluentassertions.com/">FluentAssertions</a>.</p>



<p class="wp-block-paragraph">I spend a lot of time writing tests (<a href="https://www.codejourney.net/2017/03/unit-testing-xamarin-application/">unit</a> or integration), but I spend even more time reading them. I always hope that I will find these <em>idyllic</em> tests that act as code documentation&#8230; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9d0.png" alt="🧐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">However, let&#8217;s go step by step. I recently took place in a <a href="https://smarttesting.pl/">software testing course</a>. That&#8217;s where I discovered the solution to <em>The Asserts Hell</em>.</p>



<h2 class="wp-block-heading">Assert Object for Better Asserts</h2>



<p class="wp-block-paragraph">Assert Object pattern is what solves our problem. The idea is to create an <em>Assert</em> class which wraps the original object being tested. In our case the tested object is of <span style="color:#ff9f05" class="tadv-color">Product</span> class, so our assert class will be called <span style="color:#ff9f05" class="tadv-color">ProductAssert</span>.</p>



<p class="wp-block-paragraph">Let&#8217;s see the implementation:</p>



<script src="https://gist.github.com/dsibinski/10a3c47a7e997eed29fabcb07914786b.js"></script>



<p class="wp-block-paragraph">As you can see, we simply moved the asserts from our test&#8217;s Then section into <span style="color:#ff9f05" class="tadv-color">ProductAssert</span> class&#8217;s methods. Additionally, we always return <span style="color:#ff9f05" class="tadv-color">this</span> from each asserting method, which allows chaining functions calls.</p>



<p class="wp-block-paragraph">We can now use such assert object<span style="color:#444" class="tadv-color"> in our</span> unit test: </p>



<script src="https://gist.github.com/dsibinski/e0a649e6134b9c6b389d3419db62f92a.js"></script>



<p class="wp-block-paragraph">You must agree it&#8217;s much more readable now <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">We can of course improve it even more, for example by wrapping these 3 assertion methods (<span style="color:#ff9f05" class="tadv-color">BeAvailable()</span>, <span style="color:#ff9f05" class="tadv-color">HaveDiscount() </span><span style="color:#444" class="tadv-color">and</span><span style="color:#ff9f05" class="tadv-color"> Cost()</span>) into a single one. We can also easily create an <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods">extension method</a> for the <span style="color:#ff9f05" class="tadv-color">Product</span> class itself, so the assert object doesn&#8217;t have to be instantiated in our unit test. I could even add an extension to <em>FluentAssertions</em> library.</p>



<p class="wp-block-paragraph">You can find complete source code used as examples in this article <a href="https://github.com/dsibinski/Playground/tree/main/Playground/Playground.Tests">here</a>.</p>



<h2 class="wp-block-heading">Assert Object &#8211; summary</h2>



<p class="wp-block-paragraph">I personally find Assert Object a very useful tests code refactoring method. As a programmer, you spend most of your time not on writing, but on reading the source code. Clear and simple tests can make your (and your colleagues&#8217;) life much better <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Of course, the Assert Object pattern should not be your default way of asserting. If you can complete your test with one or two assertions, then it&#8217;s probably better to keep it without wrapping into any additional objects. Having too many <em>assert</em> statements might also mean that the objects being tested are poorly designed. However, as we often work with legacy code which we can&#8217;t easily change or refactor, it might be a good solution.</p>



<p class="wp-block-paragraph">What patterns for writing better tests do you use? Share your tips in the comments!</p>
<p>The post <a href="https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/">Improve your tests with Assert Object Pattern</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3888</post-id>	</item>
		<item>
		<title>Is It Worth Migrating to TypeScript?</title>
		<link>https://www.codejourney.net/is-it-worth-migrating-to-typescript/</link>
					<comments>https://www.codejourney.net/is-it-worth-migrating-to-typescript/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 29 Aug 2020 11:03:05 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ts]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[typescript migration]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3840</guid>

					<description><![CDATA[<p>Choosing migration strategy Bright side of migrating to TypeScript If you are a JavaScript developer, the best advice I can give you is to start using TypeScript 🙂 In this section I&#8217;m describing what positively surprised me since the beginning of starting to use TypeScript. Types &#8220;for free&#8221; As soon as we changed our transpiler&#8230;</p>
<p>The post <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">Is It Worth Migrating to TypeScript?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>For the past year I&#8217;ve been working on a JavaScript project for my client. We have a mid-size web application. We use React as the web development framework. Few months ago we decided to start migrating to TypeScript.</p>
<p>Today I can say that <strong>it was the best decision we could make</strong>. TypeScript makes working with JavaScript, which is sometimes <a href="https://www.codejourney.net/2018/11/10-most-shocking-javascript-features-for-csharp-developers/" target="_blank" rel="noopener noreferrer">surprising and quite hard to understand</a>, so much better experience. However, there were some challenges on this journey. If you want to know what issues we met and how we solved them, but also what huge advantages TypeScript gave us &#8211; read on <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><em>I will not discuss TypeScript itself in this article. This is a pure recap of challenges and the experience I gained when migrating to TypeScript.</em></p>



<span id="more-3840"></span>



<h2 class="wp-block-heading">Choosing migration strategy</h2>



<p>Before starting migrating to TypeScript, we had to choose the best strategy for this process. There were two possibilities we considered: <strong>migrating the whole JavaScript codebase to TypeScript at once</strong> or <strong>switching to TypeScript compiler and migrating part-by-part</strong>.</p>
<p>For those who are not familiar with TypeScript &#8211; it is a superset of JavaScript which adds typing information to your JS code. It means that <strong>every JavaScript code is also a valid TypeScript code</strong>. When compiling TypeScript code, TS compiler removes the typing data and outputs readable, vanilla JavaScript code ready to be executed.</p>
<p>Migrating the whole codebase to TypeScript would mean to change all files extensions to TypeScript ones: <em>.js</em> to <em>.ts</em> and <em>.jsx</em> to <em>.tsx</em>. It would also mean that TypeScript compiler starts checking types in those files. This approach is doable, but &#8211; depending on the size of your project &#8211; can take a long time. During migration the code would be frozen until you fully migrate the project. Also, for TypeScript beginners, it could be a bit frustrating having to type everything at once or use some tricks to tell TypeScript to ignore checking types in many cases (because the type is not known at this stage, or we want to do it later etc.).</p>
<p>Because of that, <strong>we decided to migrate part-by-part, having JavaScript and TypeScript files at the same time</strong>. It is possible thanks to enabling <a href="https://www.typescriptlang.org/docs/handbook/compiler-options.html" target="_blank" rel="noopener noreferrer"><em>allowJs&nbsp;</em>TS compiler option</a>. It means that TypeScript will compile both TS and JS files. Such approach allows the coexistence of old JS code with the new TS parts. It also allows moving only chosen parts of the application to TypeScript at the beginning and come back to the others later.</p>
<p>In our web application the biggest JS files have few thousand lines of code. Some of this legacy code still didn&#8217;t use React, but <a href="https://backbonejs.org/" target="_blank" rel="noopener noreferrer">Backbone</a> as their framework. We didn&#8217;t want to touch these oldest files in the beginning. Instead, <strong>we moved few recently written functionalities to TypeScript straightaway and decided to implement everything new in TS as well</strong>.</p>



<h2 class="wp-block-heading">Bright side of migrating to TypeScript</h2>



<p class="wp-block-paragraph">If you are a JavaScript developer, the best advice I can give you is to start using TypeScript <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> In this section I&#8217;m describing what positively surprised me since the beginning of starting to use TypeScript.</p>



<h3 class="wp-block-heading">Types &#8220;for free&#8221;</h3>



<p class="wp-block-paragraph">As soon as we changed our transpiler from <em>babel-loader</em> to <em>ts-loader, </em>I wanted to know how we can get typing information for already-installed npm packages. It turns out that <strong>for 98% of the packages we used there&#8217;s already a typing information available</strong> as a separate npm package. </p>



<p class="wp-block-paragraph">In most cases if you have a npm package called <em>abc</em> there&#8217;s a typing package available called <em>@types/abc</em>. I explored our <em>package.json </em>and for each package listed there I just executed <em>npm install @types/package-name</em>. 2 or 3 older or not-so-popular packages didn&#8217;t have types definitions available, but for the rest we got types for free, without having to type anything ourselves. This was a first, very nice surprise <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">You can find more information about TypeScript types definition packages, as well as contribute one yourself, <a href="https://github.com/DefinitelyTyped/DefinitelyTyped" target="_blank" rel="noreferrer noopener">here</a>.</p>



<h3 class="wp-block-heading">All new code is typed</h3>



<p class="wp-block-paragraph">As I wrote before, every new feature we&#8217;ve added since the migration is written in TypeScript. Thanks to that, <strong>all n</strong>ew code we write <strong>is strongly typed</strong>. What&#8217;s remarkable here is that it required almost no effort. We just switched the compiler to TS (with a small struggle with webpack configuration, about which you can read below) and suddenly got into typed world for every new feature we implement. Quite impressive, isn&#8217;t it? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">JS-TS friendship</h3>



<p class="wp-block-paragraph">Coexistence and friendship between JavaScript and TypeScript is HUGE. <strong>These two creatures are not enemies &#8211; they are best friends</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /> We&#8217;ve already gone through many scenarios when we needed to use something written in TS in a JS file and otherwise. It turns out that all of these scenarios are manageable. Sometimes you need to import something differently (for example using <em>require</em> instead of <em>import</em>), but it&#8217;s all possible. We found it super easy to write new features or even add parts of new features to already-existing JS code, writing everything in TypeScript.</p>



<p class="wp-block-paragraph">We also rewrote some JS files that were used from multiple places in the app to TypeScript. As an example of JS-TS coexistence, I&#8217;m presenting below the potential <em>.ts</em> source code you might have. It contains both old, legacy JS code when we used <em>module.exports</em> and <em>prototype</em> to expose various services for data fetching, as well as a brand-new, nicely-exported TypeScript class:</p>



<p class="wp-block-paragraph"><style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105109386" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-services-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="services.ts content, created by dsibinski on 08:09AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="services.ts">
        <tr>
          <td id="file-services-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-services-ts-LC1" class="blob-code blob-code-inner js-file-line">module.exports.UsersService = function (url) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-services-ts-LC2" class="blob-code blob-code-inner js-file-line">  // &#8230; UsersService init code &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-services-ts-LC3" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
        <tr>
          <td id="file-services-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-services-ts-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-services-ts-LC5" class="blob-code blob-code-inner js-file-line">module.exports.UsersService.prototype.getUser = function (id) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-services-ts-LC6" class="blob-code blob-code-inner js-file-line">  // &#8230; code to get active user by id &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-services-ts-LC7" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
        <tr>
          <td id="file-services-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-services-ts-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-services-ts-LC9" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-services-ts-LC10" class="blob-code blob-code-inner js-file-line">export class NewUsersService {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-services-ts-LC11" class="blob-code blob-code-inner js-file-line">  url: string;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-services-ts-LC12" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-services-ts-LC13" class="blob-code blob-code-inner js-file-line">  constructor(url: string) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-services-ts-LC14" class="blob-code blob-code-inner js-file-line">    // &#8230; NewUsersService init code &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-services-ts-LC15" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-services-ts-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-services-ts-LC16" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-services-ts-LC17" class="blob-code blob-code-inner js-file-line">  getUser(id: number): JQuery.Promise&lt;UserViewModel, any, any&gt; {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-services-ts-LC18" class="blob-code blob-code-inner js-file-line">    // &#8230; code to get active user by id &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-services-ts-LC19" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-services-ts-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-services-ts-LC20" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/fceb3650f2121640a5e32a78ec3dc740/raw/504b504a930a8262f334017f8aeddc675e3692bf/services.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/fceb3650f2121640a5e32a78ec3dc740#file-services-ts" class="Link--inTextBlock">
          services.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
 </p>



<p class="wp-block-paragraph">Such code can of course be in separate files, but it only shows how good TS and JS can coexist together. You can keep your old code working, while implementing anything new in TypeScript.</p>



<h3 class="wp-block-heading">Flexibility in partial migrating to TypeScript</h3>



<p class="wp-block-paragraph">It turns out that choosing to partially move our web project to TypeScript was a great decision. The team wouldn&#8217;t be so happy and enthusiastic about TS if we told them to move legacy Backbone code to TypeScript. Instead, we gave them a nice tool which can be used for all new stuff. Also, if someone likes the idea and wants to move already-existing JS file to TS, he or she is welcome to do so. </p>



<p class="wp-block-paragraph">That&#8217;s how <strong>we are still migrating our project to TypeScript, without any hustle and frustration</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Wisdom of TypeScript</h3>



<p class="wp-block-paragraph">I&#8217;m positively surprised by TypeScript almost every day. At some point I get to the issue that seems hard to be solved or quite non-standard. Then I find a solution online and <strong>it makes me really impressed about the job <a href="https://github.com/microsoft/TypeScript" target="_blank" rel="noreferrer noopener">the community and Microsoft has been doing</a> around the language</strong>. </p>



<p class="wp-block-paragraph">These are sometimes small, but smart things. Recently we got surprised by <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">keyof</a>, which lets you get names of the allowed properties of your type. Generally <a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html" target="_blank" rel="noreferrer noopener">the typing system</a> is really advanced and impressive. For some it can be a disadvantage, but I think it gives an enormous flexibility. </p>



<p class="wp-block-paragraph">This is somehow the JavaScript you-can-do-whatever-you-want philosophy smuggled into TypeScript <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> But in a much smarter way. I&#8217;m sure that when you start working with TypeScript you&#8217;ll get what I mean by its wisdom <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Small effort, huge benefits</h3>



<p>Last, but not least, I must admit that <strong>migrating to TypeScript was quite an easy and smooth process. The value for the effort is huge</strong>. You get a typed world with very little work.</p>



<h2 class="wp-block-heading">Migrating to TypeScript struggles</h2>



<p class="wp-block-paragraph">During the migration process we met few difficulties. Some of them we managed to solve fully or partially. If you have any better ideas on these things, feel free to let me know in the comments.</p>



<h3 class="wp-block-heading">Complexity of webpack configuration</h3>



<p class="wp-block-paragraph">When switching to TypeScript we had few issues with <a href="https://webpack.js.org/" target="_blank" rel="noreferrer noopener">webpack</a> configuration. We have used <a href="https://github.com/babel/babel-loader" target="_blank" rel="noreferrer noopener"><em>babel-loader</em></a> before for transpiling JavaScript and initially we wanted to keep it in the TS compilation process. We first tried to keep <em>babel-loader</em> for JS(X) files and use <em>ts-loader</em> for TS(X) files, but it didn&#8217;t work &#8211; we were getting weird compilation errors. </p>



<p class="wp-block-paragraph">Then we tried to compile everything using <em>ts-loader</em> and then recompile it again using <em>babel</em> to ensure (as we initially thought would be wise) backwards compatibility. We also couldn&#8217;t make it working.</p>



<p class="wp-block-paragraph"><strong>Finally, we decided to compile everything &#8211; both JavaScript and TypeScript files &#8211; using <em>ts-loader</em></strong> (including React files). It worked, except source code maps. When we tried to debug in Chrome console it seemed the source code is not refreshing properly after rebuilding. Breakpoints were often not hit and the debugging didn&#8217;t seem right. </p>



<p class="wp-block-paragraph">After a bit of struggling we found a solution. We set <a href="https://webpack.js.org/configuration/devtool/" target="_blank" rel="noreferrer noopener">devtool</a> webpack option to <em>eval-source-map</em> and configured <em><a href="https://www.npmjs.com/package/source-map-loader" target="_blank" rel="noreferrer noopener">source-map-loader</a></em> for <em>.js</em> files. Finally, the proper part of webpack config looks as follows:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110022" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-webpack_partial-config-js" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-javascript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="webpack_partial.config.js content, created by dsibinski on 09:40AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="webpack_partial.config.js">
        <tr>
          <td id="file-webpack_partial-config-js-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-webpack_partial-config-js-LC1" class="blob-code blob-code-inner js-file-line">devtool: &quot;eval-source-map&quot;,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-webpack_partial-config-js-LC2" class="blob-code blob-code-inner js-file-line">module: {</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-webpack_partial-config-js-LC3" class="blob-code blob-code-inner js-file-line">    rules: [</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-webpack_partial-config-js-LC4" class="blob-code blob-code-inner js-file-line">        { </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-webpack_partial-config-js-LC5" class="blob-code blob-code-inner js-file-line">            enforce: &quot;pre&quot;, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-webpack_partial-config-js-LC6" class="blob-code blob-code-inner js-file-line">            test: /\.js$/, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-webpack_partial-config-js-LC7" class="blob-code blob-code-inner js-file-line">            exclude: /node_modules/, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-webpack_partial-config-js-LC8" class="blob-code blob-code-inner js-file-line">            loader: &quot;source-map-loader&quot; </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-webpack_partial-config-js-LC9" class="blob-code blob-code-inner js-file-line">        },</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-webpack_partial-config-js-LC10" class="blob-code blob-code-inner js-file-line">        {</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-webpack_partial-config-js-LC11" class="blob-code blob-code-inner js-file-line">            test: /\.(t|j)sx?$/,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-webpack_partial-config-js-LC12" class="blob-code blob-code-inner js-file-line">            exclude: /node_modules/,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-webpack_partial-config-js-LC13" class="blob-code blob-code-inner js-file-line">            use: { </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-webpack_partial-config-js-LC14" class="blob-code blob-code-inner js-file-line">                loader: &#39;ts-loader&#39;</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-webpack_partial-config-js-LC15" class="blob-code blob-code-inner js-file-line">            }</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-webpack_partial-config-js-LC16" class="blob-code blob-code-inner js-file-line">        },  </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-webpack_partial-config-js-LC17" class="blob-code blob-code-inner js-file-line">    ],</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-webpack_partial-config-js-LC18" class="blob-code blob-code-inner js-file-line">},</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/2cb3c4c10fe63a9020508c20fa31eef3/raw/6e5f9baf9bf87fec5c43cccf25e5610607c36fa6/webpack_partial.config.js" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/2cb3c4c10fe63a9020508c20fa31eef3#file-webpack_partial-config-js" class="Link--inTextBlock">
          webpack_partial.config.js
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>So far we also haven&#8217;t noticed any issues related to backwards compatibility that were theoretically solved by <em>babel</em>. TypeScript compiler does its job very well.</p>



<h3 class="wp-block-heading">Complicated JS -&gt; TS refactoring</h3>



<p class="wp-block-paragraph">I found out that JS to TS refactoring is not always an easy task. <strong>Some things that are allowed by JavaScript are not valid in TypeScript</strong>. In most cases it means that something was wrong with your JavaScript code, but we all know how it is with legacy code refactoring <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="has-dark-gray-color has-text-color wp-block-paragraph">As an example, we had several functions that we added to a <span style="color:#ef7604" class="tadv-color">String</span> prototype in JavaScript:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110060" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-string_prototype_helpers-js" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-javascript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="string_prototype_helpers.js content, created by dsibinski on 09:47AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="string_prototype_helpers.js">
        <tr>
          <td id="file-string_prototype_helpers-js-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-string_prototype_helpers-js-LC1" class="blob-code blob-code-inner js-file-line">String.prototype.contains = function (it) {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-js-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-string_prototype_helpers-js-LC2" class="blob-code blob-code-inner js-file-line">        return this.indexOf(it) != -1;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-js-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-string_prototype_helpers-js-LC3" class="blob-code blob-code-inner js-file-line">    };</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/5e9553424d7441fddefee5f2519ad6dc/raw/d67095fec29dee3eda04be5994faa58f7f94cee7/string_prototype_helpers.js" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/5e9553424d7441fddefee5f2519ad6dc#file-string_prototype_helpers-js" class="Link--inTextBlock">
          string_prototype_helpers.js
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>Such code becomes invalid in TypeScript:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="782" height="174" data-attachment-id="3862" data-permalink="https://www.codejourney.net/is-it-worth-migrating-to-typescript/typescript_prototype_functions_error/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?fit=782%2C174&amp;ssl=1" data-orig-size="782,174" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TypeScript_prototype_functions_error" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?fit=782%2C174&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=782%2C174&#038;ssl=1" alt="Migrating to TypeScript: TS error about non-existing function on String prototype in VS Code" class="wp-image-3862" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?w=782&amp;ssl=1 782w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=300%2C67&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=768%2C171&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=676%2C150&amp;ssl=1 676w" sizes="auto, (max-width: 782px) 100vw, 782px" /><figcaption>TypeScript complaining about non-existing function</figcaption></figure>



<p class="wp-block-paragraph">A non-obvious solution to that issue is to extend <span style="color:#ef7604" class="tadv-color">String</span> interface by declaring typed functions you want to add:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110103" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-string_prototype_helpers-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="string_prototype_helpers.ts content, created by dsibinski on 09:53AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="string_prototype_helpers.ts">
        <tr>
          <td id="file-string_prototype_helpers-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-string_prototype_helpers-ts-LC1" class="blob-code blob-code-inner js-file-line">interface String {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-string_prototype_helpers-ts-LC2" class="blob-code blob-code-inner js-file-line">    contains(this : string, it : any): boolean;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-string_prototype_helpers-ts-LC3" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-string_prototype_helpers-ts-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-string_prototype_helpers-ts-LC5" class="blob-code blob-code-inner js-file-line">String.prototype.contains = function (it) {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-string_prototype_helpers-ts-LC6" class="blob-code blob-code-inner js-file-line">    return this.indexOf(it) != -1;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-string_prototype_helpers-ts-LC7" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/f0cd64ae8967aee9a0cfc13409259e1f/raw/92dd7b6a53393c445096b7b63ba08149acf256c5/string_prototype_helpers.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/f0cd64ae8967aee9a0cfc13409259e1f#file-string_prototype_helpers-ts" class="Link--inTextBlock">
          string_prototype_helpers.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>There are more subtle difficulties like that you can meet while migrating JS code to TypeScript. However, in the end it gives you a possibility to make your codebase better.</p>



<h3 class="wp-block-heading">Keeping view models in sync</h3>



<p class="wp-block-paragraph">An issue I didn&#8217;t think about before migrating to TypeScript was a need to keep frontend and backend view models in sync.</p>



<p class="wp-block-paragraph">One of the first things you&#8217;d like to have in your TypeScript codebase is to have as much typed data as possible. We use .NET and C# as the backend of our application. ASP.NET MVC controllers returned the strongly-typed objects into the previously chaotic and untyped JS world. Now we are strongly-typed with TypeScript, so we&#8217;d like all this data typed as well <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Here comes the problem. First of all <strong>our C# data models which we returned from the controllers were not the best</strong>. In most cases we returned a DTO object which contained many properties from which only few were used by JavaScript code. We never saw this problem, because in JS we just dynamically typed properties names we wanted to use. We didn&#8217;t see how much of not needed data is sent from ASP controllers to the web browser.</p>



<p class="wp-block-paragraph">Now <strong>with TypeScript we needed to create these objects definitions also in TypeScript</strong>. Having a huge DTO object returned from the controller, with another X objects on which this DTO depends, it was a nightmare. <strong>It turned out that for a single DTO I had to create 10-15 TypeScript objects just to use 5-10 properties in the frontend code!</strong></p>



<p class="wp-block-paragraph">That&#8217;s the moment when we came to the necessity of <strong>creating web view models</strong>. The idea is to <strong>return a view model from a controller, not the whole DTO object. This view model contains only the data which is needed by TypeScript (frontend)</strong>.</p>



<p class="wp-block-paragraph">I think this is nothing new for experienced web developers. However, now comes the question: <strong>how do we keep backend (C#) view models in sync with frontend (TypeScript) ones?</strong></p>



<p class="wp-block-paragraph">Unfortunately, I haven&#8217;t found a perfect solution for that. The best method I came up with is&#8230; <strong>manually keeping these view models in sync</strong>. </p>



<p class="wp-block-paragraph">There&#8217;s a <a href="https://marketplace.visualstudio.com/items?itemName=adrianwilczynski.csharp-to-typescript" target="_blank" rel="noreferrer noopener">C# to TypeScript</a> VS Code extension which allows to paste the copied C# code as its TypeScript equivalent. It makes the job a bit easier. It even has a <a href="https://www.nuget.org/packages/CSharpToTypeScript.CLITool/" target="_blank" rel="noreferrer noopener">CLI tool</a>, but it produces a single <em>.ts</em> file from a single <em>.cs</em> file. If you have multiple objects in a single C# file it will produce a single TypeScript file with all these objects. If any of those objects is used in other files (unfortunately we have many of such cases), these dependencies will not be automatically added as imports in the auto-generated <em>.ts</em> files.</p>



<p class="wp-block-paragraph">However, I don&#8217;t find it very problematic for now. As soon as the TS view models are created, we just need to update them as often as we update C# view models. I think this is a very common issue so if you know any better solution here &#8211; please share in the comments <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Migrating to TypeScript &#8211; summary</h2>



<p class="wp-block-paragraph">Migrating to TypeScript has been a very interesting and rewarding process. Compared to vanilla JavaScript, TypeScript lets programmers see many problems. This allows to see how bad our codebase was. We even realized that our server-side C# code was not the best (see the section about view models above). Thanks to introducing TypeScript we improved a lot of our JavaScript and C# code, including its architecture.</p>



<p class="wp-block-paragraph">I think that TypeScript uses many simple concepts under the hood and it makes a lot of things possible (see <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">keyof</a> or <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">unknown</a>). In many cases TypeScript <em>lets</em> you do something, but <em>doesn&#8217;t force</em> you to do it. That&#8217;s the beauty of this typed JavaScript world <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">Is It Worth Migrating to TypeScript?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/is-it-worth-migrating-to-typescript/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3840</post-id>	</item>
		<item>
		<title>Basics of Flutter Widgets</title>
		<link>https://www.codejourney.net/basics-of-flutter-widgets/</link>
					<comments>https://www.codejourney.net/basics-of-flutter-widgets/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Thu, 16 Jan 2020 16:00:59 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[dart]]></category>
		<category><![CDATA[flutter]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3715</guid>

					<description><![CDATA[<p>What is a widget? If you ever worked with a web framework like React, you should know the concept of components. Flutter widgets are directly inspired by this idea. Widget is a reusable piece of code, which describes how your application&#8217;s UI looks like. Widgets define the user interface by their state. In some cases,&#8230;</p>
<p>The post <a href="https://www.codejourney.net/basics-of-flutter-widgets/">Basics of Flutter Widgets</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>After <a href="https://www.codejourney.net/2019/12/your-first-flutter-app-in-30-minutes/" target="_blank" rel="noopener noreferrer">writing our first Flutter app in less than 30 minutes</a>, today we&#8217;re taking a look at Flutter widgets. If you want to know what is a widget in Flutter, what are widgets types and how to use them &#8211; this article is for you <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-3715"></span>



<h2 class="wp-block-heading">What is a widget?</h2>



<p class="wp-block-paragraph">If you ever worked with a web framework like <a rel="noreferrer noopener" aria-label="React (opens in a new tab)" href="https://reactjs.org/" target="_blank">React</a>, you should know the concept of <em>components</em>. Flutter widgets are directly inspired by this idea. Widget is a <strong>reusable piece of code, which describes how your application&#8217;s UI looks like</strong>. Widgets define the user interface by their <strong>state</strong>. In some cases, the state can be static and not change over time &#8211; see the <a href="#flutter-widget-types">section below about Flutter widget types</a> for details.</p>



<p class="wp-block-paragraph">As soon as a widget&#8217;s state changes, Flutter rebuilds its outlook and in effect re-renders the GUI. The framework is said to do it efficiently by measuring what has changed in the widgets tree since the last rendering and re-paints only what&#8217;s necessary.</p>



<p class="wp-block-paragraph">The most basic Flutter app might look as follows:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist100539783" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-main_simplest_app-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="main_simplest_app.dart content, created by dsibinski on 02:13AM on January 13, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="main_simplest_app.dart">
        <tr>
          <td id="file-main_simplest_app-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-main_simplest_app-dart-LC1" class="blob-code blob-code-inner js-file-line">import &#39;package:flutter/material.dart&#39;;</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-main_simplest_app-dart-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-main_simplest_app-dart-LC3" class="blob-code blob-code-inner js-file-line">void main() =&gt; runApp(</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-main_simplest_app-dart-LC4" class="blob-code blob-code-inner js-file-line">      Center(</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-main_simplest_app-dart-LC5" class="blob-code blob-code-inner js-file-line">          child: Text(</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-main_simplest_app-dart-LC6" class="blob-code blob-code-inner js-file-line">        &quot;Hello Flutter!&quot;,</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-main_simplest_app-dart-LC7" class="blob-code blob-code-inner js-file-line">        textDirection: TextDirection.ltr,</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-main_simplest_app-dart-LC8" class="blob-code blob-code-inner js-file-line">      )),</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-main_simplest_app-dart-LC9" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/e950a3cd710a539359a855752900c295/raw/23a6fec940a3c5e420ab9483a585f9ea495345d4/main_simplest_app.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/e950a3cd710a539359a855752900c295#file-main_simplest_app-dart" class="Link--inTextBlock">
          main_simplest_app.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">The<span style="color:#bb9d1b" class="tadv-color"> </span><span style="color:#f7bb1e" class="tadv-color">runApp()</span> method takes a <span style="color:#f7bb1e" class="tadv-color">Widget</span> as its argument. In our case, it takes a <span style="color:#f7bb1e" class="tadv-color">Center</span> widget, which has one child &#8211; a <span style="color:#f7bb1e" class="tadv-color">Text</span> widget. As expected, such a simple Flutter app shows a &#8220;Hello Flutter!&#8221; text at the center of the screen.</p>



<p class="wp-block-paragraph">This simple example shows us a few interesting facts:</p>



<ul class="wp-block-list"><li>there are <strong>many built-in widgets</strong>, like <span style="color:#f7bb1e" class="tadv-color">Center</span> and <span style="color:#f7bb1e" class="tadv-color">Text</span></li><li><strong>widgets can have a child or children</strong> &#8211; this is <em>widgets nesting</em> and it happens all the time and can be very deep</li><li>Flutter <strong>widgets can have their own properties</strong>, like <span style="color:#f7bb1e" class="tadv-color">textDirection</span>.</li></ul>



<p class="wp-block-paragraph">Widgets nesting sometimes makes simple Flutter apps having a lot of source code inside a single file. However, as I mentioned in <a rel="noreferrer noopener" aria-label="the previous post (opens in a new tab)" href="https://www.codejourney.net/2019/12/your-first-flutter-app-in-30-minutes/" target="_blank">the previous post</a>, don&#8217;t get discouraged by that <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Actually, <strong>having a lot of nested widgets in Flutter is a good practice</strong>. If you have a few huge widgets without much nesting instead, it means that there&#8217;s something wrong with your implementation. Flutter widgets &#8211; as all reusable pieces of code &#8211; should not have too many responsibilities. <a rel="noreferrer noopener" aria-label="SOLID (opens in a new tab)" href="https://en.wikipedia.org/wiki/SOLID" target="_blank">SOLID</a> also applies here <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Viewing Flutter widgets with Flutter Inspector</h2>



<p class="wp-block-paragraph">As widgets tree may get big and quite heavily nested, there&#8217;s a very useful tool to easily view and explore it. This tool is called <a rel="noreferrer noopener" aria-label="Flutter Inspector (opens in a new tab)" href="https://flutter.dev/docs/development/tools/devtools/inspector" target="_blank">Flutter Inspector</a>.</p>



<p class="wp-block-paragraph">While in debug mode in Visual Studio Code, you can launch it by clicking the blue magnifier icon:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="866" height="174" data-attachment-id="3727" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/image/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?fit=866%2C174&amp;ssl=1" data-orig-size="866,174" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?fit=866%2C174&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?resize=866%2C174&#038;ssl=1" alt="Flutter Widgets: blue magnifier button in VS Code which opens the widgets inspector" class="wp-image-3727" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?w=866&amp;ssl=1 866w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?resize=300%2C60&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?resize=768%2C154&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?resize=676%2C136&amp;ssl=1 676w" sizes="auto, (max-width: 866px) 100vw, 866px" /><figcaption>A button for opening Flutter Widgets Inspector from VS Code</figcaption></figure>



<p class="wp-block-paragraph">It opens in a web browser and allows you to see the whole widgets tree in your app:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="950" height="1025" data-attachment-id="3728" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/image-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?fit=950%2C1025&amp;ssl=1" data-orig-size="950,1025" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?fit=950%2C1025&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?resize=950%2C1025&#038;ssl=1" alt="Flutter Widgets: Dart DevTools widgets inspector" class="wp-image-3728" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?w=950&amp;ssl=1 950w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?resize=278%2C300&amp;ssl=1 278w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?resize=768%2C829&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?resize=676%2C729&amp;ssl=1 676w" sizes="auto, (max-width: 950px) 100vw, 950px" /><figcaption>Flutter Inspector (part of Dart DevTools)</figcaption></figure>



<p>There&#8217;s a very handy feature &#8220;Select Widget Mode&#8221; which, when enabled, lets you select the widgets directly in your emulator or phone. After doing this, you can see the selected widget&#8217;s properties in the inspector.</p>



<h2 class="wp-block-heading" id="flutter-widget-types">Types of Flutter widgets</h2>



<p class="wp-block-paragraph">In Flutter, you can &#8211; and will &#8211; create your own widgets. Widget is just a Dart class which extends a proper base class. Depending on whether your widget actually manages any state and changes over time, you have two types of base classes to inherit from &#8211; <a rel="noreferrer noopener" aria-label="StatelessWidget (opens in a new tab)" href="https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html" target="_blank">StatelessWidget</a> or <a rel="noreferrer noopener" aria-label="StatefulWidget (opens in a new tab)" href="https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html" target="_blank">StatefulWidget</a>.</p>



<p class="wp-block-paragraph">The main purpose of each type of widget is to provide an implementation of a <span style="color:#f7bb1e" class="tadv-color">build() </span>method which returns a <span style="color:#f7bb1e" class="tadv-color">Widget</span> object. However, each widget type does it a bit differently. Let&#8217;s see this in action.</p>



<h3 class="wp-block-heading">StatelessWidgets</h3>



<p class="wp-block-paragraph">The simplest widget you can create is a stateless widget. You create it by simply creating a class extending <a rel="noreferrer noopener" href="https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html" target="_blank">StatelessWidget</a>.  Here&#8217;s the sample source code and a view it generates:</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-embed alignwide"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist100563362" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-main_stateless_widget-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="main_stateless_widget.dart content, created by dsibinski on 03:36AM on January 14, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="main_stateless_widget.dart">
        <tr>
          <td id="file-main_stateless_widget-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-main_stateless_widget-dart-LC1" class="blob-code blob-code-inner js-file-line">import &#39;package:flutter/material.dart&#39;;</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-main_stateless_widget-dart-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-main_stateless_widget-dart-LC3" class="blob-code blob-code-inner js-file-line">void main() =&gt; runApp(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-main_stateless_widget-dart-LC4" class="blob-code blob-code-inner js-file-line">      MaterialApp(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-main_stateless_widget-dart-LC5" class="blob-code blob-code-inner js-file-line">        title: &quot;My CodeJourney Flutter app&quot;,</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-main_stateless_widget-dart-LC6" class="blob-code blob-code-inner js-file-line">        home: Scaffold(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-main_stateless_widget-dart-LC7" class="blob-code blob-code-inner js-file-line">          appBar: AppBar(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-main_stateless_widget-dart-LC8" class="blob-code blob-code-inner js-file-line">            title: Text(&quot;My First App&quot;),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-main_stateless_widget-dart-LC9" class="blob-code blob-code-inner js-file-line">          ),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-main_stateless_widget-dart-LC10" class="blob-code blob-code-inner js-file-line">          body: MyFirstWidget(),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-main_stateless_widget-dart-LC11" class="blob-code blob-code-inner js-file-line">        ),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-main_stateless_widget-dart-LC12" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-main_stateless_widget-dart-LC13" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-main_stateless_widget-dart-LC14" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-main_stateless_widget-dart-LC15" class="blob-code blob-code-inner js-file-line">class MyFirstWidget extends StatelessWidget {</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-main_stateless_widget-dart-LC16" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-main_stateless_widget-dart-LC17" class="blob-code blob-code-inner js-file-line">  Widget build(BuildContext context) {</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-main_stateless_widget-dart-LC18" class="blob-code blob-code-inner js-file-line">    return Container(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-main_stateless_widget-dart-LC19" class="blob-code blob-code-inner js-file-line">      padding: EdgeInsets.all(8.0),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-main_stateless_widget-dart-LC20" class="blob-code blob-code-inner js-file-line">      child: Text(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-main_stateless_widget-dart-LC21" class="blob-code blob-code-inner js-file-line">        &quot;Hello MyFirstWidget!&quot;,</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-main_stateless_widget-dart-LC22" class="blob-code blob-code-inner js-file-line">        style: TextStyle(color: Colors.green),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-main_stateless_widget-dart-LC23" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-main_stateless_widget-dart-LC24" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-main_stateless_widget-dart-LC25" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-main_stateless_widget-dart-LC26" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/1a26fa1e212adbb858230f62183f7109/raw/28bd7f47b938fc6d295f3700c2550c5efe902b44/main_stateless_widget.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/1a26fa1e212adbb858230f62183f7109#file-main_stateless_widget-dart" class="Link--inTextBlock">
          main_stateless_widget.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image alignwide size-large"><img loading="lazy" decoding="async" width="1080" height="1920" data-attachment-id="3731" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/flutter_statelesswidget/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_statelessWidget" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?fit=576%2C1024&amp;ssl=1" src="https://i1.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?fit=576%2C1024&amp;ssl=1" alt="" class="wp-image-3731" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?w=1080&amp;ssl=1 1080w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=864%2C1536&amp;ssl=1 864w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=676%2C1202&amp;ssl=1 676w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /></figure>


</div>
</div>



<p class="wp-block-paragraph">You can play with it yourself <a rel="noreferrer noopener" aria-label="in the DartPad (opens in a new tab)" href="https://dartpad.dev/1a26fa1e212adbb858230f62183f7109" target="_blank">in the DartPad</a>.</p>



<p class="wp-block-paragraph">There are quite a few new things in the source code. Let&#8217;s point them out:</p>



<ul class="wp-block-list"><li>as our main widget, we used <span style="color:#f7bb1e" class="tadv-color">MaterialApp</span> and provided it to <span style="color:#f7bb1e" class="tadv-color">runApp()</span> method. MaterialApp widget gives us material design for our app out of the box. As soon as you use it, you can nest more material widgets from the <a rel="noreferrer noopener" aria-label="widgets library (opens in a new tab)" href="https://flutter.dev/docs/development/ui/widgets/material" target="_blank">widgets library</a>. There&#8217;s a similar widget for Apple-oriented widgets called <a rel="noreferrer noopener" aria-label="CupertinoApp (opens in a new tab)" href="https://api.flutter.dev/flutter/cupertino/CupertinoApp-class.html" target="_blank">CupertinoApp</a>, which allows using <a rel="noreferrer noopener" aria-label="Cupertino widgets (opens in a new tab)" href="https://flutter.dev/docs/development/ui/widgets/cupertino" target="_blank">Cupertino widgets</a></li><li>we used another material widget &#8211; a <span style="color:#f7bb1e" class="tadv-color">Scaffold</span>. It provides us with an <span style="color:#f7bb1e" class="tadv-color">appBar</span> and <span style="color:#f7bb1e" class="tadv-color">body</span> properties &#8211; setting them we&#8217;re getting this nice-looking application&#8217;s skeleton with entitled app bar and home for our widget. Scaffold also gives us many things &#8220;for free&#8221;, e.g.  <a rel="noreferrer noopener" href="https://api.flutter.dev/flutter/material/FloatingActionButton-class.html" target="_blank">FloatingActionButton</a></li><li><span style="color:#f7bb1e" class="tadv-color">body</span> of our <span style="color:#f7bb1e" class="tadv-color">Scaffold</span> is our first own stateless widget &#8211; <span style="color:#f7bb1e" class="tadv-color">MyFirstWidget</span>. As mentioned before, it overrides the <span style="color:#f7bb1e" class="tadv-color">build()</span> method, which simply returns another widget tree. Notice the usage of a <span style="color:#f7bb1e" class="tadv-color">Container</span> widget, which is very useful for grouping other widgets.</li></ul>



<p class="wp-block-paragraph">StatelessWidget is simple, works and is just there <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Let&#8217;s see something more interesting now &#8211; StatefulWidgets.</p>



<h3 class="wp-block-heading">StatefulWidgets</h3>



<p class="wp-block-paragraph">When you want your widget to change over time and maintain its state (in most cases you do), you can create a stateful widget. You do it by creating a Dart class extending <a rel="noreferrer noopener" aria-label="StatefulWidget (opens in a new tab)" href="https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html" target="_blank">StatefulWidget</a>. Unlike StatelessWidgets, StatefulWidget doesn&#8217;t override the <span style="color:#f7bb1e" class="tadv-color">build()</span> method. Instead, it implements a <span style="color:#f7bb1e" class="tadv-color">createState()</span> method, which creates the initial widget&#8217;s state (see below).</p>



<p class="wp-block-paragraph">Apart from the main widget class, which itself is still &#8220;final&#8221; (or better said &#8211; immutable), you create a class extending <a rel="noreferrer noopener" aria-label="State (opens in a new tab)" href="https://api.flutter.dev/flutter/widgets/State-class.html" target="_blank">State</a>. This class maintains the actual state and it is now who provides the <span style="color:#f7bb1e" class="tadv-color">build()</span> method&#8217;s implementation.</p>



<p class="wp-block-paragraph">Let&#8217;s see the sample code and produced GUI:</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<figure class="wp-block-embed alignwide"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist100605434" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-main_stateful_widget-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="main_stateful_widget.dart content, created by dsibinski on 11:31PM on January 15, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="main_stateful_widget.dart">
        <tr>
          <td id="file-main_stateful_widget-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-main_stateful_widget-dart-LC1" class="blob-code blob-code-inner js-file-line">class MySecondWidget extends StatefulWidget {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-main_stateful_widget-dart-LC2" class="blob-code blob-code-inner js-file-line">  MySecondWidget({Key key}) : super(key: key);</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-main_stateful_widget-dart-LC3" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-main_stateful_widget-dart-LC4" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-main_stateful_widget-dart-LC5" class="blob-code blob-code-inner js-file-line">  _MySecondWidgetState createState() =&gt; </td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-main_stateful_widget-dart-LC6" class="blob-code blob-code-inner js-file-line">                _MySecondWidgetState();</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-main_stateful_widget-dart-LC7" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-main_stateful_widget-dart-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-main_stateful_widget-dart-LC9" class="blob-code blob-code-inner js-file-line">class _MySecondWidgetState extends State&lt;MySecondWidget&gt; {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-main_stateful_widget-dart-LC10" class="blob-code blob-code-inner js-file-line">  int _clickCount = 0;</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-main_stateful_widget-dart-LC11" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-main_stateful_widget-dart-LC12" class="blob-code blob-code-inner js-file-line">  void incrementClickCount() {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-main_stateful_widget-dart-LC13" class="blob-code blob-code-inner js-file-line">    setState(() {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-main_stateful_widget-dart-LC14" class="blob-code blob-code-inner js-file-line">      this._clickCount++;</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-main_stateful_widget-dart-LC15" class="blob-code blob-code-inner js-file-line">    });</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-main_stateful_widget-dart-LC16" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-main_stateful_widget-dart-LC17" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-main_stateful_widget-dart-LC18" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-main_stateful_widget-dart-LC19" class="blob-code blob-code-inner js-file-line">  Widget build(BuildContext context) {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-main_stateful_widget-dart-LC20" class="blob-code blob-code-inner js-file-line">    return Scaffold(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-main_stateful_widget-dart-LC21" class="blob-code blob-code-inner js-file-line">      appBar: AppBar(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-main_stateful_widget-dart-LC22" class="blob-code blob-code-inner js-file-line">        title: Text(&quot;My First App&quot;),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-main_stateful_widget-dart-LC23" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-main_stateful_widget-dart-LC24" class="blob-code blob-code-inner js-file-line">      body: Container(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-main_stateful_widget-dart-LC25" class="blob-code blob-code-inner js-file-line">        padding: EdgeInsets.all(8.0),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-main_stateful_widget-dart-LC26" class="blob-code blob-code-inner js-file-line">        child: Text(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-main_stateful_widget-dart-LC27" class="blob-code blob-code-inner js-file-line">          &quot;Hello! Times clicked: &quot; </td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-main_stateful_widget-dart-LC28" class="blob-code blob-code-inner js-file-line">                + this._clickCount.toString(),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-main_stateful_widget-dart-LC29" class="blob-code blob-code-inner js-file-line">          style: TextStyle(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-main_stateful_widget-dart-LC30" class="blob-code blob-code-inner js-file-line">            color: Colors.green, </td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-main_stateful_widget-dart-LC31" class="blob-code blob-code-inner js-file-line">            fontSize: 20.0),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-main_stateful_widget-dart-LC32" class="blob-code blob-code-inner js-file-line">        ),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-main_stateful_widget-dart-LC33" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-main_stateful_widget-dart-LC34" class="blob-code blob-code-inner js-file-line">      floatingActionButton: FloatingActionButton(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-main_stateful_widget-dart-LC35" class="blob-code blob-code-inner js-file-line">        child: Icon(Icons.add),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-main_stateful_widget-dart-LC36" class="blob-code blob-code-inner js-file-line">        onPressed: this.incrementClickCount,</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-main_stateful_widget-dart-LC37" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-main_stateful_widget-dart-LC38" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-main_stateful_widget-dart-LC39" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L40" class="blob-num js-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-main_stateful_widget-dart-LC40" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/74e2318c87f611ce3b8e2f0dab817567/raw/55cbf4b0cf9f29e6f855c04d36a5a361bad588fc/main_stateful_widget.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/74e2318c87f611ce3b8e2f0dab817567#file-main_stateful_widget-dart" class="Link--inTextBlock">
          main_stateful_widget.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image alignwide size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="576" height="1024" data-attachment-id="3745" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/flutter_statefulwidget-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_statefulWidget-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?fit=576%2C1024&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=576%2C1024&#038;ssl=1" alt="" class="wp-image-3745" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=864%2C1536&amp;ssl=1 864w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=676%2C1202&amp;ssl=1 676w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?w=1080&amp;ssl=1 1080w" sizes="auto, (max-width: 576px) 100vw, 576px" /></figure>
</div>
</div>



<p class="wp-block-paragraph">The full code you can play with is available <a rel="noreferrer noopener" aria-label="in the DartPad (opens in a new tab)" href="https://dartpad.dev/6a140d19910f60d03e8752b1a3b7f083" target="_blank">in the DartPad</a>.</p>



<p class="wp-block-paragraph">Now some comments about the StatefulWidget code:</p>



<ul class="wp-block-list"><li>notice how <span style="color:#f7bb1e" class="tadv-color">MySecondWidget</span> class passes a <span style="color:#f7bb1e" class="tadv-color">key</span> to its superclass. Concept of Flutter widgets keys is interesting and we&#8217;ll dig into it in a separate post. For now, just treat it as a convention to always accept a <span style="color:#f7bb1e" class="tadv-color">key</span> as a named argument and pass it to the base class</li><li>as said before, in this simple example, <span style="color:#f7bb1e" class="tadv-color">MySecondWidget</span> only creates the initial state by instantiating <span style="color:#f7bb1e" class="tadv-color">_MySecondWidgetState</span></li><li>you&#8217;re already familiar with most of the code in <span style="color:#f7bb1e" class="tadv-color">_MySecondWidgetState</span>, but notice the usage of <span style="color:#f7bb1e" class="tadv-color">setState()</span> in <span style="color:#f7bb1e" class="tadv-color">incrementClickCount()</span> function. It tells Flutter that the state has changed, so the framework can re-render the UI. If you directly change the value of <span style="color:#f7bb1e" class="tadv-color">this._clickCount</span> without calling <span style="color:#f7bb1e" class="tadv-color">setState()</span>, GUI will not be updated until <span style="color:#f7bb1e" class="tadv-color">setState()</span> is called in some other place. We&#8217;ll talk more about state management techniques in Flutter in the future articles</li><li>note how easy it is to add a <span style="color:#f7bb1e" class="tadv-color">FloatingActionButton</span> thanks to using <a rel="noreferrer noopener" aria-label="Scaffold (opens in a new tab)" href="https://api.flutter.dev/flutter/material/Scaffold-class.html" target="_blank">Scaffold</a> material widget.</li></ul>



<p class="wp-block-paragraph">That was easy and works nicely! You now know how to use both Flutter widget types <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4aa.png" alt="💪" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Flutter quick actions in VS Code</h2>



<p class="wp-block-paragraph">I&#8217;d like to share with you two easy tips for working with Flutter in Visual Studio Code. Both speed up the development nicely. It assumes that you configured VS Code properly (if not read <a href="https://www.codejourney.net/2019/12/your-first-flutter-app-in-30-minutes/" target="_blank" rel="noreferrer noopener" aria-label="this article (opens in a new tab)">this article</a>) and have Flutter extension installed.</p>



<h3 class="wp-block-heading">Ctrl + .</h3>



<p class="wp-block-paragraph">First important keyboard shortcut is <em>Ctrl</em>+<em>.</em> (<em>Cmd</em>+<em>.</em> on Mac). It allows you to perform many element-contextual actions. For me it&#8217;s most useful for removing widgets or wrapping widgets with other ones:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="3760" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/flutter_quickactions/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?fit=418%2C409&amp;ssl=1" data-orig-size="418,409" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_quickActions" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?fit=418%2C409&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?resize=314%2C307&#038;ssl=1" alt="" class="wp-image-3760" width="314" height="307" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?w=418&amp;ssl=1 418w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?resize=300%2C294&amp;ssl=1 300w" sizes="auto, (max-width: 314px) 100vw, 314px" /><figcaption>Quick Flutter actions in VS Code (Ctrl+.)</figcaption></figure></div>



<h3 class="wp-block-heading">Snippets for widgets creation</h3>



<p class="wp-block-paragraph">Another useful feature are code snippets for creating widgets. You use them by starting to type their acronym in your <em>.dart</em> file. There are two acronyms for widgets creation &#8211; <em>stless</em> for <span style="color:#f7bb1e" class="tadv-color">StatelessWidget</span> and <em>stful</em> for <span style="color:#f7bb1e" class="tadv-color">StatefulWidget</span> scaffolding. The usage looks as follows:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="909" height="327" data-attachment-id="3763" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/flutter_snippets/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?fit=909%2C327&amp;ssl=1" data-orig-size="909,327" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_snippets" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?fit=909%2C327&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?resize=909%2C327&#038;ssl=1" alt="" class="wp-image-3763" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?w=909&amp;ssl=1 909w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?resize=300%2C108&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?resize=768%2C276&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?resize=676%2C243&amp;ssl=1 676w" sizes="auto, (max-width: 909px) 100vw, 909px" /><figcaption>Visual Studio Code &#8211; using Flutter snippets</figcaption></figure></div>



<h2 class="wp-block-heading">Most popular Flutter widgets</h2>



<p class="wp-block-paragraph">I wanted to list you here some most popular Flutter widgets, but they are quite well described <a rel="noreferrer noopener" aria-label="here (opens in a new tab)" href="https://flutter.dev/docs/development/ui/widgets-intro#basic-widgets" target="_blank">here</a>. You can also search through the <a rel="noreferrer noopener" aria-label="widgets library (opens in a new tab)" href="https://flutter.dev/docs/reference/widgets" target="_blank">widgets library</a>. We&#8217;ve also used quite few of them in our examples above <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Community widgets</h2>



<p class="wp-block-paragraph">Many more people are starting to use Flutter and they also create a lot of community widgets. You can find the Dart packages for Flutter on <a rel="noreferrer noopener" aria-label="pub.dev (opens in a new tab)" href="https://pub.dev/" target="_blank">pub.dev</a>. I also recommend checking the <a rel="noreferrer noopener" aria-label="Flutter Awesome website (opens in a new tab)" href="https://flutterawesome.com/" target="_blank">Flutter Awesome website</a> where the best Flutter widgets, libraries and other extensions are listed.</p>



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



<p class="wp-block-paragraph">That&#8217;s it! You&#8217;ve just learned how to use stateless and stateful widgets in Flutter. We&#8217;ve also seen what&#8217;s the difference between them and what are some basic conventions in creating them. There&#8217;s a lot more to Flutter widgets and related topics, but these are topics for separate posts. I hope to publish more of them soon <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">In my opinion, bringing components into the mobile world in the form of widgets is a very nice idea. They give quite a good separation of logic and GUI management. For sure it&#8217;s a fresh start, totally changing the way in which we think about mobile apps development. Components have done their job in the web world, so why would widgets not succeed in mobile apps? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> We&#8217;ll see!</p>



<p class="wp-block-paragraph">What do you think? If you are interested in some particular topics related to Flutter &#8211; let me know! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>


<p>The post <a href="https://www.codejourney.net/basics-of-flutter-widgets/">Basics of Flutter Widgets</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/basics-of-flutter-widgets/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3715</post-id>	</item>
		<item>
		<title>Your First Flutter App in 30 Minutes</title>
		<link>https://www.codejourney.net/your-first-flutter-app-in-30-minutes/</link>
					<comments>https://www.codejourney.net/your-first-flutter-app-in-30-minutes/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Wed, 04 Dec 2019 17:26:31 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[dart]]></category>
		<category><![CDATA[flutter]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3652</guid>

					<description><![CDATA[<p>You may know my past affair with Xamarin, which somehow died a natural death. In today&#8217;s post, we&#8217;re taking a look at Flutter. If you want to know what is Flutter and how to build your first Flutter app in less than 30 minutes (including installation time) &#8211; let&#8217;s jump right into it 😉 What&#8230;</p>
<p>The post <a href="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/">Your First Flutter App in 30 Minutes</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
			