<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Dmitriy Stepanenko</title>
    <description>The latest articles on Forem by Dmitriy Stepanenko (@dmitriy_stepanenko).</description>
    <link>https://forem.com/dmitriy_stepanenko</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F904824%2F1e434025-d40a-4065-9ff3-7192c6ee561d.jpeg</url>
      <title>Forem: Dmitriy Stepanenko</title>
      <link>https://forem.com/dmitriy_stepanenko</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dmitriy_stepanenko"/>
    <language>en</language>
    <item>
      <title>Qwik reaches the v1, so does qwik-nx!</title>
      <dc:creator>Dmitriy Stepanenko</dc:creator>
      <pubDate>Wed, 03 May 2023 13:55:30 +0000</pubDate>
      <link>https://forem.com/valorsoftware/qwik-reaches-the-v1-so-does-qwik-nx-3l6e</link>
      <guid>https://forem.com/valorsoftware/qwik-reaches-the-v1-so-does-qwik-nx-3l6e</guid>
      <description>&lt;p&gt;A lot has happened since we &lt;a href="https://dev.to/valorsoftware/introducing-qwik-integration-for-nx-1k5b"&gt;introduced&lt;/a&gt; the &lt;a href="https://github.com/qwikifiers/qwik-nx"&gt;qwik-nx&lt;/a&gt;, an official plugin for the Qwik framework. As Qwik breaks free by reaching the v1, we’re happy to announce the release of the stable version of the Nx integration for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few words about Qwik
&lt;/h2&gt;

&lt;p&gt;Qwik is referred to as a next-generation framework because of its revolutionary new approaches to performance optimization, among which:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript Streaming&lt;/strong&gt; - an ability to load and execute only the bare minimum of the code as Qwik analyses and splits your code into chunks up to a function level. Those chunks are prefetched in a separate thread, similar to "buffering" in video streaming. The prefetched code only executes upon user action;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;resumability&lt;/strong&gt; - a new rendering paradigm to bring you instantly interactive apps by serializing/deserializing your app as it goes from SSR to client without the need for hydration;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practise this means that you get an app with O(1) size, as its initial bundle is constant at about 1kb no matter the application complexity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s1B6B03X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ss6jtxhl0u52n22ajj89.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s1B6B03X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ss6jtxhl0u52n22ajj89.png" alt="Initial bundle size on content size" width="683" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is extremely beneficial for enterprise companies, that usually want to bring an enormous amount of functionality to their users without any performance impact. &lt;/p&gt;

&lt;p&gt;While Qwik helps to scale the application's functionality expressed via code without effort, Nx is there to make sure your &lt;strong&gt;codebase&lt;/strong&gt; can be managed at any scale. And here's where qwik-nx comes into play. It provides the same experience of the generation and execution of Qwik applications in an Nx workspace that fits the standards of other Nx projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new?
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/valorsoftware/introducing-qwik-integration-for-nx-1k5b"&gt;the previous article&lt;/a&gt;, we have talked about how you get started by initializing your Nx repository with Qwik. &lt;/p&gt;

&lt;p&gt;Recap: you can generate a new workspace by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-nx-workspace@latest org-workspace --preset=qwik-nx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or add a new Qwik application to an existing workspace by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D qwik-nx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nx generate qwik-nx:app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Today let's talk about what new opportunities does it offer:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;qwikNxVite&lt;/code&gt; plugin
&lt;/h3&gt;

&lt;p&gt;If you stick to using Qwik with Nx from its first days, you might have noticed that importing Qwik components from libraries does not work out of the box as all those dependencies should be configured as &lt;code&gt;vendorRoots&lt;/code&gt; for &lt;code&gt;qwikVite&lt;/code&gt; plugin in order for Qwik Optimizer to actually include and process them. &lt;/p&gt;

&lt;p&gt;The good news is you don't have to do it manually any more: &lt;code&gt;qwikNxVite&lt;/code&gt; plugin will by default analyze the Nx dependency graph and put all libraries your app uses as vendorRoots for the Qwik Optimizer to consume.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// vite.config.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;qwikNxVite&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;qwik-nx/plugins&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;qwikNxVite&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;= that's all you need!&lt;/span&gt;
    &lt;span class="nx"&gt;qwikCity&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;qwikVite&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;tsconfigPaths&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this behavior can be fine-tuned even further to make sure you're including only what's intended. As an example, you can mark all Qwik-specific libraries with a specific tag and filter your vendorRoots with it. Let's see how you can leverage the usage of &lt;code&gt;"framework:qwik"&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;1) Mark libs you need with the respective tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;some&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lib's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;project.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"type:ui"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scope:products"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"framework:qwik"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Configure the plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app's vite.config.ts&lt;/span&gt;
