<?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: JV Lobo</title>
    <description>The latest articles on DEV Community by JV Lobo (@jvlobo).</description>
    <link>https://dev.to/jvlobo</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%2F205333%2F62765e2d-282f-458a-804f-fe6fefb01297.png</url>
      <title>DEV Community: JV Lobo</title>
      <link>https://dev.to/jvlobo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jvlobo"/>
    <language>en</language>
    <item>
      <title>5 tips for shipping side projects with a full-time job</title>
      <dc:creator>JV Lobo</dc:creator>
      <pubDate>Fri, 14 Aug 2020 11:17:48 +0000</pubDate>
      <link>https://dev.to/jvlobo/5-tips-for-shipping-side-projects-with-a-full-time-job-1pkf</link>
      <guid>https://dev.to/jvlobo/5-tips-for-shipping-side-projects-with-a-full-time-job-1pkf</guid>
      <description>&lt;p&gt;&lt;em&gt;This post contains affiliate links. For more information, see my disclosures &lt;a href="https://jvlobo.com/disclaimer/"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Creating something is not easy. Probably everyone that has done it before will tell you that. It gets even more difficult when you don't have all the time you would like because you are selling your time to someone else.&lt;/p&gt;

&lt;p&gt;That is my case: I have been working for others for more than 5 years and I have always tried to get the most out of my free time to work on my own projects and create new things.&lt;/p&gt;

&lt;p&gt;One of my latest side projects is &lt;a href="https://codetalks.tv"&gt;codetalks.tv&lt;/a&gt; where we are about to reach 600 registered users and 4.5k tech videos. We built CodeTalksTV in around 4 months while working full time and these are the 5 tips I followed in order to perform better and embrace the spare moments as much as possible. I hope it helps you, the way it helps me 🙂&lt;/p&gt;

&lt;h2&gt;
  
  
  Everything has to do with motivation: how to find it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Internal motivation
&lt;/h3&gt;

&lt;p&gt;I define internal motivation as the one that you already have from the moment that you are thinking about starting a side project. However, it is not only the willingness of "wanting to do something". Because, that something has to be a project that you are super passionate about, otherwise, you will not dedicate the necessary time and you will leave it aside at the first chance you get.&lt;/p&gt;

&lt;h3&gt;
  
  
  External motivation
&lt;/h3&gt;

&lt;p&gt;Internal motivation goes hand in hand with external motivation. For me, external motivation is the crazy assortment of resources that, nowadays, you have at your hands which can be really helpful in giving you the strength to work on your project day after day.&lt;/p&gt;

&lt;p&gt;In my case, I consume content that is closely connected to the world of entrepreneurship, indie hackers and technology such as blogs, podcasts, books, newsletters, videos, communities...&lt;/p&gt;

&lt;p&gt;I think it is always of great help to hear success stories from other entrepreneurs and to hear how they have created something from scratch. Personally, this type of stories motivate me a lot, because if these people can do it, why wouldn’t I be able to do it too?&lt;/p&gt;

&lt;p&gt;Here is a list of resources I use to get that extra piece of motivation I need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Podcasts&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://open.spotify.com/show/4ex8hmrHCPvPohKJb3wsuC?si=FN9L2NIoS_-HveuHxt4LXA"&gt;IndieHackers:&lt;/a&gt;&lt;/strong&gt; very detailed interviews with people who are building projects where they explain literally everything on how they built them and how the projects are doing after their launch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://open.spotify.com/show/5JxcIaIkN8zx3Zy7yD9snv?si=lEu35klxT7-aN6QiHwVyEA"&gt;Rework:&lt;/a&gt;&lt;/strong&gt; podcast from &lt;a href="https://basecamp.com"&gt;Basecamp&lt;/a&gt;, the company. I really like how they do things in a different way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://open.spotify.com/show/1tgqafxZAB0Bjd8nkwVtE4?si=ulPN8-kdS9qXSnKSLOLHUg"&gt;Y Combinator:&lt;/a&gt;&lt;/strong&gt; looks like it has been inactive for a while, but still interesting to listen to the episodes they still have on Spotify Podcasts.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Newsletters&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://bloggingfordevs.com"&gt;Blogging For Devs:&lt;/a&gt;&lt;/strong&gt; I really like Monica's content and she is building an awesome community of devs who like to create content. 100% recommended!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://engineergrowth.substack.com"&gt;Engineer Growth:&lt;/a&gt;&lt;/strong&gt; interesting and very actionable tips to grow your project or business.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://growthinsider.substack.com"&gt;Growth Insider:&lt;/a&gt;&lt;/strong&gt; also an interesting resource for actionable tips. Lately, they're doing some cool case studies about well-known apps and services.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Books&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://amzn.to/2BSzyVZ"&gt;Deep Work:&lt;/a&gt;&lt;/strong&gt; this is one of the latest books I've read and I got super inspired by how people get into that deep mental state where they can work without any interruptions. No social media,  no messaging, &lt;em&gt;no distractions&lt;/em&gt;. This is one of my goals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://amzn.to/318E8bm"&gt;Elon Musk biography:&lt;/a&gt;&lt;/strong&gt; Elon... always inspiring for me.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://amzn.to/2D7eL1P"&gt;Founders at Work: Stories of Startups' Early Days:&lt;/a&gt;&lt;/strong&gt; a deep look at how some big business started.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://amzn.to/3k7peLi"&gt;Zero To One:&lt;/a&gt;&lt;/strong&gt; I think this one is very well known but still a good one to have on the list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://amzn.to/39SkGU9"&gt;The $100 Startup:&lt;/a&gt;&lt;/strong&gt; good motivation to start your own thing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://amzn.to/31gHOI2"&gt;ReWork:&lt;/a&gt;&lt;/strong&gt; like the podcast, also from Basecamp. This is a good book on how to do work "differently", which is the way they do it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://amzn.to/3k7tE4D"&gt;It Doesn’t Have to Be Crazy at Work:&lt;/a&gt;&lt;/strong&gt; also by Basecamp and also about how they work differently. Love these people! haha&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Videos&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.youtube.com/channel/UCpExuV8qJMfCaSQNL1YG6bQ"&gt;YouTube Channel: Better than Yesterday:&lt;/a&gt;&lt;/strong&gt; always important to keep learning and growing as a person.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://youtu.be/fAz8rLQmbKw"&gt;Elon Musk - Gangsta's Paradise:&lt;/a&gt;&lt;/strong&gt; at this point you probably know I get motivated by Elon Musk and his work 😂 I find this short video very inspiring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.youtube.com/results?search_query=ted+talks+motivation"&gt;YouTube search: Ted Talks motivation:&lt;/a&gt;&lt;/strong&gt; I couldn't recommend a single Ted Talk because I've watched many of them and each one motivates you in a different way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.youtube.com/c/AbsoluteMotivation/videos"&gt;YouTube Channel: Absolute Motivation:&lt;/a&gt;&lt;/strong&gt; "random" motivation, is also good motivation.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Other resources&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://growth.design/case-studies/"&gt;Growth.design Case Studies:&lt;/a&gt;&lt;/strong&gt; this recommendation is one of the last but definitely one of the best. Every case study of these guys is a piece of art. And the tips they provide are pure gold.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.indiehackers.com"&gt;IndieHackers:&lt;/a&gt;&lt;/strong&gt; as with the podcast, the entire platform is a very good resource to get inspired and connect with like-minded people.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s1CXoNUj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pcspfaabaab6ezlx5ft8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s1CXoNUj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pcspfaabaab6ezlx5ft8.png" alt="growth.design case studies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Announce it to the world.
&lt;/h2&gt;

