<?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: Kaloyan Yosifov</title>
    <description>The latest articles on DEV Community by Kaloyan Yosifov (@kyosifov).</description>
    <link>https://dev.to/kyosifov</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%2F228129%2Fc54a2474-04d9-41cf-97fb-3c4488082ef9.jpeg</url>
      <title>DEV Community: Kaloyan Yosifov</title>
      <link>https://dev.to/kyosifov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kyosifov"/>
    <language>en</language>
    <item>
      <title>Dealing with Floating Point Numbers in JavaScript: Lessons Learned</title>
      <dc:creator>Kaloyan Yosifov</dc:creator>
      <pubDate>Fri, 17 Mar 2023 11:09:33 +0000</pubDate>
      <link>https://dev.to/kyosifov/dealing-with-floating-point-numbers-in-javascript-lessons-learned-2070</link>
      <guid>https://dev.to/kyosifov/dealing-with-floating-point-numbers-in-javascript-lessons-learned-2070</guid>
      <description>&lt;h2&gt;
  
  
  Dealing with Floating Point Numbers in JavaScript: Lessons Learned
&lt;/h2&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%2Fbmpkhy7inlu7400xyik4.jpeg" 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%2Fbmpkhy7inlu7400xyik4.jpeg" width="800" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recently faced a well known issue related to floating point numbers. The experience reminded me of the importance of handling correctly monetary values in JavaScript and to not overlook details.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;A user had reported that when attempting to refund an order with a specific amount, the amount entered was off by one cent. After investigating the issue, I discovered that it was caused by how JavaScript handles floating point numbers.&lt;/p&gt;

&lt;p&gt;The IEEE 754 standard is supported by almost every computer through software or hardware. Dedicated hardware to handle floating points was added in 1985 with the Intel 8087 CPU. The standard provides a way to represent a wide range of values, including very large and very small numbers, but it can also lead to rounding errors when working with certain decimal values. Vast majority of programming languages utilize the FPU (Floating Point Unit component) instead of implementing the standard in software.&lt;/p&gt;

&lt;p&gt;The number 19.9 was one of those floating point numbers that had this issue (there are numerous more, see title 🤣). Since cents are used in the backend and database, and not decimals, conversion from decimal to cents (integer) was required.&lt;/p&gt;

&lt;p&gt;For an example in the BE the value is represented as 1990 and in the FE 19.9 is used for input elements and certain display features.&lt;/p&gt;

&lt;p&gt;In this case the refund amount was multiplied by 100 to convert it to cents, the rounding issues caused the return value to be 1989.9999999999998, instead of the expected 1990.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple solution
&lt;/h2&gt;

&lt;p&gt;To solve this issue, there were options available:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I could have used (19.9 * 100).toFixed(0)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Or round Math.round(19.9 * 100)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Or rely on a library like &lt;a href="https://www.npmjs.com/package/decimal.js?activeTab=readme" rel="noopener noreferrer"&gt;decimal.js&lt;/a&gt; or &lt;a href="https://www.npmjs.com/package/big.js?activeTab=readme" rel="noopener noreferrer"&gt;big.js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I decided to go with the second approach, as the return value had to be a number still. The first approach required to parse it from string to integer again and the third approach was a big step for a small problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoiding the issue getting to production
&lt;/h2&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%2F65yeytgpsr6vfzrx2plu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65yeytgpsr6vfzrx2plu.gif" width="500" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There were unit tests to verify the logic,however it did cover only the happy paths (1 or 2 values) with one invalid value being tested. While it was an OK test coverage it was not enough to reveal the floating point problem. So property testing.&lt;/p&gt;

&lt;p&gt;Property testing is a testing method that generates random inputs to test if a program behaves correctly for a range of inputs. By using property testing in addition to unit tests, we can ensure that our code is robust and handles edge cases appropriately. In the case of the decimal precision issue, had we used property testing, we might have discovered the issue earlier.&lt;/p&gt;

&lt;p&gt;Here is an example. I am using &lt;a href="https://vitest.dev/" rel="noopener noreferrer"&gt;Vitest&lt;/a&gt; as a testing library and &lt;a href="https://www.npmjs.com/package/@fast-check/vitest" rel="noopener noreferrer"&gt;Fast-Check&lt;/a&gt; for property testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// essentially we are using `fc` from `fast-check`, but we have
import { test, fc } from '@fast-check/vitest';
import { it, describe, expect } from 'vitest';

function toCents(value: number) {
    return Math.round(value * 100);
}