&lt;span class="nx"&gt;qwikNxVite&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
  &lt;span class="c1"&gt;// filter out all projects that does not have this tag&lt;/span&gt;
  &lt;span class="c1"&gt;// use "tags", "name", "path" regex &lt;/span&gt;
  &lt;span class="c1"&gt;// or even "customFilter" to achieve desired filtering logic&lt;/span&gt;
  &lt;span class="na"&gt;includeProjects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;framework:qwik&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="nl"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;= put this to see what projects are included&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration will make &lt;code&gt;qwikNxVite&lt;/code&gt; plugin to load only libraries that have respective tag AND are recognized by Nx as your app's dependency.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pro tip
&lt;/h4&gt;

&lt;p&gt;You can configure the Nx Console to always put the tag you want as a default value for the &lt;code&gt;tags&lt;/code&gt; field for the &lt;code&gt;qwik-nx:library&lt;/code&gt; generator. This can be achieved by setting that default value in the &lt;a href="https://nx.dev/reference/nx-json#generators"&gt;build options of nx.json&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generators"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"qwik-nx:library"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"framework:qwik"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uA44TWiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1r4yvei1mp9egs5r2gcv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uA44TWiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1r4yvei1mp9egs5r2gcv.png" alt="Generating library with Nx Console" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic versions migrations
&lt;/h3&gt;

&lt;p&gt;One of the biggest benefits of using Nx to manage the codebase is their seamless migration process: with a single command &lt;code&gt;nx migrate latest&lt;/code&gt; Nx CLI will analyze the workspace and provide the set of migrations written by Nx team to update versions of your dependencies and mutate all necessary bits of code. This is a great capability that allows large codebases to always stay up to date without investing weeks of refactoring.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;qwik-nx&lt;/code&gt; aims to provide the same feature for its users to make sure your Qwik apps are updated. This means you don't have to update the app's dependencies manually anymore, just run &lt;br&gt;
&lt;code&gt;nx migrate qwik-nx@latest&lt;/code&gt; and you are done: it will update all breaking changes and bump versions of Qwik packages.&lt;/p&gt;
&lt;h3&gt;
  
  
  React integration
&lt;/h3&gt;

&lt;p&gt;Qwik &lt;a href="https://qwik.builder.io/docs/integrations/react/"&gt;offers a great capability&lt;/a&gt; to &lt;code&gt;qwikify$&lt;/code&gt; React components - reuse existing React components and libraries within Qwik applications. Not only does this open the world of using existing UI libraries (Material UI, Threejs, React Spring, etc.) and utilities that were developed for React over time within Qwik applications, but also this turns out to be a powerful &lt;strong&gt;migration strategy&lt;/strong&gt;, as you can migrate your existing React applications chunk by chunk, preserving large parts of functionality in the old syntax without a need to rewrite everything at once.&lt;/p&gt;

&lt;p&gt;As React and Qwik components can not be mixed in the same file, if you check your project right after adding React integration to a plain Qwik app, you will see a new folder &lt;code&gt;src/integrations/react/&lt;/code&gt;, and its recommended to place all React components there.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;qwik-nx&lt;/code&gt; gives you more control over structuring your "qwikified" react code by defining 2 approaches for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use a &lt;code&gt;react-in-app&lt;/code&gt; generator, that behaves in the same manner as native Qwik integration. It will add integrations/react folder in the existing Qwik app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;react-library&lt;/code&gt; generator, which will create a separate library to keep qwikified components in it. This means you can now structure your React code as you need and still be able to use it within Qwik apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the Qwik repository there're opened PRs for Angular, Vue and Svelte integrations. As soon as they're available, you will also be able to generate separate libraries for components of those frameworks.&lt;/p&gt;
&lt;h3&gt;
  
  
  Storybook integration
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;qwik-nx&lt;/code&gt; now supports adding storybooks for your apps and libs! We get you covered in all scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run &lt;code&gt;nx g qwik-nx:storybook-configuration&lt;/code&gt; to add storybook to your existing libs and apps&lt;/li&gt;
&lt;li&gt;generate a new library with a preconfigured storybook and stories for newly generated components by running &lt;code&gt;nx g qwik-nx:library mylib --storybookConfiguration&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;add a new component along with a story for it by running &lt;code&gt;nx g qwik-nx:component --generateStories&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Deployments
&lt;/h3&gt;