&lt;p&gt;In my honest opinion, it is a worthy way to put some pressure on yourself in order to not give up once you’ve started a project.&lt;/p&gt;

&lt;p&gt;Ok, &lt;em&gt;maybe&lt;/em&gt; not to the world, but going public can simply mean telling a good friend, your partner, or a family member. If you are part of a community like IndieHackers you can start a project and then keep updating it with &lt;strong&gt;&lt;a href="https://www.indiehackers.com/milestones"&gt;milestones&lt;/a&gt;&lt;/strong&gt; which I think is a great way to feel that accountability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5jrJ4LHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5x1jfvjt12thafair19b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5jrJ4LHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5x1jfvjt12thafair19b.png" alt="IndieHackers Milestones"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If social networks are where you feel the most comfortable, it is also a good place to say that you are starting a personal project.&lt;/p&gt;

&lt;p&gt;Also, if you have a personal blog you could get a side benefit from writing about your side project: content marketing. That way, if you get people to follow your progress, you can get potential customers or users because they know the effort you are putting into building something that they may want to use.&lt;/p&gt;

&lt;p&gt;The idea is to keep showing progress, feel the need that you "owe" something to someone, and you have to keep working to show new things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do. NOT. Waste. Time
&lt;/h2&gt;

&lt;p&gt;Time is limited. And having a full-time job does not help your gig, as you probably spend most of your active hours working for others. That's why making the most of your free time is crucial. If you don't have too many obligations apart from your work, you might be surprised that you have more free time than you think.&lt;/p&gt;

&lt;p&gt;Taking into account that a day has 24 hours, of which you work an average of 8 hours, and depending on whether you have to get around to go to the office or not add 1 or 2 more hours of commute: 10 hours. An average person should get enough rest by sleeping for about 8 hours. This is 18 "busy" hours, which leaves you 5 hours each day to take advantage of. In addition to weekends, with a good organization, you can do many things with this free time. Of course, I’m assuming you don’t have children or people to take care of, as it can be trickier that way. But a tip I have is: get the most out of your weekends, and the couple of hours you might have after putting the kids to sleep.&lt;/p&gt;

&lt;p&gt;These types of calculations are done many times to see that we really have free hours a day, but obviously each person has its life and each day is different. What is very clear to me is this: if you really want to do something and you have the right motivation, you are going to get the most out of every free minute you have in your day. Imagine that you put 2 hours per day into your project, those hours will add up to 60 hours per month. And &lt;strong&gt;60&lt;/strong&gt; is better than &lt;strong&gt;0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In addition to make the most of your day, be mindful of when you are the most productive during the day. There are people who have more energy and a more active mind at certain times of the day so &lt;strong&gt;find your perfect time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, while we were building &lt;a href="https://codetalks.tv"&gt;CodeTalks&lt;/a&gt; I was living in Australia and I used to wake up very early, around 5 or 6 am since during the summer months it dawns very early and at a very good temperature. These conditions gave me a whole lot of energy, hence I always took a couple of hours to get my hands deep into this project before I had to go to my actual job.&lt;/p&gt;

&lt;p&gt;I'm aware of how easy it is to say this but then how difficult it is to actually accomplish it. Getting home after a long day at the office the last thing you want to do is to get back to coding or researching, sometimes your brain is just off and asking for some YouTube or funny memes.&lt;/p&gt;

&lt;p&gt;There are some methods you can follow to do better. Personally I like to write down a list of things I want to accomplish and feel the reward of crossing out items of this list. &lt;em&gt;Make sure you keep it short so you don’t lose motivation&lt;/em&gt;. And then, to inject me some quick dopamine into my brain, it’s nice to get some small breaks to do something non-work related.&lt;/p&gt;

&lt;p&gt;I really like this small app a friend of mine built: &lt;a href="http://dopamine.netlify.app"&gt;Dopamine&lt;/a&gt;. With this app, you can start a timer when you are working and you'll earn some "dopamine points" that you can spend on YouTube, social media, or somewhere else. So basically for every 60 minutes of work you get 15 dopamine points to spend. Every dopamine point equals 1 minute. I think it is an interesting concept to balance working and enjoyment time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yiZsKohU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zt8nlaf0dhiu4ze726lc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yiZsKohU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zt8nlaf0dhiu4ze726lc.png" alt="Dopamine app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Take care of your body
&lt;/h2&gt;

&lt;p&gt;In a word: &lt;strong&gt;move&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Whether it is going to/coming from work walking or doing some exercise at the end of the day.&lt;/p&gt;

&lt;p&gt;I personally enjoy going back home walking from the office (around 25-30min) as well as going for a run to take a break between work and get on with my project.&lt;/p&gt;

&lt;p&gt;I think it’s very important to clearly separate your working day at the office and your "working day" on your side project. It will allow you to be much more productive after work.&lt;/p&gt;

&lt;p&gt;We also underestimate the importance of good sleep. More than 5 years ago I bought one of those smart bands so I could track my sleep (among other things) and it has been very interesting to see how the amount of time I spend sleeping correlates to how sharp and energized I feel the next day. I have also been able to know the exact amount of sleep I need to be fresh the next day: ~7:30h of total sleep with ~2hours of deep sleep. If I get that amount of sleep I'm sure I'll be good and full of energy for the day 💪🏾&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qx3d2qvh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y9fl73jqwiqptnd5sqto.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qx3d2qvh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y9fl73jqwiqptnd5sqto.jpeg" alt="My average sleeping time in a week"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recommend you do something like that. If you don't have a smart band or don't want to spend money on one (although you can &lt;a href="https://amzn.to/31iuKlH"&gt;get one for cheap&lt;/a&gt;) you can do it with &lt;a href="https://www.lifehack.org/816199/best-sleep-tracker"&gt;your smartphone&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take care of your mind
&lt;/h2&gt;

&lt;p&gt;Just like exercising helps to clear the mind and stretch the muscles, I think it is also important to take mental breaks from time to time.&lt;/p&gt;

&lt;p&gt;If one day you feel like doing nothing when you leave the office, no problem! it is also necessary to relax the mind so as not to burn yourself.&lt;/p&gt;

