<?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: Nuno Alexandre</title>
    <description>The latest articles on Forem by Nuno Alexandre (@namadnuno).</description>
    <link>https://forem.com/namadnuno</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%2F265757%2F12b786d1-a0ef-4b27-9005-4e309617ce43.png</url>
      <title>Forem: Nuno Alexandre</title>
      <link>https://forem.com/namadnuno</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/namadnuno"/>
    <language>en</language>
    <item>
      <title>Svelte is Great, How I build forms on it with a store for state management 🔥</title>
      <dc:creator>Nuno Alexandre</dc:creator>
      <pubDate>Wed, 13 May 2020 08:36:20 +0000</pubDate>
      <link>https://forem.com/namadnuno/svelte-is-great-how-i-build-forms-on-it-cgm</link>
      <guid>https://forem.com/namadnuno/svelte-is-great-how-i-build-forms-on-it-cgm</guid>
      <description>&lt;p&gt;About a week ago I went out to the wild discovering another frontend framework to try and learn, and I end up founding &lt;strong&gt;Svelte&lt;/strong&gt;, actually, I already have tried but not that in dept. Have been using it to build a side project, made me learn a lot about it. This blog post I will share with you a bit about and how I am using svelte to create forms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--be3eR7Dm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://nunomalex.me/svelte-logo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--be3eR7Dm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://nunomalex.me/svelte-logo.png" alt="svelte-logo" title="svelte logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is svelte?
&lt;/h1&gt;

&lt;p&gt;Svelte is a framework/compiler with an abstraction logic that updates the DOM making it fast and simple. Let me show you an example, of how simple it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuno&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;My name is {name}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(App.svelte)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What you see in this example seams like HTML right ?&lt;/em&gt; That is true the svelte syntax is very similar to HTML but with some cool reactivity effects.&lt;/p&gt;

&lt;p&gt;In this example, we can see a &lt;code&gt;script&lt;/code&gt; tag that holds the &lt;code&gt;name&lt;/code&gt; variable and on the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; block we are referencing the &lt;code&gt;name&lt;/code&gt;, so the result will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;My name is Nuno
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So as you can see svelte files holds javascript and HTML at the same time, like VUE, but with a different syntax.&lt;/p&gt;

&lt;p&gt;Another cool thing is that you can even declare styling on the svelte file also, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;Basic stuff right ?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;There is a lot of the syntax to learn but if you want to learn them would be better to check out the svelte documentation, &lt;a href="https://svelte.dev/docs"&gt;here&lt;/a&gt;. Although in the following sections, I will show you how to use svelte with forms, in this way you will learn more in dept about &lt;em&gt;svelte&lt;/em&gt; and at the same time how to create reusable form and components.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lets create a Form component
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Creation page
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;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;saving&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&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="s2"&gt;../stores/product.js&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="nx"&gt;Form&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;./ProductForm.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;form&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="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;price&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;save&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="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;Form&lt;/span&gt; &lt;span class="na"&gt;bind:form=&lt;/span&gt;&lt;span class="s"&gt;{form}&lt;/span&gt; &lt;span class="na"&gt;on:submit=&lt;/span&gt;&lt;span class="s"&gt;{handleSubmit}&lt;/span&gt; &lt;span class="na"&gt;errors=&lt;/span&gt;&lt;span class="s"&gt;{$errors}&lt;/span&gt; &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;{$saving}&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;(create-product.svelte)&lt;/p&gt;

&lt;p&gt;This code holds the product creation page, and as you can see we have a script tag importing some values and methods from the product store (I will get on that in a minute), as well a Product Form component (that can be reused on the creation of the product as well as on the product editing page). &lt;/p&gt;

