<?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: Lex</title>
    <description>The latest articles on DEV Community by Lex (@lexpeartha).</description>
    <link>https://dev.to/lexpeartha</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%2F485309%2Fb467ffca-cc48-4227-b5f2-6b1c71fc7e69.png</url>
      <title>DEV Community: Lex</title>
      <link>https://dev.to/lexpeartha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lexpeartha"/>
    <language>en</language>
    <item>
      <title>State management in Vue 3 with Harlem.js 📦</title>
      <dc:creator>Lex</dc:creator>
      <pubDate>Sun, 27 Feb 2022 12:18:35 +0000</pubDate>
      <link>https://dev.to/lexpeartha/state-management-in-vue-3-with-harlemjs-3ifj</link>
      <guid>https://dev.to/lexpeartha/state-management-in-vue-3-with-harlemjs-3ifj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a state management?
&lt;/h3&gt;

&lt;p&gt;State management is very important topic in the field of software engineering, and it all stems from the need to store app's data.&lt;/p&gt;

&lt;p&gt;Let's say we're creating a social media app. Usually some of the features require us to fetch data, in terms of posts, user accounts or their followers and etc. This is usually done by hitting the back-end server to get the needed data. However, some data will be used a lot throughout user session: best example of that is logged user's profile data. It's not really optimal nor cost-effective to send requests every few seconds just to get the same data. That's where state management solutions come into play.&lt;/p&gt;

&lt;p&gt;Instead of continually requesting data from the server, we can use storage provided by such state management library (like Redux, Vuex and etc) to store data we need globally, which means we can access it from anywhere within our app, and sync it with the data on the server only when it changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are best state management solutions for Vue 3?
&lt;/h3&gt;

&lt;p&gt;This is a very popular topic right now, and the answer to that question is really underwhelming. There are no "best" solutions, and there never will be.&lt;/p&gt;

&lt;p&gt;During the era of Vue 2, library called &lt;a href="https://vuex.vuejs.org/" rel="noopener noreferrer"&gt;Vuex&lt;/a&gt; was prominently used mostly because it was officially backed up by Vue's core team, who knew very well how framework functioned at it's heart and how to easily implement data reactivity.&lt;/p&gt;