&lt;p&gt;Watch some Netflix, meet with a friend for a coffee (or beer!)... it's up to you, whatever helps you relax your mind. You can also try &lt;a href="https://www.womenshealthmag.com/health/g25178771/best-meditation-apps/"&gt;meditation apps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i7Z5lclS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/neledvm4mqwnx0fpu5ov.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i7Z5lclS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/neledvm4mqwnx0fpu5ov.jpg" alt="Calm App - Sleep, Meditation and Relaxation"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;My goal with this article is that you can get that extra motivation to start working on your projects too. Hopefully, I achieved it 🤞🏽&lt;/p&gt;

&lt;p&gt;I would love to hear your ideas and projects so I encourage you to write something down in the comments or contact me at my email!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>motivation</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>How to make clock-in at work easier with the ESP32 board - Part 2</title>
      <dc:creator>JV Lobo</dc:creator>
      <pubDate>Thu, 04 Jun 2020 11:07:53 +0000</pubDate>
      <link>https://dev.to/jvlobo/how-to-make-clock-in-at-work-easier-with-the-esp32-board-part-2-9if</link>
      <guid>https://dev.to/jvlobo/how-to-make-clock-in-at-work-easier-with-the-esp32-board-part-2-9if</guid>
      <description>&lt;p&gt;&lt;em&gt;This post contains affiliate links. For more information, see my disclosures &lt;a href="https://jvlobo.com/disclaimer/"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned in the &lt;a href="https://dev.to/jvlobo/how-to-make-clock-in-at-work-easier-with-the-esp32-board-part-1-3eo0"&gt;previous article&lt;/a&gt;, in this second part I am going to install a battery in the system and also design a box to organise everything.&lt;/p&gt;

&lt;p&gt;🔋 To power the system I thought about reusing an old iPhone battery that I had lying around.&lt;/p&gt;

&lt;p&gt;If you take a closer look at an iPhone battery, at first you may think that it has a strange connection and that it cannot be reused, but it really is a lithium battery like any other, with its positive and negative terminals, only they are hidden under the adhesive tape.&lt;/p&gt;

&lt;p&gt;If we remove this tape, you can clearly see the two terminals and the small board that Apple uses along with its connector.&lt;/p&gt;

&lt;p&gt;It is only needed to remove this part and check which one is the positive terminal and which one is the negative (with the help of a &lt;a href="https://amzn.to/2MkG5dM"&gt;multimeter&lt;/a&gt;) and solder a pair of wires:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BhHwaCQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z6dkcq5xehfdtcfuswfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BhHwaCQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z6dkcq5xehfdtcfuswfb.png" alt="Reusing and old iPhone battery"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But of course, with this we can provide power to the circuit until the battery charge is used up, but then what? How can we recharge the battery? 🔌&lt;/p&gt;

&lt;p&gt;For this there are some small boards called &lt;a href="https://amzn.to/300NlU6"&gt;lithium battery charging modules&lt;/a&gt;, which usually come with mini-USB or micro-USB input, and soldering the terminals to this module serve to recharge the battery. They also include charge and discharge protection.This board comes with two output terminals that are the ones that we will connect to our circuit.&lt;/p&gt;

&lt;p&gt;The assembly scheme would look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--426O8wPx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o851xqdsb8riwazbyow1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--426O8wPx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o851xqdsb8riwazbyow1.png" alt="Battery connection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👩🏽‍🎨 The next step is to design the box in 3D.&lt;/p&gt;

&lt;p&gt;About a year ago I bought the &lt;a href="https://amzn.to/2U3q9AV"&gt;Ender 3 Pro&lt;/a&gt; and I have been printing in 3D ever since but when I have designed things I have always done it on &lt;a href="http://tinkercad.com"&gt;Tinkercad&lt;/a&gt; which is very easy to use and offers quite good results. For this project I wanted to learn how to use &lt;a href="https://www.autodesk.com/products/fusion-360/overview"&gt;Fusion 360&lt;/a&gt; which offers more possibilities and with which you can make somewhat more complex designs.&lt;/p&gt;

&lt;p&gt;The first thing I do when I'm going to design something is obviously take measurements 📐. I always use my &lt;a href="https://amzn.to/2Bi8wGU"&gt;caliper&lt;/a&gt;, the most accurate tool for this task.&lt;/p&gt;

&lt;p&gt;I took the measurements of all the components that will go inside the box. I am going to use two large buttons, the ones used in old arcade machines. I will also put a switch to turn the system on and off. I will install a small vibration motor so that, after pressing any of the buttons, I will receive confirmation when the action has been carried out correctly.&lt;/p&gt;

&lt;p&gt;For the box I had a fairly simple structure in mind: rectangular with two button holes on the top, a micro-USB port on one side for charging and a switch to turn the system on or off on the other side.&lt;/p&gt;

&lt;p&gt;After quite a few hours learning and designing with Fusion 360 I came up with something that I was comfortable with 👍🏾:&lt;/p&gt;

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

&lt;p&gt;This is a three-piece design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The upper part, where the buttons go, and that has enough height to house the components inside.&lt;/li&gt;
&lt;li&gt;A part with supports to host the electronic components and with space underneath to accommodate the battery.&lt;/li&gt;
&lt;li&gt;The bottom lid, used to close the box and put the screws that will also go through the other two parts so that everything is securely fastened.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I design this type of pieces in 3D, instead of designing and printing everything at once without knowing if they are going to fit well (which takes a long time and uses too much filament), what I usually do is print small sections that I consider "critical". They are parts that because of where they are or the way I have designed them, I am not sure if they will turn out as I have in my mind 🤔. Because when you are designing, everything is "perfect", but once it is printed it doesn't turn out as it does in the design. Also there are things that may not be well designed or need to be redesigned to make them look better. You also have to take into account the tolerances between different pieces that fit or are next to each other, because the printed material is not perfect, and usually it will have a greater thickness than the one you have designed.&lt;/p&gt;

&lt;p&gt;In this design, for example: the part such as the holes for the buttons, the part where the components are mounted,  the top part in the area where it connects to the other two parts or the part of the logo and the letters. These parts to my understanding were the most critical ones and I printed small sections to be able to check and correct errors. And thank goodness I did it, because I had to redesign certain parts 😅.&lt;/p&gt;

&lt;p&gt;Here you can see the measurements I took and the parts I printed to check and correct in the design:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vrNUQIZH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8fg207y41ghb0c2d34rj.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vrNUQIZH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8fg207y41ghb0c2d34rj.JPG" alt="Measurements and test prints"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, with all the parts well designed I was able to print everything, which took quite some time ⏳:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Top piece: about 11 hours and about 20 meters of filament.&lt;/li&gt;
&lt;li&gt;Centerpiece: about 4 hours and about 6 meters of filament.&lt;/li&gt;
&lt;li&gt;Bottom piece: about 7 hours and about 11 meters of filament.&lt;/li&gt;
&lt;li&gt;Letters and logo: less than 1 hour and over 1 meter of filament.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;After printing all the pieces I had to sand them, especially the front part where the logo and letters go.&lt;/p&gt;

