<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: YPChen</title>
    <description>The latest articles on DEV Community by YPChen (@allieschen).</description>
    <link>https://dev.to/allieschen</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%2F862663%2F9cb2534f-4e93-4e70-a739-f03abd7291fc.png</url>
      <title>DEV Community: YPChen</title>
      <link>https://dev.to/allieschen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/allieschen"/>
    <language>en</language>
    <item>
      <title>Behind `NoInfer` in TypeScript</title>
      <dc:creator>YPChen</dc:creator>
      <pubDate>Wed, 26 Jun 2024 16:23:33 +0000</pubDate>
      <link>https://dev.to/allieschen/behind-noinfer-in-typescript-319</link>
      <guid>https://dev.to/allieschen/behind-noinfer-in-typescript-319</guid>
      <description>&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: As of now, I have not found documentation that explicitly supports the type inference mechanism discussed in this article. This is based on my understanding and experience with TypeScript. Readers are encouraged to explore further and refer to the official TypeScript documentation for additional information.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;NoInfer&amp;lt;T&amp;gt;&lt;/code&gt; utility type in TypeScript blocks type inference, ensuring types are matched explicitly. It works by using a type parameter T in a way that prevents automatic type inference. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;NoInfer&lt;/code&gt; - the New Utility Type
&lt;/h2&gt;

&lt;p&gt;I recently came across an awesome &lt;a href="https://youtu.be/QSIXYMIJkQg?si=bfmy0VaRT5Y2HfrJ"&gt;video&lt;/a&gt; and &lt;a href="https://www.totaltypescript.com/noinfer"&gt;article&lt;/a&gt; by Matt introducing the &lt;code&gt;NoInfer&lt;/code&gt; utility type and its mechanism.&lt;/p&gt;

&lt;p&gt;According to Matt's article and video, a self-implemented version of &lt;code&gt;NoInfer&lt;/code&gt; is:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NoInfer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;any&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;never&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wondered why this works?&lt;/p&gt;

&lt;h2&gt;
  
  
  Dive in with Examples
&lt;/h2&gt;

&lt;p&gt;I asked my friend Jiar, and he explained that it has to do with TypeScript's type inference mechanism. What &lt;code&gt;NoInfer&lt;/code&gt; does is to block the type inference. He gave me &lt;a href="https://www.typescriptlang.org/play/?ts=5.0.4&amp;amp;ssl=16&amp;amp;ssc=2&amp;amp;pln=1&amp;amp;pc=1#code/C4TwDgpgBAcg9gSQHYDMICcA8AVAfFAXigG1sBdUqCAD2AiQBMBnKAQyRCgH4oAGKAFxQkEAG4YyAbgBQ0lAFckAY2ABLOEih0mweMjRZsVWvWZQd6VUgDmuABSt01pkOzEyAGmGJUGAIJOLrA+Bji4AJRCAEZwcAA2EOxQAN7SUOlQ6BDA8uiajs4AdFZKcfIMEEx2SCH+geEyAL6y2rq16HZpGcQA5AnATD1ePdZwPZ5d6QD0AFQzUAACAwC0NJAqq+jocOhQM1OTUD1McAC2EADuABZZPdINLZVt+hidGSQ9kHBgCUNHVxA4mBxh5Dp8IN9fqDwkA"&gt;this example&lt;/a&gt;:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NoInfer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;any&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;never&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testNoInfer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;noInferArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NoInfer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;return&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;noInferArgs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;testNoInfer&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="s1"&gt;lets&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;go&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="cm"&gt;/** @ts-expect-error */&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;somewhre&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;testNoInfer&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="s1"&gt;people&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;help&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;people&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Does the Order of the Parameters Matter?
&lt;/h3&gt;

&lt;p&gt;To understand what "blocking" means, let's change the order of the parameters in the &lt;code&gt;testNoInfer&lt;/code&gt; function:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testNoInfer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;noInferArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NoInfer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;return&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;noInferArgs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;testNoInfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="cm"&gt;/** @ts-expect-error */&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;somewhre&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lets&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;go&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="nf"&gt;testNoInfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;people&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;people&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;help&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see, the order doesn't matter-- it still works.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Flash of Inspiration
&lt;/h3&gt;

&lt;p&gt;What if we leave the &lt;code&gt;noInferArgs&lt;/code&gt; argument alone?&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testNoInfer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;noInferArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NoInfer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;return&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;noInferArgs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;testNoInfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;somewhre&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;testNoInfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;people&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No error! I knew it! The type &lt;code&gt;NoInfer&lt;/code&gt; is just the type parameter &lt;code&gt;T&lt;/code&gt; itself!&lt;/p&gt;

&lt;p&gt;So why does defining the other parameter change everything?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In my opinion, the "block" occurs because TypeScript checks the &lt;code&gt;args&lt;/code&gt; with plain &lt;code&gt;T&lt;/code&gt; and then references this &lt;code&gt;T&lt;/code&gt; in the NoInfer type. Therefore, when another parameter is defined with plain &lt;code&gt;T&lt;/code&gt;, TypeScript insists that &lt;code&gt;T&lt;/code&gt; should match what &lt;code&gt;args&lt;/code&gt; received.&lt;/p&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Using Valibot for Recursive Schema Validation</title>
      <dc:creator>YPChen</dc:creator>
      <pubDate>Sun, 12 May 2024 09:16:29 +0000</pubDate>
      <link>https://dev.to/allieschen/using-valibot-for-recursive-schema-validation-15ej</link>
      <guid>https://dev.to/allieschen/using-valibot-for-recursive-schema-validation-15ej</guid>
      <description>&lt;p&gt;&lt;a href="https://valibot.dev/playground/?code=JYWwDg9gTgLgBAKjgQwM5wG5wGZQiOAcg2QBtgAjCGQgbgCh6BjCAO1XgFERlhSBlJgAsApjzgBeTADoOUYKwDmACgDaGaSAUAZEUphDlARgCUAGhljepZSYC6Jhi3bwACmlQB3aABNBo8SkNOQUVdU0dPUUDY3MZLVZdfUMADntHRhgATzAROABVVBEofysAFRy8qQBvejg4YT4fKD0AfgAuAqKS4XLKhnqrPk6NAElWMABXGAAebNyIbDhua1KeAD4BuDAPbygfEelxqdn5kUW4d1QvXzXkTfoAX0ZnDi7iu8OAITQRO5nCh9ejwKrl1pIZBAKAArERMGDKWr1RqkZp6Q4QMAwYBsMjKDSkZAALyyylsknBgJ6AWQJnMdTgQ1InRWfDuZgZO2uewOl12t2ByA5jwyzDYbxaqEmpHgQVkyGwIncUCKyip7LgSMZPGGRGhyFYIgAAiIAB7IcCkETSFggQgc+pcm77TqEIwAJgAzAAWACsADYAOwpe1PUWvCBW6SkCAqSXSmCOIA"&gt;Valibot's playground for the code demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursive Type in TypeScript
