<?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: Christian Sarnataro</title>
    <description>The latest articles on DEV Community by Christian Sarnataro (@csarnataro).</description>
    <link>https://dev.to/csarnataro</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%2F715997%2F4a49f39d-204c-46c5-bac6-e9f6e6cb07fa.png</url>
      <title>DEV Community: Christian Sarnataro</title>
      <link>https://dev.to/csarnataro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/csarnataro"/>
    <language>en</language>
    <item>
      <title>How to submit a form with SolidJS</title>
      <dc:creator>Christian Sarnataro</dc:creator>
      <pubDate>Wed, 29 Sep 2021 20:45:55 +0000</pubDate>
      <link>https://dev.to/csarnataro/how-to-submit-a-form-with-solid-js-286d</link>
      <guid>https://dev.to/csarnataro/how-to-submit-a-form-with-solid-js-286d</guid>
      <description>&lt;h2&gt;
  
  
  SolidJS
&lt;/h2&gt;

&lt;p&gt;Chances are you have already heard something about &lt;a href="https://www.solidjs.com/"&gt;SolidJS&lt;/a&gt;, the new reactive (as in &lt;a href="https://dev.to/theaswathprabhu/what-is-reactivity-116f"&gt;Reactivity&lt;/a&gt;) UI library for front-end. Think of it as a more performant React, completely built on top of a reactive system.&lt;/p&gt;

&lt;p&gt;You may find some similarities with &lt;a href="https://svelte.dev"&gt;Svelte&lt;/a&gt; as well. Actually, they share some concepts like &lt;em&gt;no-virtual-dom&lt;/em&gt;, built-in &lt;em&gt;stores&lt;/em&gt; for state management, and other few things.&lt;/p&gt;

&lt;p&gt;SolidJS is a relatively new library, &lt;a href="https://dev.to/ryansolid/solidjs-official-release-the-long-road-to-1-0-4ldd"&gt;it reached version 1.0&lt;/a&gt; around July 2021, and even if they have  very nice tutorial on their site - you know, increment a counter, decrement a counter, stuff like that - I had to struggle a little bit to implement such a simple thing like submitting a form. Probably this happened because SolidJS requires a bit of a mind shift if you're coming from a React experience. But once you get familiar with the "reactivity-first" approach, everything makes much more sense.&lt;/p&gt;

&lt;p&gt;That's why I felt the need to share the results of my initial experiments with SolidJS and forms, step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Submitting a form (the naive way)
&lt;/h2&gt;

&lt;p&gt;As a first attempt, I tried to add a &lt;a href="https://www.solidjs.com/tutorial/introduction_signals"&gt;signal&lt;/a&gt; (the basic unit of reactivity in SolidJS jargon) for each of the fields in my form. You can see the result in this &lt;a href="https://codesandbox.io/s/solidjs-submit-form-naive-way-e5123?file=/src/App.tsx"&gt;sandbox&lt;/a&gt;. Source code &lt;a href="https://github.com/csarnataro/solidjs-forms-example/tree/naive-approach"&gt;available on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/e5123"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;As you can see in the code, I had to create as many signals as my fields:&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSignal&lt;/span&gt;&lt;span class="p"&gt;(&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSurname&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSignal&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I had to keep track of modifications to each field, using its own "setter" function (e.g. &lt;code&gt;setName&lt;/code&gt; in the example below):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&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="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally I had to gather each signal with their "getter" functions (e.g. &lt;code&gt;name()&lt;/code&gt;, &lt;code&gt;surname()&lt;/code&gt;, etc.) to create an object to submit my data to some backend API service.&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;dataToSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;shipping_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sameAsAddress&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;shippingAddress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// submit to some backend service&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was happy with this first result because, well... it worked! But I started to think that having so many &lt;code&gt;createSignal&lt;/code&gt; in the same simple component was kind of an antipattern. What if I had to add validation for each field? Would I have to add an additional signal for each field, just to keep track of validation errors? And what if I need to disable some fields selectively, based on the value of another field? Another &lt;code&gt;createSignal&lt;/code&gt; for each of those flags?&lt;/p&gt;

&lt;h2&gt;
  
  
  Submitting a form (the SolidJS way)
&lt;/h2&gt;

&lt;p&gt;This didn't look the right approach to me. After digging a little bit deeper into SolidJS documentation I found the concept of &lt;a href="https://www.solidjs.com/tutorial/stores_nested_reactivity"&gt;nested reactivity&lt;/a&gt;, implemented via the so called &lt;code&gt;store&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;Using this approach, my form as a whole can be considered a collection of  &lt;code&gt;signal&lt;/code&gt;s, possibly dependent on each other. Therefore, the form can be implemented as a &lt;code&gt;store&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can check this new implementation &lt;a href="https://codesandbox.io/s/solidjs-submit-form-with-store-6kh4c?file=/src/App.tsx"&gt;in this sandbox&lt;/a&gt;. Source code &lt;a href="https://github.com/csarnataro/solidjs-forms-example/tree/store-based-approach"&gt;available on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/6kh4c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Here I created a form as a simple store, containing a single object (the set of all fields). You can create more complex stores with nested properties, if needed. SolidJS will allow you to surgically update a single nested property, without cloning the whole store.&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setForm&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FormFields&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;shippingAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sameAsAddress&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I created a utility function to update the store based on the name of the property (so that this function can be reused for all the fields in the form).&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;updateFormField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Event&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLInputElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;setForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;inputElement&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having a single object to update (the form) and not multiple individual fields allowed me to create such a utility function.&lt;/p&gt;

&lt;p&gt;And finally I can submit my data collecting the needed pieces of information from the &lt;code&gt;form&lt;/code&gt; object.&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;const&lt;/span&gt; &lt;span class="nx"&gt;dataToSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;shipping_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shippingAddress&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Just as an aside, having to choose between these 2 different approaches recalled me the well-known dilemma between &lt;a href="https://reactjs.org/docs/hooks-reference.html#usereducer"&gt;&lt;code&gt;useState&lt;/code&gt; VS &lt;code&gt;useReducer&lt;/code&gt;&lt;/a&gt; in React.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, as a bonus, splitting the logic between &lt;code&gt;App.tsx&lt;/code&gt; (my view) and &lt;code&gt;useForm.ts&lt;/code&gt; allows me to keep the UI logic separated from my business logic, following the "single responsibility" principle, which incidentally (or not?) is the first "S" in &lt;a href="https://en.wikipedia.org/wiki/SOLID"&gt;SOLID&lt;/a&gt; principles.&lt;/p&gt;

&lt;h2&gt;
  
  
   Conclusions
&lt;/h2&gt;

&lt;p&gt;SolidJS seems a very promising UI library, very performant and with a very good developer experience. Being relatively young, it's not always easy to find tutorials for some common use cases, like using a form to collect data from a user and submit it to a backend API service.&lt;/p&gt;

&lt;p&gt;I hope this post can help you to build your next real world SPA with SolidJS. In the next few weeks I would like to write another post about form validation and better UX when dealing with HTML forms.&lt;/p&gt;




&lt;p&gt;Cover picture by &lt;a href="https://unsplash.com/@impatrickt?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Patrick Tomasso&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>solidjs</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