&lt;p&gt;Finally the moment I was looking forward: the final assembly! 👨🏽‍🔧&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nygcO3wT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vasd5ady5lsgbmfztos7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nygcO3wT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vasd5ady5lsgbmfztos7.jpeg" alt="All the components ready to be assembled"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although the buttons are different, they are still connected to the same pins as in the prototype: &lt;code&gt;26&lt;/code&gt; to start/end the shift and &lt;code&gt;27&lt;/code&gt; to start/end the lunch break. The vibration motor will be connected to pin &lt;code&gt;17&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k6rD5H70--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8m01jo8jb3thrxbazhux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6rD5H70--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8m01jo8jb3thrxbazhux.png" alt="Wiring diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tip of my soldering iron is very worn, which made it difficult for me to make a good solder.&lt;br&gt;
After much soldering and connecting cables:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_GRwe5Wq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ubaxgddlgu790kb1mqy1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_GRwe5Wq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ubaxgddlgu790kb1mqy1.jpeg" alt="All the parts connected"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With everything connected, and before closing the box, I had to make some adjustments to the code.&lt;/p&gt;

&lt;p&gt;First, to control the vibration motor. It is very simple, I just configured pin &lt;code&gt;17&lt;/code&gt; as output and each time a button is pressed, separate signals are sent to the motor in different time ranges so that it makes a vibration pattern. I have created two patterns: one for when the shift or the lunch break starts and the other for when it ends. You can see it in version 2 of the source code that I will leave in a link at the end of the article.&lt;/p&gt;

&lt;p&gt;Besides, since the system is going to be connected to the battery and since it is only going to perform the action when one of the buttons is pressed, ideally it should not be working all the time. For this you can make use of the deep sleep function of the ESP32 💤. It is very simple to configure, the idea is that once the system boots, it goes into sleep mode, and only wakes up when one of the buttons is pressed. Depending on the button pressed, it will perform the corresponding action and once it is finished, it returns to deep sleep mode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://randomnerdtutorials.com/esp32-deep-sleep-arduino-ide-wake-up-sources/"&gt;This guide&lt;/a&gt; was of great help for configuring deep mode.&lt;/p&gt;

&lt;p&gt;And this is it, once the new code was uploaded to the board, it was time to put the screws in and see the final result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UAIPVOEQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5gs5gpkp0hb887lm04mz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UAIPVOEQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5gs5gpkp0hb887lm04mz.jpeg" alt="Final result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here you can find the new part of the code, it is in the &lt;code&gt;v2&lt;/code&gt; branch.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jvlobo"&gt;
        jvlobo
      &lt;/a&gt; / &lt;a href="https://github.com/jvlobo/esp32-calamari.io-api"&gt;
        esp32-calamari.io-api
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Clocking in and out in Calamari.io with the ESP32 development board
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The final test:&lt;/p&gt;

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

&lt;p&gt;It works!! 🎉&lt;/p&gt;

</description>
      <category>electronics</category>
      <category>esp32</category>
      <category>iot</category>
    </item>
    <item>
      <title>How to make clock-in at work easier with the ESP32 board - Part 1</title>
      <dc:creator>JV Lobo</dc:creator>
      <pubDate>Thu, 04 Jun 2020 11:07:45 +0000</pubDate>
      <link>https://dev.to/jvlobo/how-to-make-clock-in-at-work-easier-with-the-esp32-board-part-1-3eo0</link>
      <guid>https://dev.to/jvlobo/how-to-make-clock-in-at-work-easier-with-the-esp32-board-part-1-3eo0</guid>
      <description>&lt;p&gt;&lt;em&gt;This post contains affiliate links. For more information, see my disclosures &lt;a href="https://jvlobo.com/disclaimer/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In 2019, a regulation came into force in Europe by which companies are required to have a &lt;a href="https://www.euronews.com/2019/05/15/all-companies-must-record-employees-working-hours-eu-court-rules" rel="noopener noreferrer"&gt;daily record of the hours of their employees&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are many online tools to keep track of this. At &lt;a href="https://www.desygner.com" rel="noopener noreferrer"&gt;Desygner&lt;/a&gt; we use &lt;a href="https://www.calamari.io" rel="noopener noreferrer"&gt;Calamari.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We use Slack as a communication tool and we have commands for clocking in / out from Calamari.&lt;br&gt;
The problem is that sometimes I forget to write the command in Slack to start or end my working day 🤦🏽‍♂️&lt;/p&gt;

&lt;p&gt;Thinking about solutions to make it easier, and since I like to tinker with electronics, I thought about building a small device with a couple of buttons with which I could start and end my shift and register the lunch break. All I needed was for Calamari to offer an API to communicate with, and &lt;a href="https://developers.calamari.io" rel="noopener noreferrer"&gt;they have one&lt;/a&gt;! 👏🏽&lt;/p&gt;

&lt;p&gt;Now, it was time to choose where to start building this system. Previously, I had used &lt;a href="https://wikipedia.org/wiki/Arduino" rel="noopener noreferrer"&gt;Arduino&lt;/a&gt; for electronics projects but now I was going to need WiFi connection and the cheapest option of this brand is the &lt;a href="https://amzn.to/3ds5Y7w" rel="noopener noreferrer"&gt;Arduino Nano 33 IoT&lt;/a&gt; at around $25 on Amazon. Several people had recommended me to use the ESP32 board that also includes WiFi and Bluetooth and you can find it on &lt;a href="https://amzn.to/2TXKSG4" rel="noopener noreferrer"&gt;Amazon&lt;/a&gt; for $10.&lt;/p&gt;

&lt;p&gt;This was the chosen one:&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%2Fi%2Fuqv1jo98gupsvau07osn.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%2Fi%2Fuqv1jo98gupsvau07osn.png" alt="ESP32 Board"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was my first time working with the ESP32 board, so after the first steps to get it working with my computer and &lt;a href="https://wikipedia.org/wiki/Arduino_IDE" rel="noopener noreferrer"&gt;Arduino IDE&lt;/a&gt;, the next thing I wanted to do was connect it to the WiFi network.&lt;/p&gt;

&lt;p&gt;My first idea was to have an app or web with which to connect via Bluetooth to the board, and once there, through an interface, be able to select the network to connect it to and write the password. It sounded great! However, after searching a lot about how to connect the ESP32 board via WiFi I did not find anything similar already done. So I opted for a simpler option: hardcode the name and password of the WiFi network in the code. The downside of this is that every time I want to shift networks I need to change the code and compile it back to the board.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"WiFi.h"&lt;/span&gt;&lt;span class="c1"&gt; //ESP32 WiFi library&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;WiFi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WIFI_STA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;WiFi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Wifi_SSID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"WiFiPassword"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WiFi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;WL_CONNECTED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&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="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" still trying to connect"&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="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connected. My IP address is: "&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WiFi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;localIP&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://www.megunolink.com/articles/wireless/how-do-i-connect-to-a-wireless-network-with-the-esp32/" rel="noopener noreferrer"&gt;This guide&lt;/a&gt; was helpful&lt;/p&gt;