&lt;/h2&gt;

&lt;p&gt;TypeScript allows defining recursive types. For example, consider the following &lt;code&gt;User&lt;/code&gt; interface:&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;h2&gt;
  
  
  Using Valibot for Schema Validation
&lt;/h2&gt;

&lt;p&gt;What if you use a schema library, like &lt;a href="https://zod.dev/"&gt;Zod&lt;/a&gt; or &lt;a href="https://valibot.dev/"&gt;Valibot&lt;/a&gt;? The schema has been built on value-level, and you cannot assign the variant to its property inside the declaration.&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;v&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;valibot&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;EmailSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minLength&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="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&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;PasswordSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minLength&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="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)]);&lt;/span&gt;
&lt;span class="c1"&gt;// const UserSchema?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Recursive Schema
&lt;/h3&gt;

&lt;p&gt;Base on the Author's reply in &lt;a href="https://lnkd.in/gs-s3puw"&gt;this issue&lt;/a&gt;, you can use &lt;code&gt;v.lazy(() =&amp;gt; UserSchema)&lt;/code&gt; and to create a type of the &lt;code&gt;UserSchema&lt;/code&gt; as a type param to the &lt;code&gt;v.BaseSchema&lt;/code&gt; genre as a type inference of the &lt;code&gt;UserSchema&lt;/code&gt;:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;UserSchemaType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;UserSchemaType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;EmailSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;PasswordSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;UserSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BaseSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserSchemaType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
 &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lazy&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;UserSchema&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
 &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EmailSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PasswordSchema&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;



</description>
      <category>typescript</category>
      <category>demo</category>
      <category>valibot</category>
    </item>
    <item>
      <title>Deploy a Golang serverless function for a demo form with htmx</title>
      <dc:creator>YPChen</dc:creator>
      <pubDate>Sat, 30 Mar 2024 13:24:39 +0000</pubDate>
      <link>https://dev.to/allieschen/deploy-a-golang-serverless-function-for-a-demo-form-with-htmx-1hl4</link>
      <guid>https://dev.to/allieschen/deploy-a-golang-serverless-function-for-a-demo-form-with-htmx-1hl4</guid>
      <description>&lt;p&gt;The boilplate I begin with is the production of the tutorial by BugBytes on Youtube in the video: &lt;a href="https://www.youtube.com/watch?v=F9H6vYelYyU"&gt;Golang + HTMX - Creating a Go webserver / HTMX Integration / Template Fragments&lt;/a&gt;. It’s really good and straightforward.&lt;/p&gt;

&lt;p&gt;And I made these changes and will talk about them in this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instead of Booststrap, I used &lt;a href="https://tailwindcss.com/"&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/a&gt; as the CSS library.&lt;/li&gt;
&lt;li&gt;I deployed the project on &lt;a href="https://zeabur.com/"&gt;Zeabur&lt;/a&gt;, which is a personal preference (mainly because it’s free for the demo 😅). However, feel free to choose any similar service that suits your needs.&lt;/li&gt;
&lt;li&gt;I use &lt;a href="https://github.com/go-chi/chi"&gt;go-chi&lt;/a&gt; for handling routes and to server static file(stylesheet).&lt;/li&gt;
&lt;li&gt;I utilized the &lt;a href="https://pkg.go.dev/embed"&gt;&lt;strong&gt;Go embed directive&lt;/strong&gt;&lt;/a&gt; for the serverless plan on Zeabur.&lt;/li&gt;
&lt;li&gt;Additionally, I explored htmx a bit more for reset inputs and animation."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The demo page: &lt;a href="https://yp-go-htmx-simpleform.zeabur.app/"&gt;https://yp-go-htmx-simpleform.zeabur.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repo: &lt;a href="https://github.com/AlliesChen/go-htmx-simpleform/tree/main"&gt;https://github.com/AlliesChen/go-htmx-simpleform/tree/main&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DISCLAIMER: I’m not a GoLang expert, and I’m not yet a backend developer. However, I have experience in front-end development. Any suggestions to improve the structure of the demo or to correct any misunderstandings in this article would be greatly appreciated. 🙏&lt;/p&gt;

&lt;h2&gt;
  
  
  Go:embed for using files in serverless functions
&lt;/h2&gt;

&lt;p&gt;To learn more about serverless functions, you can watch &lt;a href="https://youtu.be/ofgt4r93TE4?si=RGDtalEF24iIeebc"&gt;this video&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Serverless function cannot access the local file system of the server. Therefore, packing static files such as templates and stylesheets is necessary to serve them as part of the response.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As Zeabur is a platform that offers free hosting for serverless functions, the remaining challange will be how to include external files, such as templates or stylesheets, in the code package.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;go:embed&lt;/code&gt;, a feature that enables embedding files into Go binaries, things couldn't be more easier.&lt;/p&gt;

&lt;p&gt;Here is my file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/static
 |— output.css
/templates
 |— index.html