&lt;p&gt;Qwik offers a variety of ways to deploy your app with its CLI, such as Netlify, Cloudflare Pages, Azure, Vercel, etc. With qwik-nx, we already provide support for Cloudflare Pages with Netlify and other integrations on their way.&lt;/p&gt;

&lt;p&gt;To try it out, all you have to do is run &lt;code&gt;nx g qwik-nx:cloudflare-pages-integration myapp&lt;/code&gt;. This will create a Cloudflare adapter and add necessary targets to preview and deploy your website with Wrangler (Cloudflare CLI tool).&lt;/p&gt;
&lt;h3&gt;
  
  
  Build executor
&lt;/h3&gt;

&lt;p&gt;As you probably know, Qwik builds your code twice, running a client build first and an SSR one after that. In the Nx world, each step of the process is supposed to be a separate target of the application, so that you can keep full control of what you're building. &lt;/p&gt;

&lt;p&gt;To achieve this, we're exposing real build steps and wrapping them into our custom build executor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
 &lt;/span&gt;&lt;span class="nl"&gt;"targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"executor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qwik-nx:build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"runSequence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="s2"&gt;"myapp:build.client"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
          &lt;/span&gt;&lt;span class="s2"&gt;"myapp:build.ssr"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outputPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/apps/myapp"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"build.client"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"executor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@nrwl/vite:build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outputPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/apps/myapp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"configFile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apps/myapp/vite.config.ts"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"build.ssr"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"executor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@nrwl/vite:build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outputPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/apps/myapp"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cool thing with this build executor is that you can customize and add additional targets to the build process if that's needed. For example, you can add "myapp:i18n" target to the &lt;code&gt;runSequence&lt;/code&gt; property in order to process your translations after building the app.&lt;/p&gt;

&lt;p&gt;Oh, and keep in mind that &lt;code&gt;build&lt;/code&gt; executor has another important purpose: it runs type checks for your app before building it!&lt;/p&gt;

&lt;h3&gt;
  
  
  Micro frontends
&lt;/h3&gt;

&lt;p&gt;Qwik is able to render &lt;a href="https://qwik.builder.io/docs/advanced/containers/"&gt;multiple application instances&lt;/a&gt; within the page as it can be attached to an HTML element, that becomes the root of the application. Inspired by &lt;a href="https://blog.cloudflare.com/better-micro-frontends/"&gt;this awesome article&lt;/a&gt;, we've added micro-frontend support to the Qwik apps. As of now this functionality is in beta&lt;/p&gt;

&lt;p&gt;The intent is to bring the same level of convenience as what you get with Nx's tooling to generate and run &lt;a href="https://nx.dev/recipes/module-federation/module-federation-with-ssr"&gt;Module Federation setup&lt;/a&gt; with React and Angular. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;qwik-nx&lt;/code&gt; provides all necessary generators and executors to use it with ease. &lt;/p&gt;

&lt;p&gt;To get started, run the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nx g qwik-nx:host shell --remotes=products,settings&lt;/code&gt;, which will scaffold the host application and 2 remotes for it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nx g qwik-nx:remote myanotherremote --host=shell&lt;/code&gt; to add a new remote application to your existing setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is it! You can now run either &lt;code&gt;nx serve shell&lt;/code&gt; or &lt;code&gt;nx preview shell&lt;/code&gt; and see both host and remotes built and served together. This is because &lt;code&gt;qwik-nx&lt;/code&gt;'s executors for serve and preview are able to process all remotes for you with 0 configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Excited? Go try it out!
&lt;/h3&gt;

&lt;p&gt;The package already provides a solid way of working with Qwik applications within Nx workspaces. Our main goal is to eventually reach feature parity with Qwik CLI.&lt;/p&gt;

&lt;p&gt;So feel free to try it out and let us know how it works out for you! &lt;/p&gt;

&lt;p&gt;You are welcome to join the &lt;a href="https://discord.gg/ndsMfSdR"&gt;Qwikifiers&lt;/a&gt; and &lt;a href="https://discord.gg/nM8hQ7yr"&gt;Qwik&lt;/a&gt; Discord servers to keep track of any updates or find any help you need. &lt;/p&gt;