&lt;p&gt;Once connected to the network, the next important step was to find out how to communicate over the Internet, needed to be able to make calls to Calamari's API.&lt;/p&gt;

&lt;p&gt;This, similar to the WiFi connection, is not a complex task since there are libraries that we can use to help us. In this case, I used the library &lt;code&gt;&amp;lt;HTTPClient.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For this first test of how to make HTTP calls I didn't want to mess with Calamari's API just yet, hence I used a service that offers a mock &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer" rel="noopener noreferrer"&gt;REST API&lt;/a&gt; for testing: &lt;a href="https://jsonplaceholder.typicode.com" rel="noopener noreferrer"&gt;JSONPlaceholder&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"HTTPClient.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;HTTPClient&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://jsonplaceholder.typicode.com/posts/1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;httpCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&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="n"&gt;httpCode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error on HTTP request: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I followed &lt;a href="https://www.dfrobot.com/blog-917.html" rel="noopener noreferrer"&gt;this guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With everything set up, I was ready to make requests to the Calamari.io API.&lt;/p&gt;

&lt;p&gt;I created a class to have everything tidier and make the operation easier within the code. I helped myself with &lt;a href="https://www.arduino.cc/en/Hacking/LibraryTutorial" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; to do it. You can see how I built it in the link at the end of the article with the repository on Github.&lt;/p&gt;

&lt;p&gt;To use the class you just need to create an instance and pass four arguments, the base URL of the Calamari.io API, the username and password (information that Calamari provides when you activate the API) and the employee's email (in this case my corporate email).&lt;/p&gt;

&lt;p&gt;The class has six methods available to use. I think the names are understandable enough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shift: &lt;code&gt;shiftIsOn()&lt;/code&gt;, &lt;code&gt;startShift()&lt;/code&gt;, &lt;code&gt;stopShift()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Break: &lt;code&gt;breakIsOn()&lt;/code&gt;, &lt;code&gt;startLunchBreak()&lt;/code&gt;, &lt;code&gt;stopLunchBreak()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After a bit of trial and error, I got everything working. I was only missing the hardware part: a button to start/end the shift 👨🏽‍💻 and another button to start/finish the lunch break 🍕&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%2Fi%2Fft54k17ym4nhlr0yar15.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%2Fi%2Fft54k17ym4nhlr0yar15.png" alt="Final protoype assembly"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The two buttons have one of the pins connected to ground through a resistor, &lt;a href="https://learn.sparkfun.com/tutorials/pull-up-resistors/all" rel="noopener noreferrer"&gt;here you can read&lt;/a&gt; a good explanation of why it is necessary to use these resistors (pull-up or pull-down). The pins on the same side but at the bottom are connected to the GPIO inputs on the board: &lt;code&gt;26&lt;/code&gt; for the first button (the one that starts/ends the shift) and &lt;code&gt;27&lt;/code&gt; for the second button (the one that starts/ends the break). And the right pins are connected to the 3.3V output.&lt;/p&gt;

&lt;p&gt;Finally, I only needed to take care of the code of when the buttons are pressed, so it can perform the necessary action depending on the button pressed.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pushShiftButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;digitalRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pushBreakButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;digitalRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;27&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="n"&gt;pushShiftButton&lt;/span&gt;&lt;span class="p"&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="n"&gt;calamari&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shiftIsOn&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stop shift"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;calamari&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stopShift&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Start shift"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;calamari&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startShift&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&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="n"&gt;pushBreakButton&lt;/span&gt;&lt;span class="p"&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="n"&gt;calamari&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;breakIsOn&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stop lunch break"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;calamari&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stopLunchBreak&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Start lunch break"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;calamari&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startLunchBreak&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&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;When one of the buttons is pressed, for example the lunch break button, it is checked whether the break is currently taking place. If it is, then the method to stop it is called, and if not, the method to start it is called. Then there is a delay of 1 second in the code. This is done because otherwise, the code could be executed multiple times, even if we only pressed the button once since this piece of code is inside a loop that runs faster than it takes to press and remove your finger from the button.&lt;/p&gt;

&lt;p&gt;And this is it, here you can see how it actually works 😁:&lt;/p&gt;

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

&lt;p&gt;And this is the complete code on my Github:&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/jvlobo" rel="noopener noreferrer"&gt;
        jvlobo
      &lt;/a&gt; / &lt;a href="https://github.com/jvlobo/esp32-calamari.io-api" rel="noopener noreferrer"&gt;
        esp32-calamari.io-api
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Clocking in and out in Calamari.io with the ESP32 development board
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Stay tuned for the second part of this project, where I am going to create in 3D and print a box to make this system more compact and portable. I will also install a battery so I don't need to be powering it through the ESP32 USB port.&lt;/p&gt;

&lt;p&gt;Update: Second part is published now! ⬇️&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/jvlobo" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F205333%2F62765e2d-282f-458a-804f-fe6fefb01297.png" alt="jvlobo"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/jvlobo/how-to-make-clock-in-at-work-easier-with-the-esp32-board-part-2-9if" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to make clock-in at work easier with the ESP32 board - Part 2&lt;/h2&gt;
      &lt;h3&gt;JV Lobo ・ Jun 4 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#electronics&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#esp32&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#iot&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>electronics</category>
      <category>esp32</category>
      <category>iot</category>
    </item>
    <item>
      <title>The difficult task of changing your seat while buying a train ticket online</title>
      <dc:creator>JV Lobo</dc:creator>
      <pubDate>Wed, 11 Mar 2020 22:53:24 +0000</pubDate>
      <link>https://dev.to/jvlobo/the-difficult-task-of-changing-your-seat-while-buying-a-train-ticket-online-3h2p</link>
      <guid>https://dev.to/jvlobo/the-difficult-task-of-changing-your-seat-while-buying-a-train-ticket-online-3h2p</guid>
      <description>&lt;p&gt;I'm living in Portugal now. The country has a good railway system and one of the transportation ways I like the most when I travel is the train, which makes it a great choice for me to move around.&lt;/p&gt;

&lt;p&gt;I wanted to travel to the south of the country so I decided to book a ticket with the state-owned train company: &lt;a href="https://cp.pt/"&gt;Comboios de Portugal&lt;/a&gt; and here is where my adventure begins.&lt;/p&gt;