describe('Money value', () =&amp;gt; {
    test([fc.float({ min: 1, max: 1000000, noNaN: true })])(
        'is converted correctly to cents',
        floatValue =&amp;gt; {
            const value = parseFloat(floatValue.toFixed(3));

            // using another approach in the test to get the correct value
            // so that we can confirm that `toCents` works correctly 
            const expectedValue = parseInt((value * 100).toFixed(0));

            expect(expectedValue).toEqual(toCents(value));
        }
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The lesson to be learned from this experience is that when working with money in JavaScript, it’s important to be aware of the limitations of the IEEE 754 standard and try to prevent similar issue from occurring in the future.&lt;/p&gt;

&lt;p&gt;I hope that the post has been helpful and has given some insights on working with floating point numbers. 🙌&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Your extraordinary one time secret</title>
      <dc:creator>Kaloyan Yosifov</dc:creator>
      <pubDate>Fri, 27 Jan 2023 13:06:53 +0000</pubDate>
      <link>https://dev.to/kyosifov/your-extraordinary-one-time-secret-23en</link>
      <guid>https://dev.to/kyosifov/your-extraordinary-one-time-secret-23en</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F13200%2F1%2AVJL6FRmuh_BfDlZmIhzl5A.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F13200%2F1%2AVJL6FRmuh_BfDlZmIhzl5A.jpeg" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Your extraordinary one time secret
&lt;/h2&gt;

&lt;p&gt;In this post we will go through our new project we created and open sourced at &lt;a href="https://www.taprolabs.de/ueber-uns" rel="noopener noreferrer"&gt;Tapro Labs&lt;/a&gt;. Let this post be a brief introduction of our project and elaboration on our agenda.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is it about? (Brief introduction)
&lt;/h2&gt;

&lt;p&gt;In our company we used a really interesting way of sharing secret. For starters when we wanted to share usernames or passwords, we would upload them in k8s secrets resource, then the other party would just fetch the secret through the Command Line.&lt;/p&gt;

&lt;p&gt;For a small company of engineers that is fine, but when we have to send passwords or files to non engineers it gets tricky.&lt;/p&gt;

&lt;p&gt;So instead, we decided to create our own custom solution for sharing secrets in our company.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why not use an already built in open source solution?
&lt;/h3&gt;

&lt;p&gt;We looked at other solutions at the time like &lt;a href="https://github.com/Luzifer/ots" rel="noopener noreferrer"&gt;Luzifer’s OTS&lt;/a&gt; and &lt;a href="https://github.com/sniptt-official/ots" rel="noopener noreferrer"&gt;Sniptt’s OTS&lt;/a&gt;. &lt;br&gt;
Which fit nicely into our use case, but since we considered adding more unique features and wanted to wet our feet with Rust, we decided to start from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is OTS
&lt;/h3&gt;

&lt;p&gt;Let’s start by first explaining what is one time secret sharing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ideally a one time secret app allows people to share private info without the server ever having knowledge of what that info is.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Encrypted secret is stored for a short period of time on the server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server cannot know about the encryption key&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basic implementation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;User sends an encrypted secret to the server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server returns a unique id to reference that secret&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User then sends the id along with the decryption key to the recipient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recipient queries the server with the secretId&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server responds with the encrypted secret and removes it from it’s storage system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recipient decrypts the secret with the decryption key&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The secret is stored by default for **24 hours **or until someone views the secret.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are we doing it (Agenda)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To make password, confidential documents and secrets easy to share for both developers and non developers alike&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To improve our skills&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To open source our first project and help people who would need the additional custom solutions we built.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What makes it so special?
&lt;/h2&gt;

&lt;p&gt;Let’s check the features of both mentioned packages above and compare them to our OTS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Luzifer’s OTS:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Secrets are encrypted by the client&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server has no knowledge of the encryption/decryption key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secret is destroyed after being viewed or after a period of time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multilingual&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sniptt’s OTS:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Secrets are encrypted by the client&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server has no knowledge of the encryption/decryption key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secret is destroyed after being viewed or after a period of time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation for self hosting&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sharing secrets through the CLI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specify time to live period&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;And here is what our OTS support:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Secrets are encrypted by the client&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server has no knowledge of the encryption/decryption key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secret is destroyed after being viewed or after a period of time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Slack app integration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;File uploads (up to 40MB)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;With more features on the way:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Command line integration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specify time to live period&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Self-hosting helm chart&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chrome extension&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;p&gt;Most of the time we are sharing passwords or environment variables, but it didn’t took long enough for us to want to send files as well.&lt;/p&gt;

&lt;p&gt;Usually when we interview people we get their CV. After the interview, this file must not be located anywhere in our company systems or personal computers. Most of the time we would send these files through slack, but we had to remember to delete them afterwards along with us trusting that Slack is not breaching their policy or no hacker is in their servers.&lt;br&gt;
This is where the file integration comes into place. It still has the same security features as sending plain text, but it allows us to not forget to delete the file from the messaging system (Slack).&lt;/p&gt;

&lt;h3&gt;
  
  
  Short Demo
&lt;/h3&gt;

&lt;p&gt;Here is a short demo displaying how it works in the browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fz7qhrlg74vta9ikugp12.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fz7qhrlg74vta9ikugp12.gif" width="600" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;We host our application at &lt;a href="https://ots.techatom.de" rel="noopener noreferrer"&gt;https://ots.techatom.de&lt;/a&gt; . While it is secure enough to use, we would recommend that you go with self-host approach. At the moment it is not documented, but we will create a helm chart ready for use in the future. You can watch for update in the repository &lt;a href="https://github.com/tapro-labs/ots" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember to keep secrets a secret 😉 and thanks for reading! 🙌&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>workplace</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Become a Vim success story</title>
      <dc:creator>Kaloyan Yosifov</dc:creator>
      <pubDate>Fri, 11 Nov 2022 13:28:41 +0000</pubDate>
      <link>https://dev.to/kyosifov/become-a-vim-success-story-3doc</link>
      <guid>https://dev.to/kyosifov/become-a-vim-success-story-3doc</guid>
      <description>&lt;h2&gt;
  
  
  Become a Vim success story
&lt;/h2&gt;

&lt;p&gt;I’ve seen some people fall short when they try to learn Vim. They get frustrated and give up. The excuses is that they slow down or that there are too many commands to learn, and so they fallback to their “good old days”.&lt;/p&gt;

&lt;p&gt;In this post I will give you my 2 cents on why learning Vim is a good challenge and why it would benefit you in the long run.&lt;/p&gt;

&lt;p&gt;Here is what we are going to go through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What is Vim&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;My experience&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;How to get started&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What are the next steps&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All good? Let’s start 🔥&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Vim?
&lt;/h2&gt;

&lt;p&gt;Vim is one of those scary editors that you enter by accident when you merge with git in the terminal and have a conflict. There is no close button like in our modern editors and the closest way to get out of the horror is to close your terminal or to&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I3wMmVi4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AHjdvCKiz1B4zt7U07Ik5iA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I3wMmVi4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AHjdvCKiz1B4zt7U07Ik5iA.jpeg" alt="" width="430" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we google this we might stumble to the first StackOverflow result &lt;a href="https://stackoverflow.com/questions/11828270/how-do-i-exit-vim"&gt;“How to exit Vim?”&lt;/a&gt; with about 2.7 million views🔥.&lt;/p&gt;

&lt;p&gt;But Vim shouldn’t be and isn’t all that scary when you start to get the feel for it. And I would like to share my experience on how I started with this beautiful editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  My experience
&lt;/h2&gt;

&lt;p&gt;I have been working with Vim for almost 3 years now and would recommend it to any developer if they want to spice up their code writing. While I am typing it feels really smooth and fast … and I really enjoy it 😅.&lt;/p&gt;

&lt;p&gt;But it wasn’t always that smooth. Before I started to work with Vim most of my experience was to get out of it quickly and never look back.&lt;/p&gt;

&lt;p&gt;But later on I started to feel unsatisfied when writing code and wanted to spice it up.&lt;/p&gt;

&lt;p&gt;I am not going to lie, at the beginning it’s really hard to get used to Vim. The muscle memory of clicking shift and ctrl for selecting text will be a problem. **You must fight that urge, **it’s beneficial in the long run!&lt;/p&gt;

&lt;p&gt;So after my unsatisfaction, I stumbled on a post for 10 finger typing and how it helps with Vim. It piqued my curiosity, so after work I spent &lt;strong&gt;about 15–20 minutes every day&lt;/strong&gt; for a week with 10 fingers. At first it felt really weird, my pinky didn’t like being used for typing 😃, but I went on until I felt more comfortable.&lt;/p&gt;

&lt;p&gt;After those 20 minutes, I would go into Vim to edit a text to get comfortable with some of the basic commands.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ggdUAwF1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Aac6x9r5uah-1A-fj_QuyDw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ggdUAwF1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Aac6x9r5uah-1A-fj_QuyDw.jpeg" alt="" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next week I tried Vim at work. You bet if you think the first two days were frustrating and annoying. The times I wanted to switch back to my good old days was a lot, but I kept on pushing.&lt;/p&gt;

&lt;p&gt;Working for two whole days with Vim, made me get comfortable with it faster and I was actually catching up to my old speed of writing.&lt;/p&gt;

&lt;p&gt;Then after that the rest is history. The more I got to learn how Vim works and how to utilise it, the faster I got and easier it became.&lt;/p&gt;

&lt;p&gt;I know for developers writing speed doesn’t matter that much as we read code more than we actually write. But when you have that sudden “Aha” moment and know exactly what you need to type, that moment is really satisfying while you are writing and editing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started
&lt;/h2&gt;

&lt;p&gt;I would recommend starting with &lt;a href="https://www.typingclub.com"&gt;https://www.typingclub.com&lt;/a&gt;, I would even say it’s essential for practicing with 10 finger typing.&lt;/p&gt;

&lt;p&gt;Even if you do not start using Vim, the practice will help you to write lighting fast messages to your colleagues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--quw9ukIS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A3ZsyV5VK9b22A3GJKfq1jg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--quw9ukIS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A3ZsyV5VK9b22A3GJKfq1jg.gif" alt="" width="498" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TypingClub
&lt;/h3&gt;

&lt;p&gt;TypingClub is a web application with challenges to test your writing skills and how fast you can type.&lt;/p&gt;

&lt;p&gt;It is really fun and engaging, because it’s not just writing some random text, but you are also learning. The content they provide is informative and filled with facts. You are really hitting 2 birds with one stone here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting with Vim
&lt;/h3&gt;

&lt;p&gt;Okay now you feel convinced and are eager to start. But to satisfy your curiosity, I would like to first recommend the tutorial below for you to start with Vim. It covers the basics and will keep you entertained! 😁&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/1UXHsCT18wE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;Now with the basics covered 🤣 (Actual Vim tutorials are left on the bottom of the page as references).&lt;/p&gt;

&lt;p&gt;If you are used to your IDE (like I am) you wouldn’t want to start coding on the terminal like a madman. And luckily for all of us there are Vim plugins for most of the popular IDEs on the market.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;*&lt;em&gt;JetBrains IDEs *&lt;/em&gt;— I would recommend the first-party plugin called &lt;a href="https://plugins.jetbrains.com/plugin/164-ideavim"&gt;IdeaVim&lt;/a&gt;. It integrates really well and it is semi configurable, which allows you to install some of the popular Vim plugins and adding custom mappings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**VSCode - **To be honest I am not a fan of VSCode anymore, but I can recommend two of the popular choices from my colleagues. &lt;a href="https://marketplace.visualstudio.com/items?itemName=vscodevim.vim"&gt;VSCodeVi&lt;/a&gt;m or &lt;a href="https://marketplace.visualstudio.com/items?itemName=asvetliakov.vscode-neovim"&gt;VSCode Neovim&lt;/a&gt;. Both seem to be pretty good, but do take these recommendations with a grain of salt.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;After you get comfortable with Vim on your IDE you might want to try out Vim on your terminal.&lt;/p&gt;

&lt;p&gt;Personally I am in love with my IDE and couldn’t find a good setup to completely migrate to vim on the terminal.&lt;/p&gt;

&lt;p&gt;I completely love that Vim is very configurable and can be made to look and feel to one’s personal style. What I do is when I have to change some configuration files in a remote server, I first upload my Vim configuration. With a couple of plugins (&lt;a href="https://github.com/junegunn/fzf.vim"&gt;FZF&lt;/a&gt;, &lt;a href="https://github.com/neoclide/coc.nvim"&gt;CoC Vim&lt;/a&gt; and some syntax plugins) I can have an editor in the remote server equivalent to VSCode. Which is awesome!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;Here is a recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Practice makes perfect. Try to find some time every day to practice your 10 finger typing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure to commit yourself to Vim to get the most benefit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Watch a quick tutorial. 🤣&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install it in one of your commonly used IDEs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unleash Vim when you ssh to remote servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Wish you all the best when learning Vim and happy Vimming! 🔥&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=_NUO4JEtkDw"&gt;Learn Vim In A Week&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://tech.osteel.me/posts/vim-is-much-cooler-than-you-think"&gt;Good first steps to learn the motion commands&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=gnupOrSEikQ"&gt;Configuring Vim to work like VSCode&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>codequality</category>
      <category>vim</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How we build and deploy updated packages with Lerna and Jenkins + K8s deployments</title>
      <dc:creator>Kaloyan Yosifov</dc:creator>
      <pubDate>Fri, 15 Jul 2022 16:06:42 +0000</pubDate>
      <link>https://dev.to/kyosifov/how-we-build-and-deploy-updated-packages-with-lerna-and-jenkins-k8s-deployments-f22</link>
      <guid>https://dev.to/kyosifov/how-we-build-and-deploy-updated-packages-with-lerna-and-jenkins-k8s-deployments-f22</guid>
      <description>&lt;h2&gt;
  
  
  How we build and deploy updated packages with Lerna and Jenkins + K8s deployments
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Quick intro
&lt;/h2&gt;

&lt;p&gt;Our setup for our app is pretty much straight forward. We use &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt; with &lt;a href="https://www.jenkins.io/"&gt;Jenkins&lt;/a&gt; and &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; for deployment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wYTgocJq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4016/1%2APctQaJ6TDYfXVj606r1GQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wYTgocJq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4016/1%2APctQaJ6TDYfXVj606r1GQw.png" alt="" width="880" height="712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--00dqxtcH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2236/1%2Aq33vg0-gNmn5JdzeHWP1WA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--00dqxtcH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2236/1%2Aq33vg0-gNmn5JdzeHWP1WA.png" alt="Project structure" width="880" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The picture above displays a standard Lerna monorepo example project we created (similar to ours), to give more insights on how everything should look like.&lt;/p&gt;

&lt;p&gt;We have three apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;my-first-react-app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;my-second-react-app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;my-third-react-app&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are a showcase on how we can build only packages that have changed.&lt;/p&gt;

&lt;p&gt;The other two “shared” packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;shared-components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;shared-configs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They have code that is reused in the three main apps specified above. You can see more details on the repository &lt;a href="https://github.com/tapro-labs/jenkins-lerna-monorepo-example"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The problem we wanted to solve was that we build all our packages (4 at the moment) no matter if they have been changed or not. &lt;strong&gt;This wastes resources and time to deploy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Also worth mentioning is that we use the standard packages directory structure for &lt;a href="https://github.com/lerna/lerna"&gt;Lerna&lt;/a&gt; for our standalone applications. So “&lt;strong&gt;App&lt;/strong&gt;” and “&lt;strong&gt;Package&lt;/strong&gt;” in this context is interchangeable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lerna to the rescue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/lerna/lerna"&gt;Lerna&lt;/a&gt; is a really awesome tool to use when we want a monorepo architecture that simplifies our workflow. As an example, let’s say we want to start the server on all of our packages, so we can go into the browser and check them out. We have three options here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open the same amount of terminals as we have packages and run the script on them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a bash script the runs the command on every package&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Or use lerna run watch which does the same as the above 👆but with &lt;strong&gt;one single command and&lt;/strong&gt; &lt;strong&gt;less bash scripting&lt;/strong&gt; 😁&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also worth mention is that the &lt;a href="https://github.com/lerna/lerna/tree/main/commands/run#lernarun"&gt;run&lt;/a&gt; command accepts an argument that is referring to a script in the package.json of each app. In our case this is the start script.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lW31B05b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3510/1%2AgAN_iARiTvY-f63gQssAZA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lW31B05b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3510/1%2AgAN_iARiTvY-f63gQssAZA.png" alt="start command matches with “start” in package.json" width="880" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we instead of start we can run build and build for production all of the packages. The other cool thing about the run command is that it has a nice argument that runs the command only on packages the have been changed given a commit id in the past. In our case we want to set it to the previous commit. The argument we are referring to is &lt;a href="https://github.com/lerna/lerna/tree/main/core/filter-options#--since-ref"&gt;--since&lt;/a&gt;  .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1r5VALX1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AwBQ8LqAfrGoXnNhPAdcE1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1r5VALX1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AwBQ8LqAfrGoXnNhPAdcE1A.png" alt="" width="623" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get the last commit we use a handy git command git rev-parse HEAD~1 .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oZnD7AKw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AJV0RJCAiE9N8KSRM5TcjcQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oZnD7AKw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AJV0RJCAiE9N8KSRM5TcjcQ.png" alt="" width="847" height="35"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And to make it a one liner: lerna run build --since $(git rev-parse HEAD~1) . AWESOME 🍹&lt;/p&gt;

&lt;p&gt;With all this in place let’s look the MAGIC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kqvHvkdn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AfIgCWzUmxaBACzPT-ZpWIw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kqvHvkdn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AfIgCWzUmxaBACzPT-ZpWIw.gif" alt="" width="200" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Magic
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stage('Build updated packages') {
  env.NODE_OPTIONS = '"--max-old-space-size=768"';
  sh './node_modules/.bin/lerna run build --since "$(git rev-parse HEAD~1)" --concurrency 1'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That’s it, nothing more nothing less! The magic pretty much is one line if we exclude the stage function (which is the build stage in Jenkins) and setting an environment variable! With this you build only the packages that have changed from the current to the previous commit.&lt;/p&gt;

&lt;p&gt;You can ignore the NODE_OPTIONS environment if you have a server with more than 2 GB.&lt;/p&gt;

&lt;p&gt;You can also remove the --concurrency 1 option as for us it was useful, because we had a really small server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;p&gt;The blog post ends here, the command above is pretty much what you need to make it build only packages that have changed. But to increase the value we have bonus content! In this next section we are reviewing how we can use what we’ve learned and utilise it to build Docker Images and deploy with Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kUae61_1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ANKLvD5RjqU7xvDH_gw66wA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kUae61_1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ANKLvD5RjqU7xvDH_gw66wA.gif" alt="" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The things we need to do are separated in steps that are easy to follow. The first couple of steps are tedious but important preparations for us to start building Docker images and deploying to Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Getting changed packages
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// get updated packages using lerna's ls command
 packagesChanged = sh(
  script: './node_modules/.bin/lerna ls --since "$(git rev-parse HEAD~1)" | xargs printf \\'%s\\\\n\\'',
  returnStdout: true
 )
 .trim()
 .split('\\n')
 // remove everything before /
 // so that we get the folder name only and not the full path
 .collect{ value -&amp;gt; value.replaceFirst(/@tapro-labs\\//, '') }
 // skip names that are empty
 .findAll{ value -&amp;gt; value != '' &amp;amp;&amp;amp; value != null &amp;amp;&amp;amp; value != ' ' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let’s split the code above piece by piece to understand what is happening.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./node_modules/.bin/lerna ls --since "$(git rev-parse HEAD~1)" | xargs printf \\'%s\\\\n\\'

Output example is:
[@tapro](http://twitter.com/tapro)-labs/package1
[@tapro](http://twitter.com/tapro)-labs/package2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The ls command is similar to run , but instead of running a script in the package.json of an updated package, it returns a list of updated packages.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.split('\\n')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Since the output is just a glob of string returned we split the string into list containing the package names only.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.collect{ value -&amp;gt; value.replaceFirst(/@tapro-labs\\//, ‘’) }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We loop through the list and remove the prefix &lt;a href="http://twitter.com/tapro"&gt;@tapro&lt;/a&gt;-labs . This is just handy so we do not repeat ourselves later when building the Docker images.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.findAll{ value -&amp;gt; value != ‘’ &amp;amp;&amp;amp; value != null &amp;amp;&amp;amp; value != ‘ ‘ }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We filter out values that are empty or null&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Defining our deployments and Docker images
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// we use deployment name if our deployment names in Kubernetes do not match in our repository
// Sometimes these names do not match
def deployments = [
  "my-first-react-app": [
    deploymentName: "first-react-app",
    dockerImageName: "tapro-labs/first-react-app",
  ],
  "my-second-react-app": [
    deploymentName: "second-react-app",
    dockerImageName: "tapro-labs/second-react-app",
  ],
  "my-third-react-app": [
    deploymentName: "third-react-app",
    dockerImageName: "tapro-labs/third-react-app",
  ]
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Since our app names do not match the ones we have as docker images and deployments in k8s, we create a deployments variable where we map based on the apps we have on our repo to the deployments and docker images.&lt;/p&gt;

&lt;p&gt;Of course if your app names match you wouldn’t require this map variable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Building Docker images
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def dockerRegistry = env.PRIVATE_DOCKER_REGISTRY
def dockerImagePrefix = env.DOCKER_IMAGE_PREFIX

packagesChanged.each { packageName -&amp;gt;
    stage("Building docker image for ${packageName}") {
      def dockerImageName = deployments.get(packageName).get('dockerImageName');
      sh "docker build -t ${dockerImagePrefix}/${dockerImageName}:${environment} -f ./packages/${packageName}/Dockerfile"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here we loop through the changed packages, fetch the docker image name from our mapping in deployments variable and build the image of each updated app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 — Pushing the images to a registry
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stage("Push docker image") {
    docker.withRegistry(dockerRegistry) {
        packagesChanged.each { packageName -&amp;gt;
            def app = docker.image(dockerImagePrefix + "/" + deployments.get(packageName).get('dockerImageName') + ":" + environment)

// we push the image with two tags
            // one for the production or staging tag
            // the other one is a tag with the current docker build
            app.push(environment) // @tapro-labs/frontend:production
            app.push(env.BUILD_TAG) // @tapro-labs/frontend:job-132
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here we just push the docker images to our registry. You can see that the images are tagged with two different labels.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First tag is the environment production or staging . Making it the new image for one of those environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second tag is the Jenkins build number, so that we can reference on which build the docker image has been built. This allows us to revert to previous builds on the server if the current one is broken. And also helps us when deploying to k8s&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5 — Deploying to kubernetes
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stage('Deploy to cluster') {
    def kubernetesServerUrl = env.KUBERNETES_SERVER_URL
    def deploymentNamespace = env.DEPLOYMENT_NAMESPACE

    withKubeConfig([credentialsId: 'monorepo-example-kubernetes-service-account', serverUrl: kubernetesServerUrl]) {
      packagesChanged.each { packageName -&amp;gt;
        def deployment = deployments.get(packageName)
        def deploymentName = deployment.get("deploymentName")
        def deploymentDockerImageName = deployment.get("dockerImageName")

        sh "kubectl set image deployment/tapro-labs-${deploymentName} -n ${deploymentNamespace} ${deploymentName}=${dockerImagePrefix}/${deploymentDockerImageName}:${env.BUILD_TAG}"
      }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After all the docker stuff, we initiate our deployment to Kubernetes!&lt;/p&gt;

&lt;p&gt;We construct the deployment name and docker images variables to pass into the Kubernetes command and after all that we start our deployment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Pw5ijNm2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AI3prlFUiqWATBFz2aVgC_A.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Pw5ijNm2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AI3prlFUiqWATBFz2aVgC_A.gif" alt="" width="500" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;${deploymentName}=${dockerImagePrefix}/${deploymentDockerImageName}:${env.BUILD_TAG}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can see we do not use the production tagged image, but the build number version.&lt;/p&gt;

&lt;p&gt;We do this because the initial deployment already has a docker image with the same name and same tag @tapro-labs/frontend:production, so us setting it to the same name will not make k8s restart the deployment and will do nothing. Therefore we use the unique tag @tapro-labs/frontend:job-132 and k8s detects that and upgrades the deployment’s pods to the new docker image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8MDuH7lG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AZLronSWbmj4IwGoWepecHQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8MDuH7lG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AZLronSWbmj4IwGoWepecHQ.gif" alt="AND WE ARE DONE!" width="480" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we did
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We got ourselves to a point where we build only one app instead of every app in the Monorepo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building images for updated apps only&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploy those apps to Kubernetes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that concludes our tutorial on setting up a build on updated packages and deploying them. With this improvement our build times take less time and we do not push unnecessary docker images to the registry.&lt;/p&gt;

&lt;p&gt;Let us know if this post was helpful and enjoyable by clicking on the like button!&lt;/p&gt;

&lt;p&gt;Cheers 🍻&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A quick tip!!!</title>
      <dc:creator>Kaloyan Yosifov</dc:creator>
      <pubDate>Wed, 10 Mar 2021 19:18:14 +0000</pubDate>
      <link>https://dev.to/kyosifov/a-quick-tip-49p</link>
      <guid>https://dev.to/kyosifov/a-quick-tip-49p</guid>
      <description>&lt;p&gt;Hello everybody 👋&lt;/p&gt;

&lt;p&gt;I am reallllllllly tired of writing the same code on every component when making a request. I want to make things simple and my guess is that you want too. Check out my examples to see my tips on such things 😃.&lt;/p&gt;

&lt;p&gt;Currently, when we want to get something from an API, we write the code below ... at least I did 😃&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&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-orders"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!loading &amp;amp;&amp;amp; orders.length"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"orders"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"order in orders"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"order.id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"errorMessage"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;errorMessage&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/span&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;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;/**
 * External dependencies.
 */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&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;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&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;@vue/composition-api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="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="s1"&gt;OrdersSection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="nf"&gt;setup&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;errorMessage&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="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;loading&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="kc"&gt;false&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;orders&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchOrders&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="o"&gt;=&amp;gt;&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;loading&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="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;errorMessage&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="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;loading&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="kc"&gt;true&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;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/orders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;orders&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;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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;errorMessage&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An error has ocurred!&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;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;loading&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="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="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;fetchOrders&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;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&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;This is ok if we are only going to use it on one component. But if we want to retrieve the orders in a different component, we can either copy the code above or create a composition function to extract the logic for it. &lt;/p&gt;

&lt;p&gt;It can look something like this.&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&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-orders"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!loading &amp;amp;&amp;amp; orders.length"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"orders"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"order in orders"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"order.id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"errorMessage"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;errorMessage&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/span&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;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;/**
 * Internal dependencies.
 */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useOrders&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;@/components/bank-form/use-orders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="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="s1"&gt;OrdersSection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="nf"&gt;setup&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useOrders&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;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the &lt;code&gt;useOrders&lt;/code&gt; composition function:&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="cm"&gt;/**
 * External dependencies.
 */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&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;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&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;@vue/composition-api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useOrders&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;errorMessage&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="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;loading&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="kc"&gt;false&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;orders&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchOrders&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="o"&gt;=&amp;gt;&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;loading&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="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;errorMessage&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="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;loading&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="kc"&gt;true&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;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/orders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;orders&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;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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;errorMessage&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An error has ocurred!&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;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;loading&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="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="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;fetchOrders&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;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;errorMessage&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;Great!!!!!&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjoc1dy8anjcz0qyf7ioo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjoc1dy8anjcz0qyf7ioo.gif" alt="GREAT"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;But after some time you need to do the same logic for another request and it becomes tedious to write the same, "loading, errorMessage and data" state.&lt;/p&gt;

&lt;p&gt;This is so much easy with &lt;code&gt;@cytools/vue-query&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example&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&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-orders"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!isLoading &amp;amp;&amp;amp; orders.length"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"orders"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"order in orders"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"order.id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isLoading"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/span&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;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;/**
 * Internal dependencies.
 */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&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;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&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;@cytools/vue-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="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="s1"&gt;OrdersSection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="nf"&gt;setup&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;async &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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/orders&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;defaultData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.tenor.com%2Fimages%2F6474018186354f73413d71779871882b%2Ftenor.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.tenor.com%2Fimages%2F6474018186354f73413d71779871882b%2Ftenor.gif" alt="boom"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've done everything with less code and get free caching of the data based on the key. &lt;/p&gt;

&lt;p&gt;Here is a link to the library for more details -- &lt;a href="https://github.com/cytools/vue-query" rel="noopener noreferrer"&gt;https://github.com/cytools/vue-query&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a lot more fun than just the example above.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>query</category>
      <category>vuequery</category>
    </item>
    <item>
      <title>How to build Vue composition apps.</title>
      <dc:creator>Kaloyan Yosifov</dc:creator>
      <pubDate>Wed, 03 Mar 2021 17:58:04 +0000</pubDate>
      <link>https://dev.to/kyosifov/how-to-build-vue-composition-apps-3cf1</link>
      <guid>https://dev.to/kyosifov/how-to-build-vue-composition-apps-3cf1</guid>
      <description>&lt;p&gt;Hey everybody!!! &lt;/p&gt;

&lt;p&gt;Last month I was working on a new project at my work and was using the Vue composition API. I had about 6-7 months of experience on the new composition API of Vue and was ready to tackle it.&lt;/p&gt;

&lt;p&gt;As I was writing the new requirements, a colleague came by and looked at how I was writing code for retrieving data from the server. On 3 or more components I had used the same features like loading, error handling, and handling data. I give it another thought and started creating a new composition function, to encapsulate the logic of fetching data from an API.&lt;/p&gt;

&lt;p&gt;He stopped me and showed me how the React community is doing it with &lt;a href="https://github.com/tannerlinsley/react-query"&gt;React Query&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I was pretty pumped up and wanted to use it on my Vue project, but with no luck. Because there is no such thing for Vue. I was like WHAT!?!??! &lt;/p&gt;

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

&lt;p&gt;Then I started working on &lt;a href="https://github.com/cytools/vue-query"&gt;Vue Query&lt;/a&gt;. It has the same concepts as React Query, but it is written with support for both Vue 3 and the composition API library.&lt;/p&gt;

&lt;p&gt;Currently, the features that are integrated are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key Caching&lt;/li&gt;
&lt;li&gt;Pagination Support&lt;/li&gt;
&lt;li&gt;Mutating Cache State&lt;/li&gt;
&lt;li&gt;and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out the video below, to see a quick tutorial on how everything is working. And most importantly give us your feedback on what we should improve or if you like the idea for Vue support. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=8Tx8eYKRPUU&amp;amp;feature=youtu.be"&gt;Vue Query Tutorial Video!!!!!&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cytools/vue-query"&gt;Vue Query&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cytools/vue-query-examples"&gt;Vue Query Examples&lt;/a&gt;&lt;br&gt;
&lt;a href="https://nifty-brattain-3dfba5.netlify.app/"&gt;Vue Query Example site&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vuequery</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Mentoring - the dream of a lifetime</title>
      <dc:creator>Kaloyan Yosifov</dc:creator>
      <pubDate>Tue, 17 Sep 2019 18:59:19 +0000</pubDate>
      <link>https://dev.to/kyosifov/mentoring-the-dream-of-a-lifetime-42mi</link>
      <guid>https://dev.to/kyosifov/mentoring-the-dream-of-a-lifetime-42mi</guid>
      <description>&lt;p&gt;Well, gotcha with that little title haven't I? It is a dream it was a dream! &lt;/p&gt;

&lt;p&gt;Enough of the utter nonsense I've written let's start on the real part.&lt;/p&gt;

&lt;p&gt;I started my programming journey when I was 15 years old. Got interested at school and started to write my own programs and games. Two years later did web development at home improving my skills and eventually did my first paid website (which was a complete mess). Soon after the little job I had stopped programming for 6 months and started working as a cashier in a gym in the summer so I can make a quick buck for school. Great! I got the money, last year at school came and I didn't know what I was going to do with my life. Yes, I did programming, but I never viewed is a job opportunity rather as a hobby. While still in school, I thought I would give a programming job a try and applied for only one interview. They contacted me and gave me some tasks and PSD(HTML and JS) on mail. I was shocked at first and tried to google how to do HTML(i was making PHP websites, but at styling, I was not that proficient) and found a tool on making a site from PSD(this is how I thought site were made). Confident in my converter tool I put my files into my USB stick and went on the interview. It was quite embarrassing as I wasn't aware that I went with a death trap in my pocket. As I was giving the USB stick to my interviewer I told him what I've done and then they immediately said I wouldn't cut it. I was kinda sad and thought that I wouldn't become a good programmer so I quit searching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/SiNHGx0XwvwJyjjjjS/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/SiNHGx0XwvwJyjjjjS/giphy.gif" alt="scared" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The mentoring dream process
&lt;/h1&gt;

&lt;p&gt;Eventually, I graduated and got myself a job as a waiter. I was really into it like I tried to learn how to get and serve plates faster etc. But I was thinking to myself is this really where I want to be. After six months I couldn't stand it anymore as I started to not like my job. I was doing it to make the buck and get home. Soon I started to look for other jobs at other areas and thought on applying for the last programming job I tried as they were still searching for candidates, but this time with PHP. At first, I was scared, that I shouldn't bother even applying, but with the help of self-development and my parents, I tried it. (There was a lesson I learned that I should and you should try to remember! You should keep trying no matter the cost. And never accept "NO" as an answer.).&lt;/p&gt;

&lt;p&gt;Three days later I got a phone call from the interviewer and was very excited. They tested my skills and hired me. I was very excited to start the job then and I am still excited working at &lt;a href="https://htmlburger.com/"&gt;HTMLBurger&lt;/a&gt;. Here is where my career as a developer started. All the past programming experience was to build the base structure and here is where I started on grinding and developing it.&lt;/p&gt;

&lt;p&gt;After I got the job they assigned me a mentor. I was pretty excited as I was going to learn new stuff and I did. That is when I started to dream to become a mentor! I was making great progress at my projects: meeting deadlines, gaining experience and most importantly building trust with my Manager, Mentor, and colleagues.&lt;/p&gt;

&lt;p&gt;Two years in my workplace and I've learned a lot. Started making projects with (Laravel, Vue, React and AWS) and these projects let me think more outside of the box and learn Linux and Shell. And it helped me a lot.&lt;/p&gt;

&lt;p&gt;Three weeks ago, the main Mentor at work quitted their job and it meant that the spot is clear. But I wasn't inclined at first, over they two years I stopped dreaming big about being a mentor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/fnpy7E5Sm1LSOvHvu8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/fnpy7E5Sm1LSOvHvu8/giphy.gif" alt="head explode" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Soon I was offered the job and was like "no,no,no i am not ready". Then I had a talk with my Mentor and my Manager, which I think of as close friends, and got me motivated to fulfill my dream and thereafter I was READY.&lt;/p&gt;

&lt;p&gt;Next day went to mentor a mentee left from our Main mentor and at first, it was kind of an awkward experience: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At first, the socializing was awkward :D&lt;/li&gt;
&lt;li&gt;Then I tried to tell him not to do rather than advising him why and what is considered better.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But a week into it I got the hanging of it and as I am teaching, I reinforce my knowledge and heck of it even learn something from the mentee. &lt;/p&gt;

&lt;p&gt;And now I am going to say what I've learned from the past three weeks. Never stop learning, if you have the chance to start mentoring (or even help people online with StackOverflow, or help a colleague).&lt;/p&gt;

&lt;p&gt;Thank you for all the readers which reached to this point, this is my first like Post like ever and I am really glad I got this off my chest.&lt;/p&gt;

&lt;h1&gt;
  
  
  So stay humble and strive to learn and DREAM BIG
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/ZoAa7lsmym6UE/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ZoAa7lsmym6UE/giphy.gif" alt="strive to learn" width="435" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mentoring</category>
      <category>teaching</category>
      <category>learning</category>
      <category>selfdevelopment</category>
    </item>
  </channel>
</rss>