main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the comments:&lt;br&gt;
(PLEASE MAKE SURE NO SPACE BETWEEN THE TWO SLASH AND &lt;code&gt;go:embed&lt;/code&gt; or it won't work)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c"&gt;//go:embed templates&lt;/span&gt;
    &lt;span class="n"&gt;templates&lt;/span&gt; &lt;span class="n"&gt;embed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FS&lt;/span&gt;
    &lt;span class="c"&gt;//go:embed static&lt;/span&gt;
    &lt;span class="n"&gt;static&lt;/span&gt; &lt;span class="n"&gt;embed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FS&lt;/span&gt;
    &lt;span class="n"&gt;pages&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;          &lt;span class="s"&gt;"templates/index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"/add-film/"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"templates/index.html"&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 handlers, rather than using &lt;code&gt;template.ParseFiles&lt;/code&gt;, we focus on the folders using &lt;a href="https://pkg.go.dev/text/template#ParseFS"&gt;&lt;code&gt;template.ParseFS&lt;/code&gt;&lt;/a&gt; with &lt;strong&gt;the page&lt;/strong&gt; which is the path to the file includes the folder name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// GET /&lt;/span&gt;
&lt;span class="n"&gt;getPage&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestURI&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
    &lt;span class="n"&gt;tmpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseFS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tmpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;films&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// ...&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// POST /add-film&lt;/span&gt;
&lt;span class="n"&gt;addFilm&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestURI&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
    &lt;span class="n"&gt;tmpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseFS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tmpl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExecuteTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"film-list-element"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Film&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Director&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;director&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// ...&lt;/span&gt;
        &lt;span class="k"&gt;return&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;That's it. Execute &lt;code&gt;go run main.go&lt;/code&gt; and visit &lt;a href="http://localhost:8000/"&gt;http://localhost:8000/&lt;/a&gt; with your browser. There should be nothing different from BugBytes' production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Include stylesheet built by Tailwind CSS
&lt;/h2&gt;

&lt;p&gt;Similar to what we did for the HTML file in the templates directory, the serverless plan also requires embedding the stylesheet within the static folder, as previously accomplished.&lt;/p&gt;

&lt;p&gt;In contrast to the earlier step, there is no need to parse the stylesheet. Instead, serve it directly when the website requests the &lt;em&gt;/static&lt;/em&gt; path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fileServer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;static&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/static/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileServer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that the stylesheet is readily available for use by the website without additional processing." 😊&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>go</category>
    </item>
    <item>
      <title>Another post that talks about lodash/fp (with Vue)</title>
      <dc:creator>YPChen</dc:creator>
      <pubDate>Sat, 15 Jul 2023 09:48:53 +0000</pubDate>
      <link>https://dev.to/allieschen/another-post-that-talks-about-lodashfp-with-vue-3ie9</link>
      <guid>https://dev.to/allieschen/another-post-that-talks-about-lodashfp-with-vue-3ie9</guid>
      <description>&lt;p&gt;In my previous post, "&lt;a href="https://dev.to/allieschen/my-first-glance-at-functional-programming-281j"&gt;My First Look at Functional Programming&lt;/a&gt;," I mentioned my intention to try using fp-ts. While I'm still learning about functional programming, I believe it can be advantageous for software development. To demonstrate the advantages of functional programming, I created a &lt;a href="https://codesandbox.io/p/github/AlliesChen/todolist-vue/main?layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522panelType%2522%253A%2522TABS%2522%252C%2522id%2522%253A%2522clihh71pn000b3n6musjxkzia%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522panelType%2522%253A%2522TABS%2522%252C%2522id%2522%253A%2522clihh71pn000d3n6mj3zacpp7%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clihh71pn000b3n6musjxkzia%2522%253A%257B%2522id%2522%253A%2522clihh71pn000b3n6musjxkzia%2522%252C%2522activeTabId%2522%253A%2522clja9ghv600cm3n6mp4zu1wvx%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clihh71pn000a3n6mphe54mcg%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252FREADME.md%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%252C%257B%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fsrc%252Fcomponents%252FTodoCreator.vue%2522%252C%2522id%2522%253A%2522clja9ghv600cm3n6mp4zu1wvx%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%257D%252C%2522clihh71pn000d3n6mj3zacpp7%2522%253A%257B%2522id%2522%253A%2522clihh71pn000d3n6mj3zacpp7%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522npm%2520run%2520dev%2522%252C%2522id%2522%253A%2522clihh76bb00823n6madlvkmgs%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%252C%257B%2522type%2522%253A%2522TASK_PORT%2522%252C%2522taskId%2522%253A%2522npm%2520run%2520dev%2522%252C%2522port%2522%253A5173%252C%2522id%2522%253A%2522clihh77fe00d33n6m5zph7ubz%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522activeTabId%2522%253A%2522clihh77fe00d33n6m5zph7ubz%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D"&gt;todolist-vue&lt;/a&gt; web app using Vue and Tailwind Elements as an example. In this post, I will be using lodash/fp to modify the implementation of the functions in the example, which I hope will offer some insights into the benefits of this coding style and whether it's worth adopting.&lt;/p&gt;

&lt;p&gt;For reference, the &lt;a href="https://codesandbox.io/p/sandbox/todolist-vue-9ce10s?file=%2Fsrc%2Fcomponents%2FTwSelector.vue%3A59%2C1"&gt;imperative version&lt;/a&gt; of the same app from the previous post.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;By utilizing the utility functions from lodash/fp, we can harness the advantages of functional programming. Two functions that I find particularly beneficial for my project are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cond-- an expression-based version of if-else statements&lt;/li&gt;
&lt;li&gt;flow-- an function to call its parameters in order&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Parts that are not as pleasant:
&lt;/h3&gt;

&lt;p&gt;You need to become familiar with the functions, although the function names do provide information about their uses. Sometimes, the explanations of the functions in the official documentation of lodash are not very good. Fortunately, since it's a commonly used library, you can find tons of tutorials on the internet, such as &lt;a href="https://masteringjs.io/lodash"&gt;this one&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lodash and lodash/fp
&lt;/h2&gt;

&lt;p&gt;So, as mentioned in the &lt;a href="https://lodash.com/"&gt;Lodash&lt;/a&gt; documentation, it's a library for JavaScript that provides various utility functions. There is a helpful introduction titled &lt;a href="https://geekyants.com/blog/things-to-keep-in-mind-when-using-lodash/"&gt;Things to keep in mind when using Lodash&lt;/a&gt; that you might want to take a look at. The concerns discussed in the article revolve around the bundle size and the implementation of functions, which may be a pitfall that can make debugging challenging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lodash/lodash/wiki/FP-Guide"&gt;lodash/fp&lt;/a&gt; is a functional programming version of Lodash, with some differences mentioned in the linked page, we can use it to write codes in functional programming style.&lt;/p&gt;

&lt;p&gt;ℹ️ There are libraries which has similar usage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ramdajs.com/"&gt;Ramda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/selfrefactor/rambda"&gt;Rambda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://radash-docs.vercel.app/docs/getting-started"&gt;Radash&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Utilities
&lt;/h2&gt;

&lt;p&gt;Although there are many functions, for me, it's &lt;code&gt;cond&lt;/code&gt; and &lt;code&gt;flow&lt;/code&gt; that make the code look like a functional programming language. Shamefully, I only talk about these two in the article... 😅&lt;/p&gt;

&lt;p&gt;It's worth mentioning that the methods from &lt;code&gt;lodash/fp&lt;/code&gt; come with auto-currying, a feature commonly seen in functional programming languages such as Elm and PureScript.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;elm
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;

&lt;span class="n"&gt;addFive&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;addFive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;addFive&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="c1"&gt;-- result will be 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;code source: &lt;a href="https://www.educative.io/answers/how-to-partially-apply-functions-in-elm"&gt;How to partially apply functions in Elm&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;PureScript
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mul :: Number -&amp;gt; Number -&amp;gt; Number
mul a b = a * b

times2 :: Number -&amp;gt; Number
times2 = mul 2
-- It's like const times2 = b =&amp;gt; mul(2)(b) in JavaScript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;code source: &lt;a href="https://blog.logrocket.com/typescript-vs-purescript-not-all-compilers-are-created-equal-c16dadaa7d3e/"&gt;TypeScript vs. PureScript&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  cond
&lt;/h3&gt;

&lt;p&gt;Within the file path src/components/TwButton.vue, the styleContext is determined using a switch statement. Although it functions properly, it creates two scopes: one for the arrow function provided to the computed function and another for the switch statement. This redundancy is somewhat unnecessary since we only need to return the value provided by the switch statement. (Yes, you cannot just return the switch statement without placing it to a function scope.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styleContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computed&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="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-danger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warning&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-warning&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-primary&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cond&lt;/code&gt; is an expression-based version of an if statement. It accepts an array consisting of arrays that represent the match patterns and their corresponding actions.&lt;/p&gt;

&lt;p&gt;ℹ️ In the future, JavaScript might introduce a native pattern matching syntax, as proposed by TC39. This syntax would provide built-in support for match patterns in JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styleMatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-success&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="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;danger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-danger&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="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warning&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-warning&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="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-info&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="nx"&gt;stubTrue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-primary&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styleContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computed&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;styleMatcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  flow
&lt;/h3&gt;

&lt;p&gt;Usually, to get an abstraction, we write assignments, function calls like the function &lt;code&gt;resetSelect&lt;/code&gt; (path: &lt;code&gt;src/components/TwSelector.vue&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resetSelect&lt;/span&gt; &lt;span class="o"&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="nx"&gt;selectRef&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="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span[data-te-select-clear-btn-ref]&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="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resetSelect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectRef&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;invokeArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;querySelector&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span[data-te-select-clear-btn-ref]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
  &lt;span class="nx"&gt;invokeArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dispatchEvent&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ℹ️ Unlike the functions from &lt;code&gt;lodash&lt;/code&gt;, they does not support &lt;code&gt;chaining&lt;/code&gt;, and lose shortcut fusion:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It means combining (fusing) functions that are going to be applied to elements into a single call and calling it on the elements in one go, instead of requiring passes&lt;br&gt;
-- &lt;a href="https://geekyants.com/blog/brilliant-but-lazy/"&gt;Brilliant But Lazy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ℹ️ &lt;a href="https://nestedsoftware.com/2018/02/27/lazy-evaluation-in-javascript-with-generators-map-filter-and-reduce-36h5.21002.html"&gt;This article&lt;/a&gt; has an example that implements shortcut fusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I no longer take "FP" as a magic word that solves every problem I encounter in OOP. It turns out JavaScript does have some, but not all, the features of a functional programming language. With the help of libraries, we can enjoy benefits such as improved readability and purity of methods. However, under the hood, these libraries use functions that imitate the mechanisms of functional programming languages in JavaScript, which may result in reduced efficiency during runtime.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
    </item>
    <item>
      <title>My First Look at Functional Programming</title>
      <dc:creator>YPChen</dc:creator>
      <pubDate>Wed, 05 Apr 2023 10:52:08 +0000</pubDate>
      <link>https://dev.to/allieschen/my-first-glance-at-functional-programming-281j</link>
      <guid>https://dev.to/allieschen/my-first-glance-at-functional-programming-281j</guid>
      <description>&lt;p&gt;ℹ️ You can skip this one if you have already known what functional programming (FP) is. I won't do any coding in this article, but only refer to explanations of what FP is from what I have discovered.&lt;/p&gt;

&lt;p&gt;I've heard arguments that functional programming leads to more maintainable, flexible, and reliable code. As a front-end developer who primarily uses JavaScript (JS), I didn't pay much attention to it. I thought functional programming is just a coding style that emphasizes the use of functions instead of classes. And, for me, using functions for almost everything is the norm, and I am not accustomed to using classes...&lt;/p&gt;

&lt;p&gt;When I changed my career to become a programmer, those popular JavaScript frameworks like React had introduced Hooks and Vue had introduced the Composition API. I have no problem with those new API, and feel like I knew what's functional programming, but I am not.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR-- just for now
&lt;/h2&gt;

&lt;p&gt;From my point of view, FP is not an elixir for those confusing logic and messy codes, operations for the elements in a function don't magically disappear/complete.&lt;/p&gt;

&lt;p&gt;There is a library called &lt;code&gt;fp-ts&lt;/code&gt; that provides a variety of utility functions, allowing JS(TS) programmers to write code in a more functional style, similar to languages like Haskell. However, the functions are named using technical terminology from the FP field, which may not be familiar to everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Functional Programming in JavaScript
&lt;/h2&gt;

&lt;p&gt;About a year ago, I just started to learn JavaScript, I watched &lt;a href="https://youtu.be/e-5obm1G_FY"&gt;Anjana Vakil's Learning Functional Programming with JavaScript on JSUnconf&lt;/a&gt;, and I thought that's all I need to know about FP (with JS).&lt;/p&gt;

&lt;p&gt;I am currently working on a company project and feeling a bit annoyed at having to write functions imperatively. At the same time, I am reminded of the benefits of functional programming mentioned at the beginning of the article-- &lt;a href="https://youtu.be/IqdvgzV_nms"&gt;Is it okay to Pursue Functional Programming on Frontend? by Minsu and Changhui on JSConf Korea&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the video, the speakers are using a library called &lt;a href="https://gcanti.github.io/fp-ts/"&gt;&lt;code&gt;fp-ts&lt;/code&gt;&lt;/a&gt;, and I was fascinated by it. However, the documentation for that library is not easy for me to understand. There are tons of terms that categorize different aspects of the library, and I'm not familiar with many of them, which makes it challenging to use the library effectively.&lt;/p&gt;

&lt;p&gt;I suggest watching the playlist of &lt;a href="https://youtu.be/Z3PLwD3iebg"&gt;Functional Programming with TypeScript&lt;/a&gt; on YouTube. It should help for understanding FP and have your mind settled for reading the document of &lt;code&gt;fp-ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the document of &lt;code&gt;fp-ts&lt;/code&gt;, it does provide a section-- "Learning Resources", which I highly recommend to read both the first article in these two series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grossbart.github.io/fp-ts-recipes/#/"&gt;fp-ts recipes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rlee.dev/practical-guide-to-fp-ts-part-1"&gt;Practical Guide to Fp-ts | Ryan's Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I started to realize that most of the module names, like &lt;code&gt;State&lt;/code&gt;, &lt;code&gt;Semigroup&lt;/code&gt;, &lt;code&gt;Monad&lt;/code&gt; in the library, points to some patterns, i.e they are technical terms. The problem is, from where the terms come, and is there a dictionary to refer to? Yes, at least from my PoV it should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/fantasyland/fantasy-land"&gt;Fantasy Land Specification&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have followed through my writings above, thank you. Do you have a feeling that we have not even written any code but put a lot of effort into explaining what functional programming is, and how we can use a library like &lt;code&gt;fp-ts&lt;/code&gt; to empower JavaScript and TypeScript to work more like a functional language such as Haskell?&lt;/p&gt;

&lt;p&gt;What came to my mind is that while I am excited to learn more about functional programming, I may not be able to introduce it to my current project. Convincing my colleagues to spend time learning the technical terms and concepts involved in functional programming may be challenging, especially when we have project sprints to complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  lodash/fp
&lt;/h2&gt;

&lt;p&gt;Due to the cost of the knowledges required for using &lt;code&gt;fp-ts&lt;/code&gt;, I turn out to bring &lt;code&gt;lodash/fp&lt;/code&gt; to my project and see the benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm more careful about the flow of my functions&lt;/li&gt;
&lt;li&gt;writing less repetitive code that uses the same logic over and over again &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here I hard coded an &lt;a href="https://codesandbox.io/p/sandbox/todolist-vue-9ce10s?file=%2Fpackage.json%3A1%2C1"&gt;imperative-todolist-vue&lt;/a&gt;, which I will use as an example for implement functions with the methods from &lt;code&gt;lodash/fp&lt;/code&gt; in the next article.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Break Vue's reactivity</title>
      <dc:creator>YPChen</dc:creator>
      <pubDate>Tue, 28 Feb 2023 15:23:51 +0000</pubDate>
      <link>https://dev.to/allieschen/break-vues-reactivity-44in</link>
      <guid>https://dev.to/allieschen/break-vues-reactivity-44in</guid>
      <description>&lt;p&gt;This article won't do a deep dive into the implementation of Vue.js reactivity, I just want to show some examples that will break the reactivity when you are writing with the framework.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should you be interested in the mechanism of the reactivity under the Vue.js, here are some information I think that would help:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://vuejs.org/guide/extras/reactivity-in-depth.html"&gt;Reactivity in depth | Vue.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.vuemastery.com/courses/vue-3-reactivity/vue3-reactivity"&gt;Vue 3 Reactivity | Vue Mastery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/gew7a_Mdh5U"&gt;Vue JS 3 Reactivity Fundamentals - Composition API by Marius Espejo&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Primitive value props cannot be modified from the child component.&lt;/li&gt;
&lt;li&gt;For a prop that is an object, modify its attributes from the child component is possible with both mutation and immutation functions, but the data structures may be different.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shallowRef&lt;/code&gt; only updates when a referred source has reassigned.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Two Way Binding
&lt;/h2&gt;

&lt;p&gt;Let's start with a simple input element with a reset button, we can see what we have typed down below the input element.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sfc.vuejs.org/#eNo9UbtuwzAM/BVWixOgsdDVVYy2U5cuGdpFi+PIiRK9IEouCsP/Xspus5G64x15mthrCPWYFWuYwD7qkABVyqGVTtvgY4IJohpghiF6CxVRK+mk673DBBbPsC/4pnpXxnj48tGcHqptoQzZ9Ul7RzhJfuB5s4VJOihT9diZrGi2qp6lm6UTfHUnX2qSssF0SVEHIC5P7VtU3Q0+aeSgOlIddfoRnICFoF3ICcad9Sdl9pKRgWQrdNJjKzB0rhU9oS1Bgi9VhbAuobEBsi+caVpOmmfBy+CicMwp0REvvdH9jcT/ryGHQykFXxnEFvy+OHtka34724X6it5Rwsv18g9AyZo1j/JGuZZesktKARvOcejLv1yx9vHMqapjdklbVSu0u2P036giCUtWJCjBmc2/O5GfWQ=="&gt;Vue Playground&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It works! Not surprising, right? But in reality, we frequently separate elements into child components to make the function of each component clearer. So, let's move the input element and the reset button to &lt;code&gt;Comp.vue&lt;/code&gt;. And it seems Vue is arguing about the prop are read-only.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://play.vuejs.org/#eNqFUk1v1DAQ/SvGl2ylkgjBaXEjKKoESEBVEFx8CckkddexLX+ERVH+OzMOGyoB7c2e92bee2PP/LVz5ZSA77kIrVcusgAxOaYbM1xIHoPktTRqdNZHNjMPPVtY7+3ICmwrNuiNHd3velnRhaYiLE1rTYhsDAO7oPZd8Ra0tuyb9bp7UpwRRVSrNirhJcLodBMBb4yJ22f1pYfmwL4mYDfQtFFNKv4UFQKZ0JLy9HS0HWh0jEKSs2rFOjXVIrjG1EjroEZQVPlUBDY1GkeqsGeoT5x5zjaXRVTUSL42L/ycn1I9sqs1r/PWBUzcQa8MXNNN5PF7FqJXBmXqXQ7fJ4OZrMHl4LgPYdidsZnc5xHluriieCnN8vCmlHEp3tvE1p9tIeF7ihF1XrVatQcknAQRv6GjqFbGX8ljwFC9Gsq7YA3Gz/Ykp80rDf6TI/+Yfr8aJ6zBN/7xPteiT3B+qre30B7+Ub8LR6pJfk2u/ASSb1hs/ABxha8+f4QjnjcQ0yaN7AdADGd1Io8r7TKZDm3f42W37/JPxqf5Eq6OEUw4hSKjxFwyX3L8A/QX/hf9j93n5Yvch0/Hl1+k+Sfq"&gt;Vue Playground&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's good to see Vue prohibit modifying props "directly", because it usually causes data flow of the states to become a mess.&lt;/p&gt;

&lt;p&gt;How about to destructure the &lt;code&gt;props&lt;/code&gt; that is an object type in JavaScript? Deeper to the &lt;code&gt;props.modelValue&lt;/code&gt;'s value property. (I add styles to stand out the elements 😁)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://play.vuejs.org/#eNqNVMtu2zAQ/JWtLnaASGra9OIqRpsg6AN9BG6QXnShJVpmTJEEH44Nw//eJWnLclGn8cnkLmdnZ3e0ST4qlS0dTUZJYSrNlAVDrVPAiWiuysSaMhmXgrVKagsb0HQGW5hp2cIAnw260I1s1e4+y/3Bo2K4FJUUxkJrGrjyz4cbWBLu6AgGnynnEn5LzetXA9ie+eyZE5VlUmCqcS39bprhGWxKAR4hCy8R5yTG+1JsS1HksRdkjgdLW8WJpXgCKOYX42tNyQIeEGlCCVZbMrsucgyEhMp3skxbWVOOCmDZMoE8xmq2hIoTYzCgiCaNJmoeFAL8FUYRMb6f08gO5Myj1XTcUS/ycAZmRoAkffpm0+tsi+QRJ8c6seDUWYti7GtOrYBpk6ZKs5boNVi6smn6NGeWIskPFWfVAtM67ZDaJPwHK6GmM0e4LfIIigWKvKcNHo1d8yiTpxllB5iSatFo6USdVpJLPYJPhAkzlVqi3D5DkbpmokmZ4EzgVF5nb95p2oZo6CjrxNqDIv2GidRK5dO77APWlMtqcRSLSF6Cl2Ic+DxX4MAVe5W6ptjhhVqBkZzVR/epJjVzOLtLtdoFKqeNl0RJJizVPaK92ewJ7+T7xpq5vVkT0W+rN9WTuk9o5BNXPAwrOU/2bnuph62c0Jn5y8bRpUpLZdBfuCoo3J0/Fbif3goP0XCd84zVqCKibMfD4NyIsIvj/dWu0DCAZgeQM+zh2OjU9nwe3ndOHyC3/ziaCeVsz7Hh6c6UewP1rRGqRWfQE25AVa3BhmasyR6NFCht4FYm/uvAONU/lSePyqIkcVxlQvBT9PQ13Fnt6Pn+vprTavGP+0ez8ndlcudZ6SWS7mIWd5vaGL799QN3qRfETh3H7GeC2JzkznOMade4Rki7lxfYfglLgYO8N7crS4XZN+WJhlUL+Siqo37PTrV+oPs2u9yt6DbZ/gHvaSZl"&gt;Vue Playground&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;By clicking "Reset" button, you trigger the &lt;code&gt;restMsg&lt;/code&gt; function in the &lt;code&gt;Comp.vue&lt;/code&gt; to clear the &lt;code&gt;value&lt;/code&gt;'s value to empty string.&lt;/li&gt;
&lt;li&gt;By clicking "Resume to default" button, you trigger the &lt;code&gt;resumeMsg&lt;/code&gt; function in the &lt;code&gt;App.vue&lt;/code&gt; to reassign an new object to the &lt;code&gt;msg&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reassign an object to the &lt;code&gt;msg&lt;/code&gt; breaks the &lt;code&gt;props&lt;/code&gt;'s reactivity. As in JavaScript, every object points to a reference of memory, the &lt;code&gt;msg&lt;/code&gt; is not pointing to the same ref of the &lt;code&gt;value&lt;/code&gt; in the &lt;code&gt;Comp.vue&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immutation and Mutation
&lt;/h2&gt;

&lt;p&gt;For this part, let's play both mutable and immutable method on two array &lt;code&gt;ref&lt;/code&gt;s to see how we can break the reactivity.&lt;/p&gt;

&lt;p&gt;On &lt;code&gt;List.vue&lt;/code&gt;, clicking "Add to ordered list" button will trigger a function to push the value from &lt;code&gt;msg.value&lt;/code&gt;  into it. However, clicking "Add to unordered list" button should see a warning message popping out.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://play.vuejs.org/#eNqtV19v2zYQ/yqcXuwOsd103YvnGE3SoN2QrEWSdQ9RHmiJltnIpEBScQzD3313pChRspKsQAukMHn/fveHd6dddFoU48eSRdNophPFC0M0M2VBciqykzgyOo7mseDrQipDdkSxJdmTpZJrMgCxwR817Vyui4ownuAB1Qb0S65NTceDpxMSi0QKoK51Rk7QxHBHHmlesikZfGZ5Lsm/UuXpLwOyf+N5pUqZYqnV6mTu7t+ANkctxXP0WCxLkRguBUlyRtWVzoZvyA5hgPmxNev+B7E4iiOQ2cdiNnHRgVjAwbB1kVPD4ETIbHU8P1OMPpBvIHTNKGh/5GY7mwDBMiQYmsfRWqYsh5iCnTgiE0dL+SMAoVoDoaCKZooWKxtzAv9muqBifrtiLh5ELlFbyuaINVOMGS4yPZvYO8L1lABQFNntGnfIHhwAXROw5YzmEBVnoEI1rcI1QgogCaIHMWhx1qH1vK1Ye+4pWPeuupsPulysuRk5go+9p2I0ZpMgrnDUZpu7EKN7LkeELGjykClZinSUyFyqKflEudALqaQtJkIKmqYQlhEXORdQQ2/H735XbG2pNhLjZc6evL6Ua7C5neJdwJLRwnPAT1Ry3NVSp8szrqnKuBgZaflr7gbRIpfJQ4vmNC2MeFVHRVA8W5kOnD6XX7IeSkLcIHlTclw8ES1zngawbJRZWkfeso4UTXkJlfa+CONl2JMZjQrFAefWS1QJukTM51sqWjZ9+q7lluZnUKcH2nSZJEzrjrbPUrDtR7bpVfYJ3oQzEyraUCUgAh1FNxCXnJ0puTmUSKH9MdURuKJKypB3kR24fFieH2UKqjoOomTHvUPJKwaRXt8w2vUKpTs+HUpfsrUU5yu+XB5gbnvXYxhe8vZa6hBxUiotFfgruTBBaOz1lFTXXgDakH290VHkZ8ErI8a37kLJQkPvTdkSSvkrnmbQzLD3fHMzoR4O2iiMwJ7s58Om94fMQDtxGtutXzGAELb+WqLu/YPBq41fMz9IXP+2bQW6RdO+uShKE7b+jp2KMzazRWlMoMo/vU7UYW58SHKePCBL5QPouMafs4nT4bBNKnDtvgrp8KP3lXQQUs98I6/ZUnfHPr6KZ/Pl3A/mwpScKkW30NMxZfPq7bZGRz8LjIu+jNsyc1n3QBhMlwbIBZ48EDd6IFZTcnfvRRvJXYj0qI3qyG4lWEYuDEPrr7OLf3VJQTO5lV9QxBdVbAI91WZRlHo17CwaThlxDgwHNdiB3VcMFOGhoX/ahlqQ6xK+G4/HPRTrUgjg3ttBl2LTXpBedQnGJ0/Y8G0/Wqvjf6EVbOMqwGbVanrp8VFlOCj3L231bo7aYBeCX3556rzPTPG0fpud3cuuRA0NqO41NRdQLRUvjuuwBfvH2h42B083VFW/4qZs2gzz0xQUSl+ZBPG1XngL5QG0qsO3htmzPaUXWJP8DjB3OEcyMbCZ+mWyD53Mw1POoRUupXKLIeEifHcQfLe0wro6m+S8SdMk0NIssfjvp2XSj+J2Jv3tD2TSVnp/JuuqfyWXL+H8SWntQ/kjaS2bhMQGhtdhYjsfBb2ptaKTQFeY3HCA4al57s9/JowRs19MuivxcXvlxl7Q/QQgeFk1Y/w58oZwLyrXApbe46XCP797HmxOixyuQhX24wGW6+puw1OzmsIy/wQSkCZhupjm5NfnF7PNipt6KQt2LKNB25Jn4+9aCpjsrtFG+OHJc6a+FBhJGOwwSqvYRxS+qzd/2TujYCj4+2TFkoee++/6Ce/i6CsuHuoRdpeaZuDbhEGakXxx8zdUZ0CEnafMgfsFIuwvEGDE6NjOwGWAHfBZtH/ajQSSeqsvniB22juFQG1QLH8cwYqCW+dzrjdwfxu/r4K5j/b/AV3MpFA="&gt;Vue Playground&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As mentioned above, reassign a new array to the &lt;code&gt;ref&lt;/code&gt; via the prop breaks the reactivity which is not allowed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unlike states which are all immutable in React, the Vue doc mentions that mutation on &lt;code&gt;ref&lt;/code&gt; is valid-- &lt;a href="https://vuejs.org/api/reactivity-core.html#ref"&gt;Reactivity API: Core #ref | Vue.js&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you would like the immutation way to update the &lt;code&gt;unorderedlist&lt;/code&gt;, you may need to modify its structure, like what we did to &lt;code&gt;msg&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// from&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;unorderedlist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;span class="c1"&gt;// to&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;unorderedlist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&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="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 should also make some change on the functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addToUList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;unorderedList&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="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;unorderedList&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nf"&gt;emits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submitMsg&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;clearUList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;unorderedList&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="nx"&gt;value&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;Array&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;ul&gt;
&lt;li&gt;&lt;a href="https://play.vuejs.org/#eNqtV19v2zYQ/yqcXuwOtd103YvnGm3Sot3QrEWSdQ9RHmiJltnIpEBScQzD3713pChRkh0jQAukMHnH4+/+8O6nXfS+KMYPJYum0UwniheGaGbKguRUZG/jyOg4mseCrwupDNkRxZZkT5ZKrskAjg3+qmUXcl1UgvEEF2g2kH/h2tRyXHg5IbFIpADpWmfkLV4x3JEHmpdsSgafWZ5L8r9UefrbgOxfeF2pUqZYaq26M7d3L8Cak5aiL69t3t6BHVCNxbIUieFSkCRnVF3qbPiC7BARIBlbbfc/WIijOIIz+1jMJi5QEBZYGLYucmoYrAiZrc7m54rRe/IdDl0xCtYfuNnOJiCwCglG6WG0linLIbxwTxyRiZOl/AGAUK1BUFBFM0WLlQ0/gX8zXVAxv1kx5waRS7SWsjlizRRjhotMzyZ2j3A9JQAUj+x2jTtkDw6ArQnc5S7NIUDuggrVtIrcCCWAJAgkxKClWUfZ67bC7rWncLt31e280+Vizc3ICXzsvRSjMZsEcYWlNtvchRjdczkiZEGT+0zJUqSjROZSTcknyoVeSCVtXRFS0DSFsIy4yLmA1L8av/5TsbWV2kiMlzl79PZSruHO7RT3ApWMFl4DfqKRs66VOl1ecU1VxsXISKtfazeIFrlM7lsyZ2lhxEkblUDxbGU6cA65/NTt4UmIGyRvSs6KR6JlztMAlo0yS+vIW9WRoikvodLeFGG8DHs0o1GhOODc+hNVgr4g5ostFa07ffqu5Jbm51CnPWu6TBKmdcfaZynY9gPbHDT2Cd6EuyY0tKFKQAQ6hq4hLjk7V3LTP5FCJ2Sqc+CSKilD3UXWc7lfnh9kCqY6DuLJjnv9k5cMIr2+ZrTrFZ7u+NQ//YWtpbhY8eWyh7nt3YGL4SVvr6QOESel0lKBv5ILE4TGbk9Jte0PQBuyrzd6GfmxcGLa+C5eKFlo6L0pW0Ipf8PVDJoZ9p7vrpXXPV0bhRHYk/182IyBUBlkb53FdutXDCCErb8+Uff+weBk49fMDxLXv21bgW7RtG8uitKErb9zT6UZm9miNCYw5Z9eJ+owN94lOU/uUaXyAWxc4c/ZxNlw2CYVuHZfhXT4KXwiHYTU49/IK7bUXQaAr+Jovpz7wVyYkvdK0S30dEzZvHq7rdERJLalS/a+A+rsUPJtxbkC8JgYDJoG00dceUxuCkHYkBL4o83JXQj6ZRvgS8tVsKJcRIbWdXcv/tXVBX3lRn7FI76+YhPYqUhGUerVsMM5nDHiHBgOarADS10M1GP/ov/aF7Ugd/jM7Xg8Piq37oUbdyfBoN+xaROqk37DuOUJG7467JK18QyXBNu4crEFYO099WSpMhyu8O9z9XqONoFBwS9PuTqvOlM8rV90h7FZItXIQOreYLMBhVXp4pAPG7d/4u0R1Xvwoan67TcV1laYv0/BoPRFTBBfqy+0UPagVXOhNQKPdqKDwJoS6ABziwsUEwN81lPQQ+hkHq5yDg10KZWjk4SL8IlC8B3VBZI7m+S8SdMksNJQX/z3yzLpB3g7k373GZm09X44k3Xtn8jlUzh/UVoPoXxOWssmIbGBkddP7IGHfiTB1sAksBimOBx+uGoe/fFPjDEi96SmS6fP2nQdO0L384HgZtUw8efIX4ScqlwLIMxnS4V/nrf2WNcih63QhP3wAGJe7W14alZT+BB4hBOQLGG6mObk9+OkbrPipiZ0AT8zGqwteTb+oaUAVuCaboQfrTxn6muBkQRSALO3in1E4fN884/dMwomh99PViy5P7D/Qz/iXhx9Q9KiHiCrtczAdw2DskLxx+t/oUYDIfClMgftJ4TAfSDAiNGpnYPLADvQs2j/tmwGknqjPz5C7LR3CoHaoFj9OAJ6g4z1mOsN3D/Gb6pg7qP9T5dJvNs="&gt;Vue Playground&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Shallow Ref
&lt;/h2&gt;

&lt;p&gt;The example below use &lt;code&gt;shallowRef&lt;/code&gt; instead of &lt;code&gt;ref&lt;/code&gt; for the &lt;code&gt;lists&lt;/code&gt;. You can see both add to list button don't make changes on the screen. But if you then click the "restore to default" button, the added items show up suddenly.&lt;/p&gt;

&lt;p&gt;As the &lt;code&gt;msg&lt;/code&gt; is used in the &lt;code&gt;List.vue&lt;/code&gt; and the "Resume" button triggered a reassign to the value from the parent-- &lt;code&gt;App.vue&lt;/code&gt;, it also have the &lt;code&gt;lists&lt;/code&gt; to update.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://play.vuejs.org/#eNrFV19v2zYQ/yo3vdgdYqvpuhfXMdakRbuh3Yqk2B7iPNASLbOhSIGkkhiGv/uOpChTcuyk6EMDJDF5/373h3fnTfK2qsZ3NU0myVRnilUGNDV1BZyI4myeGD1PZnPBykoqAxsw64rC1YpwLu8v6fIElP2j2wvYwlLJEgaoc/CmFbyQZdUQxqk9WJsR/RPTpqXbQ6ADzEUmBVJLXcCZNTfcwB3hNZ3A4CNFs/CfVDz/ZQDbF4GXowY9iXBONyD5BLRRTBTXN2+gjk6wncGZNbVzY7ixZ3BC1zcn/mBlmsP2BWJLUzASw0WBLcGsKJCqQoCKihz/5B6M5HTMZTEcKDrylAHCXNYiM0wKZNd1ST/rYvgCnE10c+zcQ2cPOorGt3MxTX3GMD94MLSsODEUTwDT1ensXFFyC/+ipktK0NodM+tpigTHkNmM3I1KmVM+QaOYa/w7TyD19JzdQcaJ1kioiCKFItXK1YINxVRXRMy+os8eq1xajTmdtfCnqTsDwzwgUMu+2UTebdEB1JOiHW9wURuDAQk2F0bAohiNKsVKotZg6IPZnZSsMZQ5ZLXSUuG9ZMJQhfD/yDjLblFBG1kEfek+Q0m1JgVC87a8XVsrbSBc4aCw+4/aDgVomkbhxqM2a+4jb732mQRYkOy2cFBHmeRSTeADYUIvpJKutAEqkudYgyMmOBOY6JfjV78rWjqqC9B4yelD0JczjTbXE3sXsRSkChz40So57WtpMxgYMYoFEyMjHX/LvUO04DK77dC8JpuXp3Q0BMWKlenBeczlY9ZjSYwbPp8JnFYPgO+K5RGsUBAh8o51pEjOaizA11Ucr24pNRJNgj5ZzBdrIjo2Q/ou5ZrwcyzfPW26zjKsrp62j1LQ9Tt6/6iyD4pSbyZWdE+UwAj0FF1hXDg9V/J+XyLHTk1VT+AzUVLGvPFbOlie72SOqnoOWsmee/uSnylGuryipO+Vle75tC/9iZZSXKzYcrmHuevdI4bxpa4vpY4R97pCGxp3PYHmOghgd3KvNzlJwmR69jSUOCt0f+aFKVQpWWls4zldYqV/sadp6PGTXXP3Y8gi2c6Gdq4EedcuUflZY2foFHqOeIBQ89j8aKfIYPDktNDUKwvN1zUd7CW7fs9EVbdt0rdCb6BhmZt+A39ei3bYfYemptuY0wZVt91ilsJ+8ESWAHp5cstKP1n2xRxN1qF0NW+6WTWO7xeu0jC5O3MbL3hyMMV28ZmbNs0Zp0RZx4d2A5vALV3jzLWf8Z9T5dPRVMHcRHfXlu1mjLODZXT40hWQcZjsb9dEVEmP11J4NR1R7E5f5Y+hq2q9GvYM+jhgyFpkMfRjBU2UYSgVqnf1ambRaVx/XrUbTK/mC8Xytt57C5CFG9EObyuh04Xi7/b0I08Bg342i+I4kBz3xGT2NkclEtzgQH0WSOeVHIfTNM/OnHjGu/RgdiUXwHiDF/be7bsuLO6p7iOSPD5xhr1jKZXvHMBEUxWSo1q/F+JGOE052yUgjVTs9kT782M5CrOsm6Nw+z05qjs5qsVPzlID53uyVO9CPDfYww/lqT6UJyeVRmriTMUt3J52r/Lw/jx2+3jTgPq74ml3F7VPtr8bg71s+ob9OAqG7MJQlwJ79elS2d+wlO2tFAuOV7EKt1Xj1tnc3bPcrCa45T6gBGZFmD6mGfx6eGO5XzHTbivR8mE0aluyYvxNS4GzzbfKxH5RY5yqfyobSRxtOGya2Cfu6+pf7s6omjbfU1FmRbPbR+6/6Qd7N0++2NGr7nB6tzSDSzvFF2TJ76/+xmKMiDj2a47cR4g4wTHAFqNnO0eXEXbE59D+6WYyJvWrfv+AsdPBKQvUBcXxzxOcz3YdO+T6Du5v49dNMLfJ9n+cUJ0m"&gt;Vue Playground&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading 🙏&lt;/p&gt;

</description>
      <category>vue</category>
    </item>
  </channel>
</rss>