&lt;p&gt;The searching and selection process is quite easy and friendly but when I had to pick my seat is when things got interesting: it doesn't work!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_svN5JsO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a0m3612ot502ew9eox13.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_svN5JsO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a0m3612ot502ew9eox13.gif" alt="Trying to select another seat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I refused to buy my ticket with the seat that you get assigned by default. I always like to choose one in which both of them are free, knowing that someone can buy the ticket for the seat next to me, but if I'm lucky nobody will get the one next to me and I will travel more comfortably.&lt;/p&gt;

&lt;p&gt;As a developer myself, I opened one of the best tools that we have at our disposal when we are building a website: &lt;a href="https://developers.google.com/web/tools/chrome-devtools"&gt;Chrome Developer Tools&lt;/a&gt; in the hope of being able to dig a bit into the code and see what the problem was. Luckily for me, the web's Javascript code doesn't have any kind of &lt;a href="https://dev.to/zicsus/writing-simple-obfuscation-and-minification-system-3395"&gt;minification or obfuscation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first thing I did was to look at the  click event listeners for the seats:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MOsQOaLy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/50eavx2g9zwlt6p9lq3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MOsQOaLy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/50eavx2g9zwlt6p9lq3j.png" alt='Click Event Listeners for the &amp;lt;a href="#?!"&amp;gt; elements on each seat'&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I see that there are two events listening to the click of this button (I'm not interested in all the others in jQuery or Bootstrap). This is the code of each one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x8jJA0PW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zkdeh7159ce374m8a9gf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x8jJA0PW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zkdeh7159ce374m8a9gf.png" alt="Button click event listeners code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of the two I see, the one that catches my attention is the second one since it calls a function &lt;code&gt;pickSeat()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DYncw49V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/otjpje1622w59z25p4tm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DYncw49V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/otjpje1622w59z25p4tm.png" alt="pickSeat function code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setting a breakpoint on the first line of this function, when I click on one of the entries I see that the &lt;code&gt;changeable&lt;/code&gt; variable is &lt;code&gt;true&lt;/code&gt; and it goes inside the conditional block. The first function called is &lt;code&gt;getSeatIndex()&lt;/code&gt; passing the seat as a parameter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DC0xYOh7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r715xt194h7cl7byw7b3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DC0xYOh7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r715xt194h7cl7byw7b3.png" alt="getSeatIndex function code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the seat is not found inside the array &lt;code&gt;seats&lt;/code&gt; this function will return &lt;code&gt;-1&lt;/code&gt;. As my intention is to enter inside the following condition in the main function &lt;code&gt;pickSeat()&lt;/code&gt;, when it is inside the function of &lt;code&gt;getSeatIndex()&lt;/code&gt; I manually add the seat that I want to select inside the &lt;code&gt;seats&lt;/code&gt; array:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MvRwDlh6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tmqgdmn7g0tc4n2fac7f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MvRwDlh6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tmqgdmn7g0tc4n2fac7f.gif" alt="Modifying the array on execution time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the execution of the code reaches the line &lt;code&gt;if(!changing &amp;amp;&amp;amp; idx! = -1) {&lt;/code&gt;, since we have modified the function &lt;code&gt;getSeatIndex()&lt;/code&gt; the variable &lt;code&gt;idx&lt;/code&gt; has a value of &lt;code&gt;1&lt;/code&gt; which is different from &lt;code&gt;-1&lt;/code&gt; and the variable &lt;code&gt;changing&lt;/code&gt; is still &lt;code&gt;false&lt;/code&gt; then it executes the code inside the conditional, which was what I was looking for.&lt;/p&gt;

&lt;p&gt;When the execution of the &lt;code&gt;pickSeat()&lt;/code&gt; function finishes I can see how the color of the seat changes to a light gray:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R2DMctkL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/t4adh9w7zfx89hog1efo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R2DMctkL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/t4adh9w7zfx89hog1efo.png" alt="Seat selected through code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After these steps, naive of me I was expecting to continue with the process having my new seat selected, but when I click on next I get this error message:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8hs51Xkl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/29kwpsvg5sstsgp2prbn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8hs51Xkl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/29kwpsvg5sstsgp2prbn.png" alt="Please select a seat error message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🤔 Looks like it was not going to be as easy as I expected.&lt;/p&gt;

&lt;p&gt;This message is displayed once you click on &lt;code&gt;Next route&lt;/code&gt; (since it is a round trip ticket, I also have to select the seat for the return trip) so the next thing I do is to inspect the button. Like I did with the buttons on the seats I check the &lt;code&gt;Event Listeners&lt;/code&gt; section, but for this button, I find nothing interesting.&lt;/p&gt;

&lt;p&gt;However, when looking at the HTML element I find that a function is being called when the button is clicked:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d3HyEcrY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o9b9qurwznzao4wxsf6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d3HyEcrY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o9b9qurwznzao4wxsf6e.png" alt="HTML element onclick event"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With no time to waste, I go back to the Javascript code to see what is happening inside this &lt;code&gt;change()&lt;/code&gt; function&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WWH8YfoV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/siriukvn6q1hk7ay58nw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WWH8YfoV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/siriukvn6q1hk7ay58nw.png" alt="Function in charge of doing the change of seat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The message I was seeing before was because the &lt;code&gt;changing&lt;/code&gt; variable has a value of &lt;code&gt;true&lt;/code&gt;, so inside the &lt;code&gt;change()&lt;/code&gt; function that first conditional is being executed showing the message and returning &lt;code&gt;false&lt;/code&gt;.&lt;br&gt;
Just before this first &lt;code&gt;if&lt;/code&gt; I change the value to &lt;code&gt;false&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E6Y6vAbZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0spp6608njfkfop0fkum.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E6Y6vAbZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0spp6608njfkfop0fkum.gif" alt="Changing the var value to false"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I finish the code execution with the hope that now I would be able to move on to the next step with my selected seat but ... no!&lt;/p&gt;