&lt;p&gt;We are also looking forward to see any new contributions to the package itself &lt;a href="https://github.com/qwikifiers/qwik-nx"&gt;https://github.com/qwikifiers/qwik-nx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last but not least, we'd like to extend a heartfelt thank you to &lt;a href="https://twitter.com/ryanhutchison"&gt;Ryan Hutchison&lt;/a&gt; and &lt;a href="https://www.asicentral.com/"&gt;ASI Central&lt;/a&gt; for their unwavering support of our project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Need Help?
&lt;/h3&gt;

&lt;p&gt;At Valor Software, we are passionate about staying at the forefront of technology and are integration partners with the creators of Qwik, Builder.io. If you have any questions or need assistance with your project, don't hesitate to contact us at &lt;a href="mailto:sales@valor-software.com"&gt;sales@valor-software.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>qwik</category>
      <category>nx</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Avoiding common pitfalls with ControlValueAccessors in Angular</title>
      <dc:creator>Dmitriy Stepanenko</dc:creator>
      <pubDate>Sat, 14 Jan 2023 15:55:43 +0000</pubDate>
      <link>https://forem.com/valorsoftware/avoiding-common-pitfalls-with-controlvalueaccessors-in-angular-4m57</link>
      <guid>https://forem.com/valorsoftware/avoiding-common-pitfalls-with-controlvalueaccessors-in-angular-4m57</guid>
      <description>&lt;p&gt;One of the biggest advantages of Angular is the variety of tools and solutions that are brought to developers out of the box. One of them is the &lt;code&gt;@angular/forms&lt;/code&gt; package, which brings the solid experience of working with any kind of UI controls.&lt;br&gt;
But have you ever wondered, how exactly this works under the hood? The only thing that needs to be done in order to tie FormControl with, let's say, a plain input is using a "formControl" binding on the input element, pointing that UI element to the instance of a FormControl.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;[formControl]=&lt;/span&gt;&lt;span class="s"&gt;"ctrl"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And voila, everything works.&lt;/p&gt;

&lt;p&gt;But obviously, there should be a component or directive that Angular uses to make everything happen. And that "something" can be found &lt;a href="https://github.com/angular/angular/tree/main/packages/forms/src/directives" rel="noopener noreferrer"&gt;here&lt;/a&gt;: Angular brings a set of directives like &lt;a href="https://github.com/angular/angular/blob/main/packages/forms/src/directives/default_value_accessor.ts" rel="noopener noreferrer"&gt;default_value_accessor.ts&lt;/a&gt;, &lt;a href="https://github.com/angular/angular/blob/main/packages/forms/src/directives/select_control_value_accessor.ts" rel="noopener noreferrer"&gt;select_control_value_accessor.ts&lt;/a&gt;, &lt;a href="https://github.com/angular/angular/blob/main/packages/forms/src/directives/checkbox_value_accessor.ts" rel="noopener noreferrer"&gt;checkbox_value_accessor.ts&lt;/a&gt;, etc. All of them implement the ControlValueAccessor interface, which, according to docs, &lt;em&gt;"Defines an interface that acts as a bridge between the Angular forms API and a native element in the DOM."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This means any component can be easily defined as a form control by implementing this interface and registering itself as an &lt;code&gt;NG_VALUE_ACCESSOR&lt;/code&gt; provider. In practice, it requires you to define 4 methods:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ControlValueAccessor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;writeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
  &lt;span class="nf"&gt;registerOnChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
  &lt;span class="nf"&gt;registerOnTouched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
  &lt;span class="nf"&gt;setDisabledState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)?:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;*although setDisabledState is optional, there’re only a few rare scenarios when it’s indeed not needed&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To understand how exactly everything works, let’s have a look at the very basic counter component:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;lib-counter&lt;/span&gt; &lt;span class="na"&gt;[formControl]=&lt;/span&gt;&lt;span class="s"&gt;"counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/lib-counter&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Counter Value: {{ counter.value }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6g8tfdf8oago654c5v12.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6g8tfdf8oago654c5v12.gif" alt="CounterComponent UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the code of the component itself:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionStrategy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectorRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;forwardRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ControlValueAccessor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NG_VALUE_ACCESSOR&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;COUNTER_CONTROL_ACCESSOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NG_VALUE_ACCESSOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;useExisting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;forwardRef&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;CounterControlComponent&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;multi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib-counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;button (click)="down()" [disabled]="disabled"&amp;gt;Down&amp;lt;/button&amp;gt;
        {{ value }}
        &amp;lt;button (click)="up()" [disabled]="disabled"&amp;gt;Up&amp;lt;/button&amp;gt;
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;changeDetection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectionStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OnPush&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;COUNTER_CONTROL_ACCESSOR&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterControlComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;ControlValueAccessor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;onTouched&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_cdr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeDetectorRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="nf"&gt;up&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;down&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;registerOnChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;registerOnTouched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onTouched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;setDisabledState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;writeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_cdr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;emitEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emitEvent&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onTouched&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As you see here we’re implementing 4 methods and providing &lt;code&gt;COUNTER_CONTROL_ACCESSOR&lt;/code&gt;. This is needed in order to let Angular know it deals with an instance of a form control.&lt;/p&gt;