&lt;p&gt;However, in Vue 3 (through it's &lt;a href="https://vuejs.org/guide/extras/composition-api-faq.html#what-is-composition-api" rel="noopener noreferrer"&gt;Composition API&lt;/a&gt;) we can now access it's reactivity system anywhere, by just importing needed utilities from the library, which made it easier for the community to build their own solutions.&lt;/p&gt;

&lt;p&gt;Truth is, the solution you use doesn't matter as much as &lt;strong&gt;how&lt;/strong&gt; you use it. However, good starting point would be to check out &lt;a href="https://pinia.vuejs.org/" rel="noopener noreferrer"&gt;Pinia&lt;/a&gt; and &lt;a href="https://harlemjs.com" rel="noopener noreferrer"&gt;Harlem&lt;/a&gt;, two most popular state management libraries in Vue 3&lt;/p&gt;

&lt;h2&gt;
  
  
  Harlem.js
&lt;/h2&gt;

&lt;p&gt;In this article I will be going over Harlem.js, what I would call a flexible spiritual successor of Vuex. It's an ongoing &lt;a href="https://github.com/andrewcourtice/harlem" rel="noopener noreferrer"&gt;open-source&lt;/a&gt; project that has seen it's first release just well over a year ago.&lt;/p&gt;

&lt;p&gt;There are 2 very compelling selling points of the library:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Core package is very minimal and light-weight, and all additional features you could need (like actions, syncing to browser's storage etc) can be added through it's &lt;a href="https://harlemjs.com/extensibility/" rel="noopener noreferrer"&gt;extensions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;It makes state immutable outside of mutations&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Working with the library
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setting up
&lt;/h3&gt;

&lt;p&gt;The best way to actually learn how to use something, is to build something with it. Let's start by creating &lt;a href="https://vitejs.dev" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; project, selecting Vue and installing harlem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Initializes Vite app&lt;/span&gt;
npm create vite@latest harlem-project

&lt;span class="c"&gt;# Installs harlem.js&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; @harlem/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you chose vanilla javascript starter template, your project should look like this:&lt;/p&gt;

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

&lt;p&gt;We can add harlem to our project by registering it as a plugin in &lt;code&gt;main.js&lt;/code&gt; file like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createApp&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;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Harlem&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;@harlem/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&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;./App.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Harlem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#app&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;Since our goal is to get familiar with the library, and for the sake of simplicity, I'll delete &lt;code&gt;components&lt;/code&gt; folder and set contents of &lt;code&gt;App.vue&lt;/code&gt; to:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&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;h1&amp;gt;&lt;/span&gt;Hello Harlem.js!&lt;span class="nt"&gt;&amp;lt;/h1&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;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Understanding the stores
&lt;/h3&gt;

&lt;p&gt;Now that we have clutter-free project we can work with, we'll start working with the library itself. I'll create &lt;code&gt;stores&lt;/code&gt; folder, and in it add &lt;code&gt;recipe.js&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createStore&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;@harlem/core&lt;/span&gt;&lt;span class="dl"&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;getter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mutation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;recipe&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="na"&gt;recipes&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;Harlem exposes &lt;code&gt;createStore&lt;/code&gt; function from it's core library, which we can use to initialize our store by providing it with two arguments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;String which will be used as unique identifier (you'll see that this is common pattern in the library)&lt;/li&gt;
&lt;li&gt;An object which represents our initial state/data we want in our store&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As it can be seen in the example above, we can destructure things we need from it, like &lt;code&gt;getter&lt;/code&gt;, &lt;code&gt;mutation&lt;/code&gt; or &lt;code&gt;state&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's important to mention that we'll use these to work with our store, and while it might seem unnecessary and cumbersome at first, it helps a lot (especially if you are using TypeScript) in telling our IDE with what store are our mutations or getters linked with. Even with regular JavaScript, if you are using smart IDEs like &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; we get almost complete auto-completion, which makes development experience much better.&lt;/p&gt;
&lt;h3&gt;
  
  
  Getters
&lt;/h3&gt;

&lt;p&gt;Getters are what we use for accessing state. That might sound very redundant, because one might say: "Well, we can just import state directly for that". While that is completely true, we need to keep in mind scalability and potential complexity of the app. &lt;/p&gt;

&lt;p&gt;Let's go through it with some examples:&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;// Simple, very basic example&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allRecipes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allRecipes&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;state&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recipes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// A bit more complex getter, to get more specific data&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cakeRecipes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cakeRecipes&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;state&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;cakeRecipeArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recipes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;recipe&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;recipe&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="nf"&gt;toLowerCase&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cake&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="c1"&gt;// Note: we could've also returned array directly, or used filter method instead&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cakeRecipeArray&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Getter &lt;code&gt;allRecipes&lt;/code&gt; is pretty straight forward. Same as before, string that serves as an id, and a type specific parameter: in this case a function that gets state object as a parameter. Getter methods are used for getting data in common ways across an app.&lt;/p&gt;

&lt;p&gt;Looking at the more complex example below, we can see how much code is needed to access more specific data. If we imported state right away, in all places we need &lt;code&gt;cakeRecipes&lt;/code&gt; we would need to repeat the same code, but If we stick to keeping it in our store file, we can modify that single source of truth to get same results everywhere.&lt;/p&gt;

&lt;p&gt;What about working with parameter based getters? Maybe if we need to search for something specific in our state, how could we pass down parameters?&lt;/p&gt;

&lt;p&gt;As the library author pointed out &lt;a href="https://github.com/andrewcourtice/harlem/discussions/42#discussioncomment-1647873" rel="noopener noreferrer"&gt;here&lt;/a&gt;, he recommends implementing regular function or computed property for that. In that case we rely on Vue's reactivity to reevaluate itself, but there's still a strong point being made by wanting to have all your store logic centralized in the single place.&lt;/p&gt;

&lt;p&gt;In this case, we can rely on returning a function with wanted parameters in our getter:&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;// How such getter would look like&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recipesByChef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;recipesByChef&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;state&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chefName&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recipes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;recipe&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;recipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;chefName&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;div class="highlight js-code-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;recipesByChef&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;./stores/recipe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// And we could call it just like regular function, passing on what we need&lt;/span&gt;
&lt;span class="nf"&gt;recipesByChef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Gordon Ramsay&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;h3&gt;
  
  
  Mutations
&lt;/h3&gt;

&lt;p&gt;Mutations are designed to be the only place where you can change your state. While Pinia is taking a completely different approach of allowing state to be mutated anywhere, harlem exposes state as read-only everywhere except in mutations. While there's nothing inherently wrong with Pinia's approach, having state being permutable everywhere can lead to unpredictable and error prone code.&lt;/p&gt;

&lt;p&gt;Let's take a look at some examples:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addRecipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;addRecipe&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&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;recipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;payload&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;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;payload.description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recipes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recipe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeRecipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;removeRecipe&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;recipeId&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;recipeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recipes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findIndex&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;recipe&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;recipe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;recipeId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recipes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recipeIndex&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 same manner as before, we're passing on parameter of our mutation just after string id. Now we can import these mutations and call them from UI.&lt;/p&gt;

&lt;p&gt;Important thing to note is in the &lt;a href="https://harlemjs.com/guide/core-concepts/mutations.html#defining-a-mutation" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is not recommended to call other mutations within the body of a mutation. This could cause unintended side-effects. Harlem has built-in protection to prevent infinite circular mutation calls from occurring.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So instead of calling methods within one another (like getting all cake recipes that don't have eggs in the same mutation by calling other mutation), we can call them one after another in our component or composable function, where we actually use them. Think of mutations as the most basic unit for editing your state, it's up to you to create castle out of the building blocks Harlem provides.&lt;/p&gt;


&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Harlem.js is awesome new library, that's simple to use, light-weight and flexible. If you've used Vue 2 with Vuex before, I wholeheartedly recommend migration to either Harlem or Pinia. If you are missing some features, like &lt;a href="https://harlemjs.com/extensibility/extensions/action.html" rel="noopener noreferrer"&gt;actions&lt;/a&gt; or &lt;a href="https://www.npmjs.com/package/@harlem/plugin-ssr" rel="noopener noreferrer"&gt;server-side rendering support&lt;/a&gt; - remember to check out all of harlem's extensions.&lt;/p&gt;

&lt;p&gt;For the sake of simplicity and relevancy, I'm rounding up this article here. If you are interested in full code, you can find it here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Lexpeartha" rel="noopener noreferrer"&gt;
        Lexpeartha
      &lt;/a&gt; / &lt;a href="https://github.com/Lexpeartha/vite-harlem-example" rel="noopener noreferrer"&gt;
        vite-harlem-example
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Code for the article about state management in Harlem.js
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Vue 3 + Vite&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; SFCs, check out the &lt;a href="https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup" rel="nofollow noopener noreferrer"&gt;script setup docs&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Recommended IDE Setup&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://code.visualstudio.com/" rel="nofollow noopener noreferrer"&gt;VSCode&lt;/a&gt; + &lt;a href="https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar" rel="nofollow noopener noreferrer"&gt;Volar&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Lexpeartha/vite-harlem-example" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Let me know what are your favorite state management solutions in the comments 👇&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting into tech as a complete beginner 🖥️</title>
      <dc:creator>Lex</dc:creator>
      <pubDate>Sun, 27 Feb 2022 07:22:05 +0000</pubDate>
      <link>https://dev.to/lexpeartha/getting-into-tech-as-a-complete-beginner-1g0f</link>
      <guid>https://dev.to/lexpeartha/getting-into-tech-as-a-complete-beginner-1g0f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Learning is crucial for further development of any skill
&lt;/h3&gt;

&lt;p&gt;Having a lot to learn isn't specific just to tech industry, a lot of professionals world wide are where they are (mostly) because of their love for learning and improving. In the past, it was a real trouble trying to find right resources to learn anything specific. Thankfully today, with widespread usage of internet, most of what you need to get started is at your fingertips - just a few clicks away.&lt;/p&gt;

&lt;p&gt;In today's article, I'll be sharing &lt;strong&gt;free online resources&lt;/strong&gt; and &lt;strong&gt;tips&lt;/strong&gt; for getting into tech (or web development more specifically) as a complete beginner in 2022.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it possible to get into industry without previous Computer Science degree?
&lt;/h3&gt;

&lt;p&gt;Answer to this is &lt;strong&gt;yes&lt;/strong&gt;. Although it will take time, what matters the most is persistence and willingness to learn. Programming has evolved a lot in the past couple of years, so much so that very rarely in today's world you need to know low-level functionalities (like how V8 engine works with JavaScript on web pages, for example) to actually apply them and build a website, or an app per se.&lt;/p&gt;

&lt;p&gt;If you are still unsure about starting without base knowledge, I would highly suggest this &lt;strong&gt;free&lt;/strong&gt; &lt;a href="https://www.edx.org/course/introduction-computer-science-harvardx-cs50x"&gt;CS50 course&lt;/a&gt; hosted on EdX platform by Harvard University. It's 100% self-paced, so you can learn from scratch how computing and programming works from the ground up at any time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Importance of learning structure
&lt;/h3&gt;

&lt;p&gt;There's a very good reason schools and universities create curriculum for topics that should be covered throughout the education. &lt;strong&gt;Learning structure&lt;/strong&gt; gives us an idea of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What to learn next&lt;/li&gt;
&lt;li&gt;What topics are worth your time or irrelevant&lt;/li&gt;
&lt;li&gt;How much we've learned so far and etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, where can you find a structure for learning relevant skills? There are many resources online, few of which I'll go through in this article&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer roadmaps
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HP6AoKGO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645902991786/wEGa-_BlM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HP6AoKGO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645902991786/wEGa-_BlM.png" alt="Screenshot of roadmap.sh website" title="All available pathways at the time of the writing the article" width="880" height="728"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the most straight forward ways to start learning is by guidance of a roadmap. You can find a lot of them online, but one of the most popular websites for that is &lt;a href="https://roadmap.sh/"&gt;roadmap.sh&lt;/a&gt;. It is completely free and open-source solutions, that is continually being improved and worked on by 100+ developers all around the world (check out it's source code &lt;a href="https://github.com/kamranahmedse/developer-roadmap"&gt;here&lt;/a&gt; if you would like to see more details)&lt;/p&gt;

&lt;p&gt;The jist of it is that you can go to the website, and choose one of many pre-built pathways for different skillsets (Frontend - for creating interface of the website, Backend - for creating servers that will parse and handle requests and data, and many more). After selecting desired pathway, you will see tree of yellow-ish boxes that represent your learning path.&lt;/p&gt;

&lt;p&gt;From here you can take 2 different routes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now that you have structure of topics you need to learn, you can just use it as your guide and find videos, written articles or courses (whichever you prefer) on that specific topic&lt;/li&gt;
&lt;li&gt;You can click on each on the topics on the website, and it will link to recommended articles for researching given topic (many topics are lacking, this project is still being worked on)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Websites for learning
&lt;/h3&gt;

&lt;p&gt;Roadmaps are awesome, but for some they are not enough. A lot of people get stuck at certain topics, and due to roadmap's very personal nature, you don't have anyone to talk to or discuss your issue with, which is very valuable when you are starting on.&lt;/p&gt;

&lt;p&gt;If you are one of those, then I have two more options for you, both very similar in their essence. &lt;a href="https://www.theodinproject.com/paths"&gt;The Odin Project&lt;/a&gt; is community-focused learning platform that will guide you through basics of becoming a web developer. If you ever get stuck, you can join their Discord community of around 50.000 people, and ask anything you are troubled with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Gy6t2IP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645904569629/g6LMhlOlP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Gy6t2IP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645904569629/g6LMhlOlP.png" alt="Odin Project" title="Odin Project" width="880" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another very popular option is &lt;a href="https://www.freecodecamp.org/learn/"&gt;freeCodeCamp&lt;/a&gt; where you can learn everything you need to build websites, or visualize and work with complex data. It has built-in editor for basics of HTML, CSS and JavaScript, and large community backing it up - huge portion of which (40.000 as it is mentioned on the website) went and got a job in companies like Microsoft and Spotify.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some tips from personal experience
&lt;/h3&gt;

&lt;p&gt;Everyone wants to learn coding for different reasons. Some like the challenge of creating something both complex and creative (me included), and some want to get hired by a company and earn for the living. Whatever your reason is, here are few things to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;While structure to your learning is important, it can only get you so far. The best way to learn any technology is, hands-down, to actually build something with it. For example: If you have learned basic HTML, CSS and JavaScript, you could build functional gallery website for your favorite topic (like cars, pokemons, illustrations etc). The reason why I'm mentioning this is because working on something you are interested in will keep you motivated and reduce risk of burning-out&lt;/li&gt;
&lt;li&gt;Learning alone can be daunting. If you are just starting out, you can bet others are too! For that reason, I recommend joining one of aforementioned Discord servers to find learning partner, or go to &lt;a href="https://www.reddit.com/r/ProgrammingBuddies/"&gt;r/ProgrammingBuddies&lt;/a&gt; subreddit to find someone learning same technologies as you. Having learning buddy can help keep you stay on the right track immensely &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are you going to learn next?
&lt;/h2&gt;

&lt;p&gt;Share your answers below, and let me know what other topic would you like me to cover next (preparing for interviews, avoiding burn-outs or something else). Thank you for reading the blog, and stay safe.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>motivation</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