&lt;p&gt;Now an error message appears on the console:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jEt--Xfd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k4tn23ktoviltamh4tro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jEt--Xfd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k4tn23ktoviltamh4tro.png" alt="Javascript error in the console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Something is broken now 😰. &lt;br&gt;
I see that the error comes from the &lt;code&gt;sameSeats()&lt;/code&gt; function which is the one called within the &lt;code&gt;change()&lt;/code&gt; function in the second &lt;code&gt;if&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HHw4VWVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7u28zx8ukq7c25unwpk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HHw4VWVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7u28zx8ukq7c25unwpk0.png" alt="sameSeats function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seeing the code of this function and the error, seems clear what is happening. It is trying to use &lt;code&gt;split&lt;/code&gt; in one of the elements of the &lt;code&gt;seats&lt;/code&gt; array or the &lt;code&gt;oldSeats&lt;/code&gt; array, and possibly using an index outside the array. Since the &lt;code&gt;for&lt;/code&gt; loop goes from &lt;code&gt;0&lt;/code&gt; until the size of the array &lt;code&gt;seats&lt;/code&gt;, I'm going to assume that this array is correct, so the error would be in the line&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var a2 = oldSeats[x].split('_');&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To confirm this I debug the code again.&lt;br&gt;
If I add these two variables to the &lt;em&gt;Watch&lt;/em&gt; section I can see how, indeed, my guess is correct:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cwpbnix4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2sva8iy5ml883al5kf4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cwpbnix4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2sva8iy5ml883al5kf4i.png" alt="Adding variables to the watch section"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the breakpoint on the line &lt;code&gt;199&lt;/code&gt;, as shown in the screenshot, I go to the console and type &lt;code&gt;oldSeats.push('184_4_64')&lt;/code&gt; so that the &lt;code&gt;sameSeats()&lt;/code&gt; function doesn't fail this time and returns &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally the &lt;code&gt;doChange()&lt;/code&gt; function is executed. This function is responsible for calling another one, which is the one that makes the actual change of the seat:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EB5sFimi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lwybm2rvnm2h8enenmdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EB5sFimi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lwybm2rvnm2h8enenmdg.png" alt="changeTripSeatsValue function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this function, I put a breakpoint on the last line, which seems to be the important one since it is responsible for assigning the new seat as the value of an item with &lt;code&gt;tripSeats&lt;/code&gt; id (I guess it is an &lt;code&gt;input&lt;/code&gt;, possibly hidden, within a &lt;code&gt;form&lt;/code&gt; element).&lt;/p&gt;

&lt;p&gt;When the debugger stops in this line, I see how &lt;code&gt;newValue&lt;/code&gt; has a slightly strange value assigned, so I decide to change it to the value of the seat I am trying to select, and by continuing with the execution of the code ... bingo!&lt;/p&gt;

&lt;p&gt;I have finally been able to select my seat :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i8-EwJoS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iqcjo64t5kdlv8ad2436.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i8-EwJoS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iqcjo64t5kdlv8ad2436.gif" alt="My seats is finally selected"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;My purpose with this post is to document how I do a JavaScript code debugging process using Google Chrome developer tools. I think it is an interesting and very important process for any front-end developer.&lt;/p&gt;

&lt;p&gt;In this case in particular with the Comboios de Portugal website, using vanilla Javascript (and some jQuery) and with a fairly easy to follow code, it has been a fun task because it is a code that I haven't written. This makes it more interesting and I took it as a challenge.&lt;/p&gt;

&lt;p&gt;The funniest thing comes now: after having done all this process and having been able to select my seat I have continued testing things on this website and at one point I saw this message:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HCzmtSoo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wgoxytz13uhyfxo8oe3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HCzmtSoo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wgoxytz13uhyfxo8oe3e.png" alt="You have to deselect your current seat and select the new one"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In summary... the selection of seats works so that you have to click first on the seat that you have been assigned automatically and then click on one of the empty seats. And yes, doing so works perfectly 🤦🏽‍♂️&lt;/p&gt;

&lt;p&gt;I may be very clumsy, but since no one likes to accept his clumsiness I began to check other pages where you can book train and plane tickets. It turns out that in all the ones I tried the selection of seats is done in the way that I was instinctively trying: you just need to click on the empty seat.&lt;/p&gt;

&lt;p&gt;In my opinion, this is the friendliest or easiest way to do it and the one that a person will instinctively try. I think it's a big &lt;a href="https://hackernoon.com/what-is-ui-ux-design-1f01e9dbbf02"&gt;UX&lt;/a&gt; issue on this specific page.&lt;/p&gt;

&lt;p&gt;Anyway, and despite the fact that my entire process to select the seat was not necessary, I had a lot of fun and I ended up being satisfied to have been able to achieve that "challenge".&lt;/p&gt;

&lt;p&gt;I really like programming and technology, that is why I created &lt;a href="https://codetalks.tv"&gt;CodetalksTV&lt;/a&gt; with a friend of mine.&lt;br&gt;
I also wrote a &lt;a href="https://dev.to/jvlobo/building-a-side-project-codetalks-tv-19po"&gt;post on dev.to&lt;/a&gt; a while ago talking about how and why we built it. Check it out if you want to know more :)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>debugging</category>
      <category>frontend</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Building a side project: Codetalks.tv</title>
      <dc:creator>JV Lobo</dc:creator>
      <pubDate>Fri, 02 Aug 2019 09:30:13 +0000</pubDate>
      <link>https://dev.to/jvlobo/building-a-side-project-codetalks-tv-19po</link>
      <guid>https://dev.to/jvlobo/building-a-side-project-codetalks-tv-19po</guid>
      <description>&lt;h1&gt;
  
  
  🤓 What is Codetalks?
&lt;/h1&gt;

&lt;p&gt;As programmers, we know how important it is to be up to date in terms of programming languages, frameworks, methodologies and tools in general. We must always be in continuous learning. One of the best ways to stay up-to-date is by attending technology conferences and events, but many of these events are not in our city or we simply cannot attend. The positive part is that most of these events are recorded and are available for free through different video platforms (mainly Youtube or Vimeo), which is great, but there are a couple of problems:&lt;/p&gt;

&lt;p&gt;❌ There are plenty of interesting events and talks around the world every week and it’s hard to be aware that they exist.&lt;/p&gt;

&lt;p&gt;❌ Each event is on a different date and is published on different accounts and video platforms, which makes it very complicated to track the events that interest us.&lt;/p&gt;

&lt;p&gt;That’s why we decided to create &lt;a href="https://codetalks.tv"&gt;Codetalks.tv&lt;/a&gt;, a &lt;strong&gt;platform for developers &lt;br&gt;
that brings together the best programming talks around the world in one place.&lt;/strong&gt; Each video is grouped by tags and event so that it is incredibly easy to discover conferences, watch lectures and keep learning.&lt;/p&gt;

&lt;h1&gt;
  
  
  📋 What should our MVP have?
&lt;/h1&gt;

&lt;p&gt;Considering that this is a MVP (minimum viable product) we wouldn’t want to extend the development time too much, therefore, we tried to identify the key functionalities that would give meaning to the project, in this way we could validate if our idea made sense or not before continuing to invest more time and effort in it. The characteristics we identified as most important were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Talks finder&lt;/li&gt;
&lt;li&gt;View talks by tag&lt;/li&gt;
&lt;li&gt;View talks by event&lt;/li&gt;
&lt;li&gt;View available tags&lt;/li&gt;
&lt;li&gt;View existing events&lt;/li&gt;
&lt;li&gt;Send talks (Youtube &amp;amp; Vimeo)&lt;/li&gt;
&lt;li&gt;Subscribe to a specific tag&lt;/li&gt;
&lt;li&gt;Receive feedback and ideas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As for the design, it had to be simple and intuitive. It didn’t make sense to create anything new and extravagant and that’s why we opted for a design similar to that of Youtube, so that anyone can instantly feel familiar with it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5fM9CO5Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ct4pgjzing2753s264wa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5fM9CO5Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ct4pgjzing2753s264wa.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Focusing more on the look and feel, we decided to make a small wink to our potential users, the developers, for this reason, we gave it the appearance of a code editor (VS Code?), and even… we used the famous Monokai color palette.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Shr9xynm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/k8xckyv2olob57tkdf0c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Shr9xynm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/k8xckyv2olob57tkdf0c.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🛠 Let’s get to work
&lt;/h1&gt;