&lt;p&gt;So what’s happening with control is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Once FormControl is initialised, it invokes &lt;code&gt;writeValue&lt;/code&gt;, &lt;code&gt;registerOnChange&lt;/code&gt; and &lt;code&gt;registerOnTouched&lt;/code&gt; methods on the counter component. This syncs the initial state of the FormControl with our counter and also passes onTouched and onChanged methods into the counter, so it can talk back to the FormControl when the user interacts with it.&lt;/li&gt;
&lt;li&gt;When the value is changed, FormControl invokes the &lt;code&gt;writeValue&lt;/code&gt; method, so counter updates its internal state without triggering the &lt;code&gt;onChange&lt;/code&gt;/&lt;code&gt;onTouched&lt;/code&gt; methods.&lt;/li&gt;
&lt;li&gt;When the user interacts with our counter, it’s required to not only update the internal state but also notify parent FormControl about this state change, thus &lt;code&gt;onChange&lt;/code&gt;/&lt;code&gt;onTouched&lt;/code&gt; methods are invoked.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Although that’s not really a lot going on here, it is worth taking a look at a few important implementation details. And this is actually what this article is about&lt;/p&gt;

&lt;h2&gt;
  
  
  Common pitfalls with CVAs and how to avoid them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;onChange&lt;/code&gt; should be only triggered by an internal event
&lt;/h3&gt;

&lt;p&gt;It’s important to keep in mind that these methods should only be used to notify FormControl about the change that was triggered in the component internally. In other words, if FormControl changes the value of the component, it should never notify FormControl back about this change. This is a quite common mistake as it won’t break anything at the first glance, instead you’ll be able to notice it by subscribing to &lt;code&gt;valueChanges&lt;/code&gt; of the bound FormControl:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;rabbit&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;ctrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueChanges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;hare&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the normal scenario by executing the code above you will see only 2 logs: ‘hare’, ‘cat’. However, if your &lt;code&gt;writeValue&lt;/code&gt; method ends up invoking &lt;code&gt;onChange&lt;/code&gt; you will see doubled console logs in the output: ‘hare’, ’hare’, ‘cat’, ‘cat’.&lt;/p&gt;

&lt;p&gt;Here’s a modified code of &lt;code&gt;CounterComponent&lt;/code&gt; where this issue can be seen, when FormControl invokes &lt;code&gt;writeValue&lt;/code&gt; we notify it back with the &lt;code&gt;onChange&lt;/code&gt; method:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// ... code of CounterComponent&lt;/span&gt;
&lt;span class="nf"&gt;writeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// it's convenient to reuse existing "setValue" method, right?&lt;/span&gt;
    &lt;span class="c1"&gt;// however, this will lead to the incorrect behavior&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_cdr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onTouched&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;onChange&lt;/code&gt; and &lt;code&gt;onTouched&lt;/code&gt; should not always be called together
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;onChange&lt;/code&gt;/&lt;code&gt;onTouched&lt;/code&gt; methods actually serve completely different purposes. While &lt;code&gt;onChange&lt;/code&gt; is used to pass data when a component’s state changed internally, &lt;code&gt;onTouched&lt;/code&gt; should be invoked after the user interacts with the component. This doesn’t always mean the component’s value is changed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onTouched&lt;/code&gt; method is used in 2 cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;by FormControl to update its &lt;code&gt;touched&lt;/code&gt; state&lt;/li&gt;
&lt;li&gt;when you set up your control to use &lt;code&gt;updateOn: “blur"&lt;/code&gt; &lt;a href="https://angular.io/api/forms/AbstractControl#updateOn" rel="noopener noreferrer"&gt;https://angular.io/api/forms/AbstractControl#updateOn&lt;/a&gt;, FormControl uses it to properly identify this blur event to apply the value to itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the CounterComponent both touch and change events are combined because the only way to interact with it is by clicking the button. However, with other components, the flow will be different. For instance, a plain &lt;code&gt;&amp;lt;input /&amp;gt;&lt;/code&gt; element with a tied FormControl (with DefaultValueAccessor under the hood) is expected to be marked as touched when the user interacts with the input even by focusing it. Thus, for this kind of components onTouched emission should be tied to the &lt;code&gt;blur&lt;/code&gt; event from the input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ipzapmhtadfgh8e9hjy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ipzapmhtadfgh8e9hjy.gif" alt="value &amp;amp; state changes"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Handling nulls properly
&lt;/h3&gt;