&lt;p&gt;In the HTML part, you can see that we are passing the form object into the Form component with &lt;code&gt;bind:form={form}&lt;/code&gt;, this will bind the form object, meaning that when the form object updates inside the Form component, it will be reflected on the creation page as well.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;on:submit={handleSubmit}&lt;/code&gt; is an event listener, the will trigger whenever the &lt;code&gt;Form&lt;/code&gt; fires/dispatchs &lt;code&gt;submit&lt;/code&gt; event.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;errors={$errors} loading={$saving}&lt;/code&gt; props are values that we receive from the store and are passed to our &lt;code&gt;Form&lt;/code&gt; component (the &lt;code&gt;$&lt;/code&gt; is just a shortcut to subscribe to the store, I will explain more in dept bellow).&lt;/p&gt;

&lt;h2&gt;
  
  
  Form component
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;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;createEventDispatcher&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;svelte&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="nx"&gt;Field&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/Field.svelte&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;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createEventDispatcher&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;let&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// prop&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// prop&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// prop&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;on:submit&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="na"&gt;preventDefault=&lt;/span&gt;&lt;span class="s"&gt;{()&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; dispatch('submit')}&amp;gt;
  &lt;span class="nt"&gt;&amp;lt;Field&lt;/span&gt;
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
    &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Name"&lt;/span&gt;
    &lt;span class="na"&gt;bind:value=&lt;/span&gt;&lt;span class="s"&gt;{form.name}&lt;/span&gt;
    &lt;span class="na"&gt;errors=&lt;/span&gt;&lt;span class="s"&gt;{errors}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Field&lt;/span&gt; 
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"price"&lt;/span&gt; 
    &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Price"&lt;/span&gt; 
    &lt;span class="na"&gt;bind:value=&lt;/span&gt;&lt;span class="s"&gt;{form.price}&lt;/span&gt; 
    &lt;span class="na"&gt;errors=&lt;/span&gt;&lt;span class="s"&gt;{errors}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-4 flex justify-between"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;{loading&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;button&lt;/span&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="na"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;button&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="err"&gt;"}&lt;/span&gt;
        &lt;span class="na"&gt;disabled=&lt;/span&gt;&lt;span class="s"&gt;{loading}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Save
      &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(ProductForm.svelte)&lt;/p&gt;

&lt;p&gt;The Product Form looks fairly simple, in the &lt;code&gt;script&lt;/code&gt; tag, we are importing the &lt;code&gt;Field&lt;/code&gt; component, to use it as our inputs but already abstracted with the markup and necessary logic to work. Then we are importing &lt;code&gt;createEventDispatcher&lt;/code&gt; that will provide us with a &lt;code&gt;dispatch&lt;/code&gt; letting us communicate with a parent component. To receive the props from a parent component, we are exporting some variables (form, errors, loading), using &lt;code&gt;export&lt;/code&gt; is required, by using it we are tailing the parent and svelte that we want to receive that as props.&lt;/p&gt;

&lt;p&gt;In the HTML part, we are defining a form with an &lt;code&gt;on:submit&lt;/code&gt; event and passing a preventDefault modifier (allows us to prevent the default browser behavior when the event fires), in fact, we can add as many modifiers as we want, see more &lt;a href="https://svelte.dev/docs#on_element_event"&gt;here&lt;/a&gt;, as a value, we are passing a function that will dispatch the &lt;code&gt;submit&lt;/code&gt; event. If you remember on the Product creation form we are using &lt;code&gt;on:submit={handleSubmit}&lt;/code&gt; to listen to for the &lt;code&gt;submit&lt;/code&gt; event from the child. So by dispatching events from the children to the parent, we are able to communicate between them.&lt;/p&gt;

&lt;p&gt;We are also declaring some &lt;code&gt;Field&lt;/code&gt; components that will receive the value that will be bound, and also the errors prop, that will be used to display errors on the input itself.&lt;/p&gt;

&lt;p&gt;To finish the Form component we have a submit button which has the &lt;code&gt;class&lt;/code&gt; props, so when the user &lt;code&gt;[prop]={ ...expression }&lt;/code&gt;, the value of the &lt;code&gt;prop&lt;/code&gt; will be always the result of the expression. &lt;/p&gt;