&lt;p&gt;And it’s time to code!&lt;/p&gt;

&lt;p&gt;One of the interesting things about a side-project is that you can afford to experiment and try new things out, so, we didn’t want to miss this opportunity.&lt;/p&gt;

&lt;p&gt;Here is a brief summary of the technology stack we used, both for the backend and for the frontend. If you find it interesting, we will publish more articles explaining part of the development process in more detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/facebook/create-react-app"&gt;Create React App&lt;/a&gt;: Create React apps with no build configuration&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/apollographql/apollo-client"&gt;Apollo&lt;/a&gt;: The perfect partner for GraphQL. The client is designed to help you quickly build a UI that fetches data with GraphQL.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.styled-components.com/"&gt;Styled-Components&lt;/a&gt;: A very popular CSS-in-JS styling library that uses tagged template literals in JavaScript and the awesome power of CSS to provide a platform that allows you to write actual CSS code to style your components.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Other libraries or tools that have helped us a lot:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/storybooks/storybook"&gt;Storybook&lt;/a&gt;: Open source tool for developing and organize UI components&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sampotts/plyr"&gt;Plyr&lt;/a&gt;: This library is gold. It allows us to embed videos from YouTube or Vimeo, and customize them completely: Put our logo, remove the buttons from the original platform … etc..&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jaredpalmer/formik"&gt;Formik&lt;/a&gt;: To create forms in a simple way (Everybody hates forms, right?). It is very useful used together with &lt;a href="https://github.com/jquense/yup"&gt;Yup&lt;/a&gt;, an input validation library.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Qix-/color#readme"&gt;Color&lt;/a&gt;: This is another simple library to perform small operations with colors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/prisma/graphql-yoga"&gt;GraphQL-Yoga&lt;/a&gt;: Fully-featured GraphQL Server based in Express&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.prisma.io/"&gt;Prisma&lt;/a&gt;: Prisma is a database abstraction layer that turns your databases into GraphQL APIs with CRUD operations and realtime capabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Third party tools:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sentry.io/welcome/"&gt;Sentry&lt;/a&gt;: This is the tool we use to receive errors that occur both in frontend and backend. In this way we can eliminate the small bugs that arise.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mailchimp.com/"&gt;Mailchimp&lt;/a&gt;: This is how users can subscribe to receive the latest videos from a tag, when they do so their email account is added to a Mailchimp list and from there we can then send the weekly summary of the best videos.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cyfe.com/"&gt;Cyfe&lt;/a&gt;: we use Cyfe to have in one place information from different parts of the platform. For example, we have a panel for Analytics, and another to see the number of users and videos we have on the platform. We can continue to add data and internal information from the platform to have it all in one place.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.typeform.com/"&gt;Typeform&lt;/a&gt;: we use Typeform to receive feedback from users because it is a simple and quick way to implement it and have it integrated with Slack to receive information instantly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then came the moment of truth…&lt;/p&gt;

&lt;h1&gt;
  
  
  🚀 The launch
&lt;/h1&gt;

&lt;p&gt;The truth is that if we are taken out of the technical or product part we will feel like a fish out of water, one could say that marketing is not our strong point. That’s why, to define our launch strategy, we simply asked ourselves a question: Where are our potential users?, and based on the answers we found, we drew up a list of possible acquisition channels:&lt;/p&gt;

&lt;h3&gt;
  
  
  ☠ Big portals (Disaster):
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Product Hunt:&lt;/strong&gt; We tried to follow all the advice we read by different blogs regarding a successful launch in PH, we knew it was very important and one of the keys to the launch, however we only got &lt;a href="https://www.producthunt.com/posts/codetalks-tv"&gt;9 upvotes&lt;/a&gt; (very sad).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hacker News:&lt;/strong&gt; We only got &lt;a href="https://news.ycombinator.com/item?id=19349321"&gt;4 points&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reddit:&lt;/strong&gt; We sent it to the subreddit &lt;a href="https://www.reddit.com/r/programming/"&gt;r/programming&lt;/a&gt;. It wasn’t published either.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, and after a truly horrible initial release, we wondered if &lt;a href="https://codetalks.tv"&gt;Codetalks&lt;/a&gt; actually made sense, are we really solving a problem and bringing something to the community? our motivation crashed.&lt;/p&gt;

&lt;p&gt;However, after a few days of decline, we decided to continue trying in other ways and this time, fortunately, it was better:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✌ ️Niche media (Not bad):
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blogs for devs:&lt;/strong&gt; We have appeared in several important blogs in the sector, which has brought us very qualified traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Devs Newsletters:&lt;/strong&gt; We have been quoted in several newsletters, many of them with tens or hundreds of thousands of subscribers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twitter:&lt;/strong&gt; Since the beginning, it has been a great ally, we get a lot of traffic through this social network, partly due to a very cool bot we have developed that posts talks and mentions speakers all day long (this is for another post).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite not having had a spectacular launch, we have seen over the last month how traffic has been increasing day after day steadily. In addition, we have received a lot of positive feedback, so the general feeling is that people like it, and although we think we have not reached product-market-fit yet, we do believe that we are going in the right direction and that it is worth continuing to invest some more time.&lt;/p&gt;

&lt;p&gt;In addition, we have a few very cool ideas for version 2.0, and…. why not, we’ll make another release later with lessons learned, maybe this time we’ll be luckier hehehe.&lt;/p&gt;

&lt;h1&gt;
  
  
  🎓 What we learnt
&lt;/h1&gt;

&lt;p&gt;If we had to draw some key lessons, these would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attempt to &lt;strong&gt;resolve a real problem&lt;/strong&gt;, a pain that you have detected in your own flesh. In this way, you will be your own target client and you will know what you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep things simple.&lt;/strong&gt; Don’t go crazy with the technology stack or the features that the MVP should have. Try to launch quickly and validate your idea as soon as possible.&lt;/li&gt;
&lt;li&gt;Since you’re doing a side-project, &lt;strong&gt;try to learn something new&lt;/strong&gt; along the way. If the project finally fails, you will at least take with you new knowledge and something interesting to add to your portfolio.&lt;/li&gt;
&lt;li&gt;Don’t be discouraged if your project doesn’t receive all the attention you expected at the beginning, it could be for different reasons. &lt;strong&gt;Be patient.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listen to your audience&lt;/strong&gt; and try to improve your product little by little.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make lots of launches&lt;/strong&gt;. Consider each new feature you add to the product as a new opportunity to make a new launch and get attention.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sideprojects</category>
      <category>graphql</category>
      <category>react</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