&lt;p&gt;With an introduction of typed forms, form controls can now either infer a type from the default value or be typed explicitly. There’s an interesting thing, though: if we define a control &lt;code&gt;const control = new FormControl&amp;lt;string&amp;gt;()&lt;/code&gt; and then check its type, it will be &lt;code&gt;string | null&lt;/code&gt;. And you might wonder: why does the type of this control include &lt;code&gt;null&lt;/code&gt;? This is because the control can become null at any time, by calling the &lt;code&gt;reset()&lt;/code&gt; method on it. Here’s an example from angular docs:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;control&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// null&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Although this becomes quite obvious with typed forms, this behavior was inherent in forms from the very beginning. And while new handy types may catch issues with control’s values, it doesn’t really save you from any issues with nulls inside your CVA. Moreover, since CVA component doesn’t have any control over the form it’s being used within and there’s no way to enforce certain types of control on the form, it’s possible to actually pass literally any value into the control. Hence this value will end up passing into the &lt;code&gt;writeValue&lt;/code&gt;, which can potentially break your component.&lt;/p&gt;

&lt;p&gt;Let’s change our CounterComponent as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// ... code of CounterComponent&lt;/span&gt;
&lt;span class="nf"&gt;writeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// it's convenient to reuse existing "setValue" method, right?&lt;/span&gt;
    &lt;span class="c1"&gt;// however, this will lead to the incorrect behavior&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_cdr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markForCheck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;emitEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emitEvent&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onTouched&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl3yuhojj7bzqon5b1vg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl3yuhojj7bzqon5b1vg.gif" alt="behavior with and without null handling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CounterComponent is too simple to have big issues with null because JavaScript will cast null into 0 (&lt;code&gt;null + 1 = 1&lt;/code&gt;), but as you can see component is visually broken after &lt;code&gt;reset()&lt;/code&gt; is called. So it’s very important to keep in mind this behavior and implement some value protections for the &lt;code&gt;writeValue&lt;/code&gt; method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standardising your custom UI form components with ControlValueAccessor Test Suite
&lt;/h2&gt;

&lt;p&gt;Even if you keep in mind all the potential pitfalls listed above, there’s always a chance something will go wrong due to some change or enhancement in the future. The best way to maintain the valid behavior of a component is to have extensive unit test coverage. However, it might be annoying to write the same list of tests for all CVA components or some use cases can be accidentally left without coverage. So it should be much better to have one unified testing solution, that can keep your components safe.&lt;/p&gt;

&lt;p&gt;And there’s one called &lt;a href="https://github.com/dmitry-stepanenko/ngx-cva-test-suite" rel="noopener noreferrer"&gt;ngx-cva-test-suite&lt;/a&gt;. It’s a small npm package, that provides an extensive set of test cases, ensuring your custom controls behave as intended. It is designed and tested to work properly with both Jest and Jasmine test runners.&lt;/p&gt;