&lt;h2&gt;
  
  
  Field Component
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&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;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;label&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;let&lt;/span&gt; &lt;span class="nx"&gt;name&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;let&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

  &lt;span class="nl"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hasErrors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;errors&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="nl"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hasErrors&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input with-error&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="s2"&gt;input&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;handleInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&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;value&lt;/span&gt; &lt;span class="o"&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;target&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;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mb-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&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;placeholder=&lt;/span&gt;&lt;span class="s"&gt;{label}&lt;/span&gt;
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;{classes}&lt;/span&gt;
    &lt;span class="na"&gt;bind:value&lt;/span&gt;
    &lt;span class="na"&gt;on:input=&lt;/span&gt;&lt;span class="s"&gt;{handleInput}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    {#if hasErrors}
      &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-red-500 text-xs italic mt-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{errors[name].message}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    {/if}
&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;In the &lt;code&gt;Field&lt;/code&gt; component we have some props as expected, two &lt;em&gt;computed&lt;/em&gt; variables, when we have &lt;code&gt;$: [varName] = {expression}&lt;/code&gt; will create a variable that will recompute when the component updates (like a computed method in &lt;em&gt;vue&lt;/em&gt;). Then we are creating a method to handle the input change, this means that &lt;code&gt;on:input={handleInput}&lt;/code&gt; will listen to any change on the input and when it happens it will trigger the &lt;code&gt;handleInput&lt;/code&gt; method, that therefore will update the value, since the value is being bound with the parent value will be updated as well.&lt;/p&gt;

&lt;p&gt;For the first time we can see an &lt;code&gt;if&lt;/code&gt; statement, as there are others (see &lt;a href="https://svelte.dev/docs#each"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;h1&gt;
  
  
  The Store
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&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;writable&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;svelte/store&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;api&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;api.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;writable&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;saving&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;writable&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;writable&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;save&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;saving&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&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="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;product&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;saving&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&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="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&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="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;saving&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&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="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;saving&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(product.js)&lt;/p&gt;

&lt;p&gt;To abstract logic from components we often need to create a store, this can also be useful when we need to share information across multiple components. &lt;em&gt;Svelte&lt;/em&gt; has a couple of functions that help us create stores, like &lt;code&gt;writable&lt;/code&gt;, &lt;code&gt;readable&lt;/code&gt;, &lt;code&gt;derived&lt;/code&gt;. When accessing store variables on a svelte component we normally use &lt;code&gt;$&lt;/code&gt; prefix, which will set the appropriate store subscription with that component, making us access it without any more logic. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;writable&lt;/code&gt; returns a object that has additional &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; methods, more about &lt;a href="https://svelte.dev/docs#writable"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our store has multiple &lt;code&gt;writable&lt;/code&gt;(s) like &lt;code&gt;errors, success, saving&lt;/code&gt; that will be used later on our components with &lt;code&gt;$&lt;/code&gt; prefix, to be subscribed. We are also declaring a &lt;code&gt;save&lt;/code&gt; method that is responsible to send our product to the API and set the &lt;code&gt;errors&lt;/code&gt; or &lt;code&gt;success&lt;/code&gt; accordingly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;There is a lot more about &lt;em&gt;Svelte&lt;/em&gt; than what I have shown you, although I think this will be a good start. If you have any suggestion feel free to reach out to me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7btNa0RUYa5E7iiQ/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7btNa0RUYa5E7iiQ/giphy.gif" alt="easy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see also the blog post on my blog &lt;a href="https://nunomalex.me/blog/svelte-is-great-how-i-build-forms-on-it"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; Writing blog posts is a big challenge for me if you think that something is wrong, feel free to reach out to me.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>development</category>
      <category>forms</category>
      <category>store</category>
    </item>
  </channel>
</rss>