&lt;p&gt;Among the main features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ensures the correct amount of calls for the &lt;code&gt;onChange&lt;/code&gt; function (incorrect usage may result in extra emissions of &lt;code&gt;valueChanges&lt;/code&gt; of formControl)&lt;/li&gt;
&lt;li&gt;ensures correct triggering of &lt;code&gt;onTouched&lt;/code&gt; function (is needed for touched state of the control and &lt;code&gt;updateOn: 'blur'&lt;/code&gt; &lt;a href="https://angular.io/api/forms/AbstractControl#updateOn" rel="noopener noreferrer"&gt;strategy&lt;/a&gt; to function properly)&lt;/li&gt;
&lt;li&gt;ensures that no extra emissions are present when control is disabled&lt;/li&gt;
&lt;li&gt;checks for control to be resettable using &lt;code&gt;AbstractControl.reset()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is quite easy to be configured, here’s the usage scenario for the CounterComponent we looked into within this article:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;runValueAccessorTests&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ngx-cva-test-suite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CounterControlComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./counter.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;runValueAccessorTests&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="cm"&gt;/** Component, that is being tested */&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CounterControlComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/** 
     * All the metadata required for this test to run. 
     * Under the hood calls TestBed.configureTestingModule with provided config.
     */&lt;/span&gt;
    &lt;span class="na"&gt;testModuleMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;declarations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CounterControlComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="cm"&gt;/** Whether component is able to track "onBlur" events separately */&lt;/span&gt;
    &lt;span class="na"&gt;supportsOnBlur&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/** 
     * Tests the correctness of an approach that is used to set value in the component, 
     * when the change is internal. It's optional and can be omitted by passing "null"
     */&lt;/span&gt;
    &lt;span class="na"&gt;internalValueChangeSetter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/** Function to get the value of a component in a runtime. */&lt;/span&gt;
    &lt;span class="na"&gt;getComponentValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fixture&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fixture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;componentInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/** When component is reset by FormControl, it should either get a certain default internal value or "null" */&lt;/span&gt;
    &lt;span class="na"&gt;resetCustomValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="cm"&gt;/** 
     * This test suite applies up to 3 different values on the component to test different use cases. 
     * Values can be customized using this configuration option.
     */&lt;/span&gt;
    &lt;span class="na"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can learn more about usage examples in the &lt;a href="https://github.com/dmitry-stepanenko/ngx-cva-test-suite#readme" rel="noopener noreferrer"&gt;package’s repository&lt;/a&gt; or get inspiration by looking at a few CVA components that are placed &lt;a href="https://github.com/dmitry-stepanenko/ngx-cva-test-suite/tree/master/apps/integration/src/app/controls" rel="noopener noreferrer"&gt;within the repository here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>forms</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Introducing Qwik integration for Nx</title>
      <dc:creator>Dmitriy Stepanenko</dc:creator>
      <pubDate>Fri, 30 Dec 2022 14:00:55 +0000</pubDate>
      <link>https://forem.com/valorsoftware/introducing-qwik-integration-for-nx-1k5b</link>
      <guid>https://forem.com/valorsoftware/introducing-qwik-integration-for-nx-1k5b</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;While the Qwik framework itself confidently continues its way to v1, it feels like an exactly right time to introduce the Nx plugin for it, which is named &lt;a href="https://github.com/qwikifiers/qwik-nx" rel="noopener noreferrer"&gt;qwik-nx&lt;/a&gt;. The main functionality that this plugin provides is the generation and execution of Qwik applications in an Nx workspace that fits the standards of other Nx applications. &lt;br&gt;
Since Qwik itself uses Vite as a build tool, this Nx plugin leverages the functionality of the brand new &lt;code&gt;@nrwl/vite&lt;/code&gt; package to build and run your Qwik applications. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;The first thing to be done in order to get started is to generate an Nx workspace. &lt;code&gt;qwik-nx&lt;/code&gt; plugin is one of the first that uses Nx’s custom interactive presets, so all you need to do is simply run &lt;code&gt;npx create-nx-workspace@latest --preset=qwik-nx&lt;/code&gt;. You will firstly be prompted with generic questions like what workspace name to use and whether to enable Nx Cloud and after short initialization it will proceed with Qwik specific questions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F83vp7h9rhr7i7y5dcmxw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F83vp7h9rhr7i7y5dcmxw.gif" alt="Installation process"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once done, you will end up with a pretty much regular Nx repository with a Qwik application with Qwik city and all relevant dependencies installed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsylghq9m6u2qy2asf0cj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsylghq9m6u2qy2asf0cj.png" alt="Structure of the workspace"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point it is only possible to create a basic app with Qwik City, but we are planning to include all other starters that standard Qwik CLI provides.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating new applications, libraries and components
&lt;/h2&gt;

&lt;p&gt;Upon setting up the workspace, we will get access to a bunch of neat generators that the &lt;code&gt;qwik-nx&lt;/code&gt; plugin has prepared. It’s highly recommended to use Nx console plugins for &lt;a href="https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; and &lt;a href="https://plugins.jetbrains.com/plugin/15000-nx-webstorm" rel="noopener noreferrer"&gt;Webstorm&lt;/a&gt;, since they do the perfect job visualizing all configuration options and actual changes with dry runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generating new apps
&lt;/h3&gt;

&lt;p&gt;In VS Code’s Nx Console by clicking &lt;code&gt;generate =&amp;gt; qwik-nx - application&lt;/code&gt; you will see the following options&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fll30qq7182yk6jj26hos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fll30qq7182yk6jj26hos.png" alt="qwik-nx:application generator options"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Alternatively you can run &lt;code&gt;npx nx generate qwik-nx:application &amp;lt;name&amp;gt;&lt;/code&gt; with the same options you see on the screenshot above. With everything left as-is we will end up with exactly the same application as what was created during the initialization process. &lt;/p&gt;

&lt;p&gt;There is a lot of excitement around tailwind as well, so it is worth mentioning that it’s possible to include tailwind configuration for the app that is being created using the &lt;code&gt;tailwind&lt;/code&gt; option. If you haven’t done so, you can always do it later by running &lt;code&gt;npx nx generate qwik-nx:setup-tailwind –project=&amp;lt;application name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generating libs
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;qwik-nx:library&lt;/code&gt; generator is built upon the standard Nx library generator, so it does pretty much what you would expect from it: there’re generic options for Nx libs along with Qwik specific ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmavh44p4omd405wvs2s4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmavh44p4omd405wvs2s4.png" alt="qwik-nx:library generator options"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Generating components
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;qwik-nx&lt;/code&gt; plugin also provides an ability to qwikly (you got this one, right?) scaffold a new component for your app. All you have to do is run the &lt;code&gt;qwik-nx:component&lt;/code&gt; generator and select the project for the new component to be placed in. It is also highly configurable as per options shown on the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7e3zak2yedi0q207tui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7e3zak2yedi0q207tui.png" alt="qwik-nx:component generator options"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As of now there's no "route" generator, but expect to see it added soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running and building the code
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;qwik-nx&lt;/code&gt; plugin replaces direct invocation of build, serve and test commands with Nx generators to standardize these tasks in a consistent and predictable manner. Plugin relies on executors provided by the &lt;code&gt;@nrwl/vite&lt;/code&gt; package. Here’s the list of commands available for the Qwik application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;serve&lt;/code&gt; - uses &lt;code&gt;@nrwl/vite:dev-server&lt;/code&gt; executor to run the app in the development mode with hot reloads&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt; - uses &lt;code&gt;@nrwl/vite:build&lt;/code&gt; executor to generate the bundle for the client side app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build-ssr&lt;/code&gt; - also uses &lt;code&gt;@nrwl/vite:build&lt;/code&gt; executor to generate code needed for Vite preview server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;preview&lt;/code&gt; - wraps up build commands above in order to run the app simulating production mode &lt;a href="https://qwik.builder.io/docs/getting-started/#running-in-production" rel="noopener noreferrer"&gt;https://qwik.builder.io/docs/getting-started/#running-in-production&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test&lt;/code&gt; - uses &lt;code&gt;@nrwl/vite:test&lt;/code&gt; executor that relies on vitest&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lint&lt;/code&gt; - just a regular &lt;code&gt;@nrwl/linter:eslint&lt;/code&gt; executor &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Nx by itself is an awesome tool with great capabilities of managing code in distributed fashion with one or more applications in the repository. With the &lt;code&gt;qwik-nx&lt;/code&gt; plugin, Qwik applications and libraries can fit seamlessly into an Nx monorepo, making it easier for developers to achieve their goals. &lt;br&gt;
Being focused on speed and performance, Qwik framework promises to be the next revolutionary solution in web development. As we move forward, &lt;code&gt;qwik-nx&lt;/code&gt; plugin will evolve and become more capable and feature-rich as Qwik itself does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need Help?
&lt;/h2&gt;

&lt;p&gt;At Valor Software, we are passionate about staying at the forefront of technology and are integration partners with the creators of Qwik, Builder.io. If you have any questions or need assistance with your project, don't hesitate to contact us at &lt;a href="mailto:sales@valor-software.com"&gt;sales@valor-software.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>qwik</category>
      <category>nx</category>
      <category>javascript</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
