<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Juanda Martínez</title>
    <description>The latest articles on Forem by Juanda Martínez (@juandadev).</description>
    <link>https://forem.com/juandadev</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%2F385128%2F1ed99551-de2b-428b-b520-448209989517.jpg</url>
      <title>Forem: Juanda Martínez</title>
      <link>https://forem.com/juandadev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/juandadev"/>
    <language>en</language>
    <item>
      <title>I built the ultimate Pokédex and would love you to try it!</title>
      <dc:creator>Juanda Martínez</dc:creator>
      <pubDate>Fri, 05 Sep 2025 21:10:59 +0000</pubDate>
      <link>https://forem.com/juandadev/i-built-the-ultimate-pokedex-and-would-love-you-to-try-it-472l</link>
      <guid>https://forem.com/juandadev/i-built-the-ultimate-pokedex-and-would-love-you-to-try-it-472l</guid>
      <description>&lt;p&gt;Four years ago, while playing Pokémon, I realized that I could memorize a lot of stuff like my SSN or my EIN... but not the &lt;strong&gt;Pokémon type chart&lt;/strong&gt;. Every match, I had to pause, open a wiki, search weaknesses, check evolution chains, among all crappy useless information that only made me &lt;strong&gt;waste more time scrolling down&lt;/strong&gt; to the exact info I wanted.&lt;/p&gt;

&lt;p&gt;So as a web dev, I decided that I could build my own tools for my personal use, so why not create a web app that solve this issue for me? having this kind of information I cared about in a single place, without wasting too much effort on &lt;code&gt;Googling a Pokémon → Open a wiki link → Scroll up/down many times → Find the info I wanted → Click more links bc I needed more info → Repeat&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And that's how &lt;strong&gt;Pokémon Stats&lt;/strong&gt; was born: a small MVP using &lt;strong&gt;PokéAPI&lt;/strong&gt; + &lt;strong&gt;Bootstrap&lt;/strong&gt;, quickly fetching Pokémon's evolution chains, evolution details, a type chart, and a basic search bar to enter the Pokémon name. Nothing fancy if you ask me, and made for &lt;em&gt;casual players&lt;/em&gt; (just like me).&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%2Fo44vp1ghqzu5wmok88am.webp" 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%2Fo44vp1ghqzu5wmok88am.webp" alt="First version of Pokémon Stats" width="800" height="669"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I bought a domain and hosted the site directly with &lt;em&gt;Vercel&lt;/em&gt;, because I wanted to feel this like a sophisticated web app, and from that I just've been pushing small updates with stuff that I wanted to improve in the user experience while playing Pokémon games.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fast-forward to today&lt;/strong&gt;: I’ve completely redesigned the project from the ground up. Same idea, but &lt;em&gt;cleaner&lt;/em&gt;, &lt;em&gt;faster&lt;/em&gt;, and built with the stack I actually enjoy using: &lt;strong&gt;Next.js, React, Tailwind, shadcn/ui)&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A redesigned &lt;strong&gt;type effectiveness chart&lt;/strong&gt; (interactive, mobile-friendly).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;search system with suggestions&lt;/strong&gt; and &lt;strong&gt;keyboard navigation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved evolution chains&lt;/strong&gt;, including special cases (stones, time of day, trades, etc.).&lt;/li&gt;
&lt;li&gt;Support for &lt;strong&gt;regional forms and variants&lt;/strong&gt; (Alola, Galar, etc.).&lt;/li&gt;
&lt;li&gt;High-quality official artwork with fallback sprites.&lt;/li&gt;
&lt;li&gt;A roadmap and contributors page, because now it’s &lt;strong&gt;open source&lt;/strong&gt;!&lt;/li&gt;
&lt;/ul&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%2F4z2ju9ru64zu89ib1wmm.webp" 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%2F4z2ju9ru64zu89ib1wmm.webp" alt="Pokémon Stats redesigned" width="800" height="843"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters to me
&lt;/h2&gt;

&lt;p&gt;This project isn’t the most complex I’ve ever built, but it’s the one I’ve loved the most. It started as a personal tool, grew through trial and error, and turned into something I still actively use while playing. I’ve put a lot of effort (and coffee) into making it not just functional but actually enjoyable to look at and use.&lt;/p&gt;

&lt;p&gt;It’s free, it’s open, and if you’re a Pokémon fan (or just like checking out passion projects), I’d love for you to try it: &lt;a href="https://pokemonstats.com" rel="noopener noreferrer"&gt;pokemonstats.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also peek at the source, file an issue, or even contribute: &lt;a href="https://github.com/juandadev/pokemonstats" rel="noopener noreferrer"&gt;GitHub - juandadev/pokemonstats&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>📬 My First Waitlist: Lessons From a Side Project Experiment</title>
      <dc:creator>Juanda Martínez</dc:creator>
      <pubDate>Fri, 25 Jul 2025 00:59:17 +0000</pubDate>
      <link>https://forem.com/juandadev/my-first-waitlist-lessons-from-a-side-project-experiment-1c3</link>
      <guid>https://forem.com/juandadev/my-first-waitlist-lessons-from-a-side-project-experiment-1c3</guid>
      <description>&lt;p&gt;Not gonna lie, creating a waitlist for my side project wasn’t strictly necessary, but it was fun, insightful, and a great excuse to learn something new.&lt;/p&gt;

&lt;p&gt;This post isn’t about building a revolutionary app (not yet). It’s about using your side projects as a sandbox to experiment, explore, and grow.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It All Started
&lt;/h2&gt;

&lt;p&gt;Lately, I’ve been quite active on X/Twitter. I follow a lot of indie devs who build amazing projects and share everything publicly, what we now call &lt;strong&gt;building in public&lt;/strong&gt;. I’ve always wanted to do the same, so I even bought the blue checkmark to commit to this journey.&lt;/p&gt;

&lt;p&gt;One trend I kept seeing was the use of &lt;strong&gt;waitlists&lt;/strong&gt;, where users can leave their email to get notified when a product launches. It's like a teaser trailer for a movie or the release announcement of a huge videogame like GTA VI, it builds &lt;em&gt;hype&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Two stories really inspired me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://athas.dev/" rel="noopener noreferrer"&gt;Athas.dev&lt;/a&gt;, an open source code editor that even caught the attention of the one and only Guillermo Rauch, CEO of Vercel.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://x.com/mazeincoding" rel="noopener noreferrer"&gt;Maze&lt;/a&gt;, who built an open source CapCut alternative. His waitlist blew up to over 500k signups (including a massive bot attack!).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  So, What Did I Do?
&lt;/h2&gt;

&lt;p&gt;Even though I’m not working on a fancy SaaS or groundbreaking tool for devs, I decided to make a waitlist for an app I started 4 years ago: &lt;strong&gt;&lt;a href="https://www.pokemonstats.com/" rel="noopener noreferrer"&gt;Pokémon Stats&lt;/a&gt;&lt;/strong&gt;, a simple tool to check Pokémon evolutions and type weaknesses. I originally made it for myself to avoid bouncing around wikis while playing.&lt;/p&gt;

&lt;p&gt;Every time I picked up a new Pokémon game, I’d tweak the app and add improvements. This time, as I returned to my dusty Pokémon Let’s Go save file, I set myself the challenge of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Redesigning the app from scratch.&lt;/li&gt;
&lt;li&gt;Temporarily shutting down the old version and replacing it with a landing page + waitlist.&lt;/li&gt;
&lt;li&gt;Using this commitment to learn new things and hold myself accountable (even if just two people sign up, I can’t let them down!).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Now the Fun Part, How I Protected the Waitlist
&lt;/h2&gt;

&lt;p&gt;I didn’t want just another form. I learned from others' mistakes and added real protections against spam and bots. Here's a quick breakdown:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. CSRF Token Protection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I generate a unique CSRF token server-side, only if the request comes from an authorized host.&lt;/li&gt;
&lt;li&gt;The token is signed using a secret key stored in an environment variable.&lt;/li&gt;
&lt;li&gt;It’s saved in a cookie and expires after 1 hour.&lt;/li&gt;
&lt;li&gt;Every &lt;code&gt;POST&lt;/code&gt; request must include and validate this token. If it’s missing or invalid, the server throws an error.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Bot Detection with Vercel BotID
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Works like an invisible reCaptcha.&lt;/li&gt;
&lt;li&gt;Analyzes user interaction to determine if it’s a bot, validated both on the frontend and backend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love to say I understand how BotID works under the hood, but honestly… I just followed the docs. Might write a deep-dive post in the future once I get it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. (Missing) Rate Limiter
&lt;/h3&gt;

&lt;p&gt;Didn’t implement it... yet. But it’s something I’d like to explore, even if I don’t expect much traffic. It’s all part of the learning process.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Was it necessary? Nope.&lt;br&gt;&lt;br&gt;
Did I learn something? Absolutely.&lt;br&gt;&lt;br&gt;
Was it fun? Totally.&lt;/p&gt;

&lt;p&gt;Your side projects don’t need to change the world. They just need to teach you something new.&lt;/p&gt;

&lt;p&gt;So if you’re into Pokémon, feel free to join the waitlist, star the repo, or check out the code (yep, it’s open source). I’d love to hear your thoughts and feedback!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devjournal</category>
      <category>learning</category>
    </item>
    <item>
      <title>Building pagination with Prisma felt… unnecessarily complex</title>
      <dc:creator>Juanda Martínez</dc:creator>
      <pubDate>Thu, 19 Jun 2025 15:49:00 +0000</pubDate>
      <link>https://forem.com/juandadev/building-pagination-with-prisma-felt-unnecessarily-complex-3ab9</link>
      <guid>https://forem.com/juandadev/building-pagination-with-prisma-felt-unnecessarily-complex-3ab9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a translated version of the &lt;a href="https://www.juanda.dev/blog/prisma-y-la-paginacion-una-reflexion-sobre-optimizacion-y-prioridades" rel="noopener noreferrer"&gt;original post&lt;/a&gt; published in my Spanish blog. The translation was generated using ChatGPT and manually reviewed for clarity and accuracy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Recently, I decided to revisit my fullstack side and start building small projects again — each one with increasing technical complexity. Motivated by development speed and convenience (and because I really wanted to get my self-hosted blog launched ASAP), I asked chatGPT for some tech stack suggestions. I went ahead with Prisma, a very popular ORM for working with databases in JavaScript.&lt;/p&gt;

&lt;p&gt;Everything was going pretty well… until it was time to implement a very basic feature: result pagination.&lt;/p&gt;

&lt;p&gt;I didn’t have much time to dedicate to that feature at that moment, so I went into &lt;em&gt;vibe coder&lt;/em&gt; mode and asked chatGPT for help. It generated a query using Prisma that included some properties I wasn’t familiar with, and the code looked a bit suspicious. So, I did what I always do — I checked the official docs to verify everything and to see how to properly get the total record count.&lt;/p&gt;

&lt;p&gt;To my surprise, I discovered something unexpected: &lt;strong&gt;Prisma doesn’t have a built-in method to return both the data and the total count in a single query!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, you read that right. If you want to paginate and also show the total number of records, you have to run two separate queries — one to get the paginated results and another to count the total number of items. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&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;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&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;count&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;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine the mess this becomes when you start adding filters, joins, and other conditions... it's a nightmare!&lt;/p&gt;

&lt;p&gt;This really caught my attention — especially coming from frontend development, where we're always thinking about performance and keeping things snappy for the user. I dug a little deeper and found &lt;a href="https://github.com/prisma/prisma/issues/7550" rel="noopener noreferrer"&gt;this issue&lt;/a&gt;, where people have been asking for a &lt;code&gt;findManyAndCount&lt;/code&gt; feature.&lt;/p&gt;

&lt;p&gt;For a second I felt that nostalgic happiness from the old days of googling your errors and landing on a StackOverflow thread where someone had the &lt;em&gt;exact&lt;/em&gt; same problem... but that joy quickly faded when I saw the issue was still marked as &lt;em&gt;Open&lt;/em&gt; 😣 — and even worse, it’s been open since &lt;strong&gt;2021&lt;/strong&gt; 💀&lt;/p&gt;

&lt;p&gt;Reading through the comments, I realized I wasn’t alone. Many users with larger systems and more complex pagination needs were also frustrated. Some of the workarounds mentioned include using &lt;code&gt;prisma.$transaction&lt;/code&gt;, which is better organized but executes sequentially and is slower (especially with big datasets):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;]&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;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$transaction&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&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;A faster alternative would be using &lt;code&gt;Promise.all&lt;/code&gt; to execute both queries in parallel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&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;However, someone pointed out an important detail in the issue thread: while those approaches work for simple use cases, there’s a data consistency risk. What if an &lt;code&gt;INSERT&lt;/code&gt; or &lt;code&gt;DELETE&lt;/code&gt; happens between those two queries? You could end up with mismatched results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Total count = 5
- Returned elements = 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That reminded me of something I read a while ago: no matter how friendly an ORM is, it will never fully replace raw SQL — especially when you need full control and optimization. (Unfortunately, I couldn’t find the tweet again, but that idea stuck with me.)&lt;/p&gt;

&lt;p&gt;This whole experience also got me wondering: have Prisma and similar tools actually become more popular lately, or is this just the classic illusion where once you start using something, you start seeing it everywhere? Kind of like when you buy a car and suddenly that same model is on every street corner. Funny how that works.&lt;/p&gt;

&lt;p&gt;In the end, this doesn't affect me too much for my current use case since I’m just paginating a small dataset for my blog. But it definitely made me think more carefully about the tools I choose — and how even seemingly basic features should never be taken for granted.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💭 This reminded me of a similar story: a while ago, we had to pick a tool for unit testing on the frontend. I pushed for &lt;em&gt;React Testing Library&lt;/em&gt; because I was more familiar with it, but for various reasons, we ended up using &lt;em&gt;Cypress&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The project involved heavy use of &lt;code&gt;iframes&lt;/code&gt;... and turns out, &lt;em&gt;Cypress&lt;/em&gt; has no elegant way of handling those in tests. And guess what? I found &lt;a href="https://github.com/cypress-io/cypress/issues/136" rel="noopener noreferrer"&gt;this issue&lt;/a&gt; dating back to &lt;strong&gt;2016&lt;/strong&gt;, filled with people also disappointed to find out how hard it is to test iframes.&lt;/p&gt;

&lt;p&gt;That was the &lt;em&gt;first&lt;/em&gt; time I learned the importance of checking tool limitations. Prisma’s pagination problem is officially my &lt;em&gt;second&lt;/em&gt; reminder. So I'm obliged not to make the same mistake a third time!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, I’d really love open a discussion and hear from others:&lt;/p&gt;

&lt;p&gt;Have you experienced something similar with Prisma or any other ORM? Do you think raw SQL is still necessary for cases like this? How do you evaluate tradeoffs when choosing your stack?&lt;/p&gt;

&lt;p&gt;Drop your thoughts in the comments — these small (but critical) engineering decisions deserve more discussion.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>discuss</category>
      <category>webdev</category>
      <category>prisma</category>
    </item>
    <item>
      <title>⚛️ When React Context API Turns Against You: A Late-Night Debugging Story</title>
      <dc:creator>Juanda Martínez</dc:creator>
      <pubDate>Fri, 06 Jun 2025 23:31:00 +0000</pubDate>
      <link>https://forem.com/juandadev/when-react-context-api-turns-against-you-a-late-night-debugging-story-3bkf</link>
      <guid>https://forem.com/juandadev/when-react-context-api-turns-against-you-a-late-night-debugging-story-3bkf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a translated version of the &lt;a href="https://www.juanda.dev/blog/de-props-a-context-y-de-ahi-al-desastre-errores-que-me-ensenaron-mas-que-el-codigo" rel="noopener noreferrer"&gt;original post&lt;/a&gt; published in my Spanish blog. The translation was generated using ChatGPT and manually reviewed for clarity and accuracy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It was 2:41 AM. Procrastination had sneaked into my sprint without warning, and suddenly, the night before the deadline, I found myself buried under a mountain of work. The reason? A massive refactor that, to be honest, no one asked for.&lt;/p&gt;

&lt;p&gt;Just like the meme, I had big dreams of refactoring the component I’ve been working on. The opportunity came when someone on my team proposed building a "Generic Framework" to speed up the integration of third-party tools (I can’t share details, but it’s probably been the most ambitious project of my career). So, I jumped at the chance and proposed several long-overdue refactor tickets.&lt;/p&gt;

&lt;p&gt;What I didn’t realize was that I was setting a trap for myself… Yes, these refactors solved real problems, but they also included extra steps to fix the messy techniques I used back when I joined the company and was a bit more inexperienced. I was also finally tackling a lot of the technical debt that only I knew existed 😅. Still, I’ve learned a lot and feel like I leveled up, so I wanted to document the experience.&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%2Fbx53leqw75dof0xty4u0.webp" 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%2Fbx53leqw75dof0xty4u0.webp" alt="Big plans beavers meme" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At that moment, I was hating my life, struggling to stay awake, and also struggling with React’s &lt;strong&gt;Context API&lt;/strong&gt;. I had created multiple contexts, nested &lt;code&gt;Providers&lt;/code&gt; like there was no tomorrow, and packed complex logic into &lt;code&gt;reducers&lt;/code&gt;. Everything looked clean, sure, but that infamous ✨gut feeling✨ kicked in: something wasn’t right.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Am I abusing context?&lt;/em&gt; I asked myself. &lt;em&gt;Do I really need to have almost **everything&lt;/em&gt;* in global state?*&lt;/p&gt;

&lt;p&gt;Half-asleep and in need of external validation, I turned to AI instead of Reddit (time crunch). &lt;strong&gt;Spoiler: yes&lt;/strong&gt;, it’s a problem in most cases. As it turns out, no surprise here: any component that consumes a specific context will re-render—even if it doesn’t directly use the value that changed. I had forgotten all about that. I was just trying to avoid prop-drilling at all costs, but overusing any technique will always come with side effects.&lt;/p&gt;

&lt;p&gt;So to back up my suspicion, I needed visual proof. I knew what the outcome would be, but still—always question everything, even your own assumptions. Like any seasoned dev, I debugged the re-renders with a trusty &lt;code&gt;console.log&lt;/code&gt;.&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%2Fbm79k85zqa7zmv3a4jy7.webp" 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%2Fbm79k85zqa7zmv3a4jy7.webp" alt="Console render test results" width="249" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yep, it’s React 🚬⚛️&lt;/p&gt;

&lt;p&gt;Here’s the deal: my component manages a list of items, renders them in different sections, and sometimes accesses them individually. That’s why I used context. The issue started when I decided that the form state used to add new items should also live in global state… out of laziness and simplicity.&lt;/p&gt;

&lt;p&gt;So I put those values in the same context. Big mistake. Every time &lt;code&gt;onChange&lt;/code&gt; fired to update the form state, it triggered a re-render of the component that only renders the list — completely unnecessary.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Why not use form libraries or state helpers?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This component is meant to be shared across multiple apps in our org, so our top priority is to keep it lightweight and minimize dependencies. Using a library is a heavier decision I don’t have control over — and, well, you know what they say: &lt;em&gt;"give the client what they want."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You could say it’s just part of working with React. One of the reasons it gets hate is because of how hard it is to avoid unnecessary re-renders (and the endless “Angular vs. Vue vs. React” debates, blah blah). Maybe they’re right. What I’ve learned is that those unnecessary re-renders &lt;em&gt;aren’t always&lt;/em&gt; a problem—until they are. That’s when experience and instinct help you decide: let it slide, or prevent a bigger performance issue down the road.&lt;/p&gt;

&lt;p&gt;Unfortunately, I didn’t have the energy to restructure everything. The sprint ended the next day, and I had promised my manager there wouldn’t be any carry-over. Maybe I didn’t need a full restructure either. So my short-term fix was to split the context into smaller, more specific ones. Turns out my mistake was cramming too many properties into a single context for convenience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;I always wondered why people use external libraries for global state management when React already has the &lt;strong&gt;Context API&lt;/strong&gt;. But now I get it. Even in seemingly “simple” scenarios, popular libraries like &lt;strong&gt;Zustand&lt;/strong&gt; might help solve these performance issues with a much cleaner and lighter API.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤯 &lt;strong&gt;This kind of realization is exciting.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
That’s why this meme hits harder now. I’m pretty sure I’ll use the Context API again in the future… or maybe I’ll ditch React entirely. Who knows?&lt;/p&gt;
&lt;/blockquote&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%2Fd3hia9gv9n2kpoy2bibg.webp" 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%2Fd3hia9gv9n2kpoy2bibg.webp" alt="React context curve meme" width="675" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, my next steps? I want to explore state libraries like &lt;strong&gt;Zustand&lt;/strong&gt;, and revisit other design patterns too — like &lt;strong&gt;Observer&lt;/strong&gt; — that might better fit some of my use cases (or maybe they’re the same thing and I just don’t know it yet).&lt;/p&gt;

&lt;p&gt;In any case, today I almost became the villain of my own refactor. It would’ve been easy to leave things as they were… but I’m glad I caught it in time and shipped something cleaner.&lt;/p&gt;

</description>
      <category>react</category>
      <category>learning</category>
      <category>frontend</category>
    </item>
    <item>
      <title>😵‍💫 Server Components in Next.js 15: What I got wrong (and right)</title>
      <dc:creator>Juanda Martínez</dc:creator>
      <pubDate>Tue, 27 May 2025 18:23:53 +0000</pubDate>
      <link>https://forem.com/juandadev/server-components-in-nextjs-15-what-i-got-wrong-and-right-50fa</link>
      <guid>https://forem.com/juandadev/server-components-in-nextjs-15-what-i-got-wrong-and-right-50fa</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a translated version of the &lt;a href="https://www.juanda.dev/blog/server-components-en-nextjs-15-lo-que-entendi-mal-y-bien" rel="noopener noreferrer"&gt;original post&lt;/a&gt; published in my Spanish blog. The translation was generated using ChatGPT and manually reviewed for clarity and accuracy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I set out to build my personal blog with Next.js 15, I was excited to finally take advantage of the famous &lt;strong&gt;✨ Server Components ✨&lt;/strong&gt;. I had never really given them a proper try before, and I thought, “This is the future.” What I didn’t know is that I was about to step into a world of bugs, broken builds, missing sessions, and documentation that was… confusing?&lt;/p&gt;

&lt;p&gt;This post isn’t a tutorial — it's more of a story about &lt;em&gt;how not to lose your mind&lt;/em&gt; when things don’t go as expected with Server Components, and how (unsurprisingly) AI can be overly agreeable unless you steer it toward the actual solution. &lt;strong&gt;Spoiler&lt;/strong&gt;: I ended up learning more than I thought.&lt;/p&gt;




&lt;h2&gt;
  
  
  The first problem: the fetch that never came
&lt;/h2&gt;

&lt;p&gt;It all started when my homepage, where I wanted to show the latest five blog entries, just… &lt;strong&gt;didn’t render anything&lt;/strong&gt;. For context, I was using Next.js API routes with the App Router to handle the "backend" side of things.&lt;/p&gt;

&lt;p&gt;The homepage is a &lt;strong&gt;server component&lt;/strong&gt; generated &lt;strong&gt;statically&lt;/strong&gt; at build time. It tries to fetch the latest posts via an internal API… but when I deployed it to Vercel, the build logs threw this error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  ❌ Internal Server Error
&lt;/h3&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Internal server error
    at a (.next/server/app/page.js:1:5127)
    at async p (.next/server/app/page.js:1:3031)
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;The build didn’t fail entirely, but the log was concerning. When I checked the live site, the list of posts was completely empty.&lt;/p&gt;

&lt;p&gt;I thought this project would be "simple", but here I was — asking ChatGPT, then Grok because ✨ free tier ✨, taking a coffee-break ☕️ when I finally remembered that I &lt;em&gt;do&lt;/em&gt; have a brain, and that back in the day we used Google and StackOverflow to solve things. Then came the eureka moment:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How can I expect a static page to fetch posts from an API that **isn’t running yet&lt;/em&gt;&lt;em&gt;?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It made total sense. Locally, the Node server is always running, so API routes are available. But during a deploy, when &lt;code&gt;npm run build&lt;/code&gt; executes, there’s no server running yet — there’s nothing to fetch from.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution:&lt;/strong&gt; I had to query the &lt;strong&gt;database directly&lt;/strong&gt; from the Server Component. It feels like I’m breaking an abstraction, but it worked.&lt;/p&gt;




&lt;h2&gt;
  
  
  Session confusion
&lt;/h2&gt;

&lt;p&gt;On another page, I needed to fetch an individual post. In this case, fetching from the internal API worked fine — it was also a Server Component, but the key difference is that this route is dynamic. It fetches data when someone visits the post. The server handles the query and sends back the full page. So far, so good.&lt;/p&gt;

&lt;p&gt;The issue came when I needed to validate some logic based on the user's session. I kept trying different approaches, but the session inside the API routes always came as &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And again… failed attempts asking an AI to solve my life. Something I could’ve solved if I had just read the official docs 😅&lt;/p&gt;

&lt;p&gt;Still, I kept trying with Grok, trying to guide it toward the right idea. Here’s the prompt I used (don’t judge my broken English — I promise that I can do better, but since this thing is smarter than me, I don't bother to correct my grammatical issues 🤣):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;it didn't work, still coming as null, but doesn't this have to do that I am using an internal API route to fetch a post, but this post is being fetched in a server component. I just tried to get the session data in the fetch itself and not inside my API routes and it worked&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I know what you're thinking—I should’ve told the AI all of this context from the start. But in my experience, if you throw too much info at once, it ignores half of it and replies with whatever it wants anyway...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution:&lt;/strong&gt; When doing fetch from a Server Component, the browser’s &lt;strong&gt;cookies 🍪 are not sent automatically&lt;/strong&gt;. And without cookies, there’s no session. You have to pass them manually—and thankfully, Next.js has the tools to do just that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This depends on the type of authentication your app uses. I use &lt;code&gt;JWT&lt;/code&gt; (&lt;a href="https://en.wikipedia.org/wiki/JSON_Web_Token" rel="noopener noreferrer"&gt;JSON Web Token&lt;/a&gt;) along with &lt;a href="https://next-auth.js.org/" rel="noopener noreferrer"&gt;NextAuth.js&lt;/a&gt;, which stores session data in cookies.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/headers&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;cookieStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cookies&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;cookieString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cookieStore&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cookie&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="s2"&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;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`http://localhost:3000/api/post/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cookieString&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;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Docs - 1 | AI - 0&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Since I'm apparently becoming a pseudo "vibe coder", let me highlight this moment where AI didn’t give the best answer.&lt;br&gt;&lt;br&gt;
In Grok’s response, it built a cookie string using &lt;code&gt;.map&lt;/code&gt; and &lt;code&gt;.join&lt;/code&gt;, which works. But if you look at the &lt;a href="https://nextjs.org/docs/app/api-reference/functions/cookies" rel="noopener noreferrer"&gt;official Next.js docs&lt;/a&gt;, you’ll see the &lt;code&gt;cookies()&lt;/code&gt; method already has a built-in &lt;code&gt;.toString()&lt;/code&gt; that does this for you. So yeah... always double check 👁️&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  So… what did I learn?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Server Components are great, but full of gotchas.&lt;/strong&gt; You need to understand &lt;em&gt;where&lt;/em&gt; and &lt;em&gt;how&lt;/em&gt; your code runs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fetching your own API vs. querying the DB directly&lt;/strong&gt; from Server Components is a nuanced decision. Context matters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cookies aren't sent automatically with server-side fetch.&lt;/strong&gt; If you need session data, pass cookies manually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't blindly rely on AI.&lt;/strong&gt; Sometimes the old-school way (reading docs) saves you hours.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Things I could improve
&lt;/h3&gt;

&lt;p&gt;It still feels a bit off to query the DB directly from a Server Component. If you also feel that &lt;em&gt;✨ itch thing ✨&lt;/em&gt; when something seems wrong… trust it.&lt;/p&gt;

&lt;p&gt;Every time I’ve ignored that gut feeling, I get code reviews or manager feedback pointing out &lt;strong&gt;exactly&lt;/strong&gt; what I already suspected. I’m working on that — and this is a great chance to put it into practice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💬 I was looking through my Twitter bookmarks and found &lt;a href="https://x.com/asidorenko_/status/1884710772040679432" rel="noopener noreferrer"&gt;this tweet from &lt;em&gt;@asidorenko_&lt;/em&gt;&lt;/a&gt; explaining why you should separate your DB calls. I &lt;em&gt;knew&lt;/em&gt; I’d read that somewhere.&lt;br&gt;&lt;br&gt;
Pro tip: when it comes to frontend, anything can be exposed—so be careful.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Uncle Juan's final thoughts
&lt;/h2&gt;

&lt;p&gt;I remember when Server Components first showed up, the very nice and not-at-all toxic &lt;em&gt;Twitter / X&lt;/em&gt; community was comparing them to &lt;strong&gt;old-school PHP&lt;/strong&gt;, calling it a step backwards.&lt;/p&gt;

&lt;p&gt;Personally (as with most tech trends), I didn’t jump on the hype train right away. I resisted Tailwind, daily AI use, search engine replacements, and Server Components (yep—my old Next.js projects always started with &lt;code&gt;use client&lt;/code&gt; at the top). But eventually, I gave in. I tried them. And I liked them.&lt;/p&gt;

&lt;p&gt;My point is: &lt;strong&gt;trying new things expands your understanding&lt;/strong&gt; and helps you face real challenges. It's a good practice to reflect on the &lt;em&gt;why&lt;/em&gt; behind what you're doing. Push yourself — try applying a design pattern or avoid using libraries for everything.&lt;/p&gt;

&lt;p&gt;I once read (maybe on Reddit or Twitter) that a common question is: “When should I use &lt;code&gt;use client&lt;/code&gt;?” The answer was simple: use &lt;strong&gt;server components by default&lt;/strong&gt;, and only move the interactive parts to &lt;em&gt;client components&lt;/em&gt; when absolutely necessary — &lt;strong&gt;even if it feels silly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That advice stuck with me. And building my blog from scratch gave me the chance to follow it. It helped me write better component compositions (funny enough, there’s a React pattern called &lt;strong&gt;&lt;em&gt;Composition&lt;/em&gt;&lt;/strong&gt; that aligns perfectly with this approach). If I had just slapped &lt;code&gt;use client&lt;/code&gt; everywhere, I wouldn’t have run into these issues — or learned from them.&lt;/p&gt;

&lt;p&gt;That’s why experience matters when companies hire. It’s not just about knowing the concepts — it’s about the challenges you’ve faced and how you solved them. And that only comes from working on real-world projects that go beyond a JS calculator or a basic React to-do list.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💬 While writing this post, I found &lt;a href="https://x.com/asidorenko_/status/1865864202625147378" rel="noopener noreferrer"&gt;another tweet by &lt;em&gt;@asidorenko_&lt;/em&gt;&lt;/a&gt; explaining how to separate the interactive part into a new component. I swear I’m not sponsored by him — go follow him if you're into Next.js content.&lt;/p&gt;

&lt;p&gt;Also, look into the &lt;strong&gt;Composition pattern&lt;/strong&gt;. Now that you've made it this far, you know it exists. You’ve probably already used it without realizing it. Being aware of it, studying it, and applying it consciously will score you points in interviews. 😉&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;At the end of the day, this post is more of a war diary than a tutorial. But if I helped you save even a couple of hours of debugging, then it was all worth it.&lt;/p&gt;

&lt;p&gt;Have you also wrestled with Server Components? Let me know—I’d love to hear your experience 😅&lt;br&gt;&lt;br&gt;
Suggestions and corrections are welcome—I'm far from perfect, but I’m not afraid to be transparent and show my thought process when tackling problems.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>learning</category>
    </item>
    <item>
      <title>Level Up Your Object Oriented Programming Knowledge with Nintendo Switch 🎮👾</title>
      <dc:creator>Juanda Martínez</dc:creator>
      <pubDate>Wed, 18 Oct 2023 03:55:48 +0000</pubDate>
      <link>https://forem.com/juandadev/level-up-your-oop-knowledge-with-nintendo-switch-78n</link>
      <guid>https://forem.com/juandadev/level-up-your-oop-knowledge-with-nintendo-switch-78n</guid>
      <description>&lt;p&gt;Imagine for a moment that &lt;strong&gt;Object Oriented Programming (OOP)&lt;/strong&gt; is like the inner workings of your favorite gaming console, the Nintendo Switch. Just as the Switch combines different components to bring your favorite games to life, OOP unites data and functions to create efficient and organized code. In this article, we'll embark on a journey to explore the four fundamental principles of OOP through the lens of the Nintendo Switch, will try my best to teach you this powerful programming paradigm with examples that are as enjoyable as a game of the great N. Get ready to level up your coding skills and game on as we unlock the secrets of OOP with the Nintendo Switch as our guide.&lt;/p&gt;

&lt;p&gt;OOP relies on two major concepts: &lt;strong&gt;Classes&lt;/strong&gt; and &lt;strong&gt;Objects&lt;/strong&gt;. These concepts can be applied in code to enable us to build applications. &lt;em&gt;Object Oriented Programming&lt;/em&gt; was created to guide the creation of better software, by achieving easier maintenance and reusability.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;DISCLAIMER&lt;/strong&gt;: The following examples are just an attempt to explain my point, there may be inconsistencies according to reality&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  CLASSES AND OBJECTS
&lt;/h2&gt;

&lt;p&gt;Let's say that we want to create a brand new console, shall we? :) It comes in many colors, we have the ability to play videogames anywhere, it has a battery life of 6 hours that drains every time you play a game, and you can install many games on its internal storage! We decided to name it ✨&lt;em&gt;Nintendo Switch&lt;/em&gt;✨&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%2Fafff8ufbctv5yzv10ft5.png" 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%2Fafff8ufbctv5yzv10ft5.png" alt="Nintendo Switch Lite Drawing" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we translate this in code, we can create a &lt;strong&gt;Class&lt;/strong&gt; named &lt;code&gt;NintendoSwitch&lt;/code&gt; and we list the principal attributes and its methods, think of a &lt;em&gt;class&lt;/em&gt; as it were a &lt;strong&gt;template&lt;/strong&gt; or &lt;strong&gt;blueprint&lt;/strong&gt; that will specify how the console looks and the way it's going to perform some actions (I would like to explain this class/object stuff with Typescript first):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NintendoSwitch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;screenSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;5.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;storageCapacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;batteryLife&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;gamesInstalled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gamesInstalled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gamesInstalled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gamesInstalled&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;playGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;logic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;installGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;logic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;checkBatteryLife&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;logic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&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;Here we have the principal &lt;em&gt;attributes&lt;/em&gt; like &lt;code&gt;color&lt;/code&gt;, &lt;code&gt;screenSize&lt;/code&gt;, &lt;code&gt;storageCapacity&lt;/code&gt;, &lt;code&gt;batteryLife&lt;/code&gt;, &lt;code&gt;gamesInstalled&lt;/code&gt;. Then we have the &lt;code&gt;constructor&lt;/code&gt;, a function that serves to initialize the attribute's values when we create an &lt;strong&gt;instance&lt;/strong&gt; of &lt;em&gt;NintendoSwitch&lt;/em&gt; class.&lt;/p&gt;

&lt;p&gt;Note that our class already has &lt;code&gt;storageCapacity&lt;/code&gt;, &lt;code&gt;batteryLife&lt;/code&gt;, and &lt;code&gt;screenSize&lt;/code&gt; initialized, because it will be the same for all the new &lt;strong&gt;instances&lt;/strong&gt; instead of &lt;code&gt;color&lt;/code&gt; and &lt;code&gt;gamesInstalled&lt;/code&gt;, those can be set at the moment we create the &lt;strong&gt;instance&lt;/strong&gt; of the current class.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An &lt;strong&gt;Instance&lt;/strong&gt; is equal to an &lt;strong&gt;Object&lt;/strong&gt;, we create as many objects as we want from a &lt;strong&gt;Class&lt;/strong&gt;, in most languages we use the &lt;strong&gt;new&lt;/strong&gt; keyword in order to create a new object, every object can be different one from another, because we can have many NintendoSwitch objects with different colors and different games installed!&lt;/p&gt;
&lt;/blockquote&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%2F1c017zp0zgr84nkhuxog.png" 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%2F1c017zp0zgr84nkhuxog.png" alt="Instances example with Nintendo Switch Lite" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, none of our instances have games to play with :( but the good part is that you can now understand what &lt;em&gt;Classes&lt;/em&gt; and &lt;em&gt;Objects&lt;/em&gt; are, so let's move on!&lt;/p&gt;

&lt;p&gt;In order to achieve mastery, we need to understand the ✨&lt;strong&gt;four principles&lt;/strong&gt; of Object Oriented Programming✨ starting with the first one:&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 ENCAPSULATION
&lt;/h2&gt;

&lt;p&gt;Is the need to separate your code in independent pieces for a single purpose, think of it like a box 📦 that holds data (&lt;em&gt;properties, attributes&lt;/em&gt;) and the things that can be done with that data (&lt;em&gt;methods, functions&lt;/em&gt;). This way, you can ensure that your data is safe and it's used correctly.&lt;/p&gt;

&lt;p&gt;This principle can define the reason for having classes, we encapsulate a set of &lt;em&gt;attributes&lt;/em&gt; and the things we can perform with those attributes as &lt;em&gt;methods&lt;/em&gt;, with the purpose of hiding the internal process and just showing what matters to the public, it's up to us if we want to set some attributes or methods as &lt;strong&gt;public&lt;/strong&gt;, or keep it &lt;strong&gt;private&lt;/strong&gt; just for internal use.&lt;/p&gt;

&lt;p&gt;If you want to explain this in a more technical way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Encapsulation is a way to restrict the direct access to some components of an object, so users cannot access state values for all of the variables of a particular object. Encapsulation can be used to hide both data members and data functions or methods associated with an instantiated class or object.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  INHERITANCE
&lt;/h2&gt;

&lt;p&gt;Is the idea that you can inherit perks and abilities from your parents 👨‍👩‍👦, like eye color or hair type.&lt;/p&gt;

&lt;p&gt;Let's go back to the Nintendo Switch; Now we want to create a new console by taking all the things inside of the &lt;em&gt;Nintendo Switch&lt;/em&gt; but with additional features. If we talk in terms of coding, maybe some newbie developer may think of copying and pasting the &lt;em&gt;Nintendo Switch&lt;/em&gt; class and creating a new one to add the desired new features... easy, right? But what if I told you that instead of re-write the code again, we can create our new model from what we already have 😱 Yes! you heard it right! we can &lt;strong&gt;extend&lt;/strong&gt; from the &lt;em&gt;Nintendo Switch&lt;/em&gt; class and then create the &lt;em&gt;Nintendo Switch Pro&lt;/em&gt; class without copying all the code from scratch, we will have all the features of the original Nintendo Switch, and then we can just add the new code for the features! on this new model, we want detachable controllers and also the ability to connect the Nintendo Switch to a dock and be able to play on a TV! how awesome is that?&lt;/p&gt;

&lt;p&gt;So we proceed to create our new class for the &lt;em&gt;Nintendo Switch Pro&lt;/em&gt;, &lt;strong&gt;extending&lt;/strong&gt; from &lt;em&gt;NintendoSwitch&lt;/em&gt; class, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NintendoSwitchPro&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;NintendoSwitch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;detachJoycons&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sr"&gt;/../&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;connectToTV&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sr"&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;&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%2Fvo04f6sw9cwa4jyj1laa.png" 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%2Fvo04f6sw9cwa4jyj1laa.png" alt="Nintendo Switch Drawing" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that its composition it's similar, but now we can detach the controllers (&lt;code&gt;detachJoycons&lt;/code&gt;) to play with them wireless, and we can also connect it to the TV! (&lt;code&gt;connectToTV&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Maybe this is a vague example but in the big picture this is ✨&lt;strong&gt;inheritance&lt;/strong&gt;✨ we take the &lt;em&gt;NintendoSwitch&lt;/em&gt; class, and extend this in a new class &lt;em&gt;NintendoSwitchPro&lt;/em&gt; that inherits all the &lt;em&gt;NintendoSwitch&lt;/em&gt; attributes and methods, and additionally we have two more methods that can do new things!&lt;/p&gt;

&lt;p&gt;This approach makes things more organized and saves you from doing the same things over and over again.&lt;/p&gt;

&lt;h2&gt;
  
  
  POLYMORPHISM
&lt;/h2&gt;

&lt;p&gt;Polymorphism means many shapes, in OOP we can &lt;strong&gt;modify the properties and methods that we inherited&lt;/strong&gt; to have different behavior in a way that makes sense for each class. This makes our code flexible and easy to adapt to many use cases.&lt;/p&gt;

&lt;p&gt;Going back to our previous example, our first class, &lt;em&gt;Nintendo Switch&lt;/em&gt;, as we know has a little screen of 5.5in, its size makes you able to even fit in your pocket and the battery lasts 6 hours of continuous play! But then when we created the &lt;em&gt;Nintendo Switch Pro&lt;/em&gt;, and decided that this new model would have a screen of 7in, bigger than his &lt;strong&gt;parent&lt;/strong&gt;!! and Thus we have a larger size of the whole console that can barely fit in your jeans pocket, we increment the battery life up to 10 hours of continuous play, and the rest remains the same, so now our new class will end like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NintendoSwitchPro&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;NintendoSwitch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;screenSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;batteryLife&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;detachJoycons&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sr"&gt;/../&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;connectToTV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sr"&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;super()&lt;/strong&gt; is another keyword that most languages adopt to refer to the &lt;strong&gt;super class&lt;/strong&gt; or &lt;strong&gt;parent class&lt;/strong&gt;, in the case above, we are using the same exact constructor of the &lt;em&gt;parent&lt;/em&gt; class because we don't need to add anything new to it.&lt;/p&gt;
&lt;/blockquote&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%2Fsuhdn87cu66pejknazes.png" 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%2Fsuhdn87cu66pejknazes.png" alt="Explanation of inheritance with Nintendo Switch" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, we set a couple of attributes that are named the same as some of the &lt;em&gt;parent&lt;/em&gt; models but modified their values to fit the new necessity. This is called &lt;strong&gt;Overriding&lt;/strong&gt; and it is a valid practice, even with methods! is like taking the inherited abilities and leveraging them with superpowers 💪🏻&lt;/p&gt;

&lt;h2&gt;
  
  
  ABSTRACTION
&lt;/h2&gt;

&lt;p&gt;Abstraction means simplifying complex things by breaking them into smaller and more manageable parts. Think of it like driving a car 🚗 we don't need to know all the technical details of how the engine works, we just need to understand how the basic controls like the steering wheel, gas pedal, and breaks work. With that being said, our methods contained in the &lt;em&gt;NintendoSwitch&lt;/em&gt; class can tell us &lt;strong&gt;WHAT&lt;/strong&gt; it does, without caring much about &lt;em&gt;HOW&lt;/em&gt; it does.&lt;/p&gt;

&lt;p&gt;For example, the method &lt;code&gt;checkBatteryLife()&lt;/code&gt; can tell us what it does just by its own name! but internally works like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NintendoSwitch class file&lt;/span&gt;
&lt;span class="nf"&gt;checkBatteryLife&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`This Nintendo Switch has &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;batteryLife&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; hours of battery life remaining.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//Our main script&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myFirstSwitch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NintendoSwitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

&lt;span class="nx"&gt;myFirstSwitch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkBatteryLife&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Console output: This Nintendo Switch has 6 hours of battery life remaining.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the &lt;code&gt;batteryLife&lt;/code&gt; attribute on its own doesn't say much about it, it's just &lt;code&gt;6&lt;/code&gt;, but 6 what?? then &lt;code&gt;checkBatteryLife()&lt;/code&gt; gives us more context, and the result is that the logged message in the console specifying that the battery life attribute is meant to be the &lt;em&gt;hours&lt;/em&gt; left of battery life!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sometimes we can find &lt;strong&gt;getters&lt;/strong&gt; and &lt;strong&gt;setters&lt;/strong&gt; functions inside classes, we won't focus on these things right now, but think of them as functions that help us to set/modify the value of an object's attribute (&lt;em&gt;setters&lt;/em&gt;), and functions to read those values (&lt;em&gt;getters&lt;/em&gt;). At first sight, this may seem useless, but sometimes this can keep our attributes safer, like by adding a validation layer, so no one can set a null-ish value that can break our app, or set that &lt;em&gt;abstraction&lt;/em&gt; layer like in the example above to give a meaning to our attributes values.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In OOP we can hide complicated pieces of code and provide a simple interface, so we can focus on what our code does rather than how it does it, this makes our code easier to understand and maintain.&lt;/p&gt;




&lt;p&gt;And that's all, folks!&lt;/p&gt;

&lt;p&gt;I hope that you can understand better the OOP principles with these examples :) Let me know in the comments your thoughts, this is an important topic in software development, and can even get you an opportunity to get a job in a big tech company! they often opt for developers with this kind of general knowledge instead of looking for someone with a specific language, because if you know all of this stuff you are more likely to adapt to any technology.&lt;/p&gt;

&lt;p&gt;This is the first of a three-part series that I'm about to write, because I want you to understand from my perspective, how OOP, Javascript Prototypes, and SOLID principles can be related ✨&lt;/p&gt;

</description>
      <category>programming</category>
      <category>learning</category>
      <category>development</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Should You Lower Your Possibilities When Looking For a Job?</title>
      <dc:creator>Juanda Martínez</dc:creator>
      <pubDate>Thu, 05 Oct 2023 20:59:54 +0000</pubDate>
      <link>https://forem.com/juandadev/should-you-lower-your-possibilities-when-looking-for-a-job-2p0j</link>
      <guid>https://forem.com/juandadev/should-you-lower-your-possibilities-when-looking-for-a-job-2p0j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@andrewjoegeorge?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Andrew George&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/g-fm27_BRyQ?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These past days I decided to focus my energies on doing some research and studying for a position I really wanted to be part of as a Node.js developer (Back-end). As some of you would already know, my expertise lies in Frontend development, especially with React, Redux, and Graphql, or at least that's what I thought at the beginning...&lt;/p&gt;

&lt;p&gt;I was afraid to apply for full-stack or back-end positions, I thought that I couldn't perform well in these areas because of my professional experience, but after some time of self-retrospective, I just realized that I always have been a full-stack developer without knowing it. The thing is that although in my last job I was given the title of &lt;strong&gt;Web UI developer&lt;/strong&gt;, to be honest, I feel the industry always leans towards full-stack somehow, and in my last project we managed a Node.js server with Apollo server to extend the usability of GraphQL in our front-end with React, and it was something of our daily tasks to code in both repos after all. So that's it!! I already know Node.js so I can say that I have experience in the field, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Discover your hidden abilities!
&lt;/h2&gt;

&lt;p&gt;After realizing this, it was an eureka moment for me! How can you be biased about your capabilities just because of the title some company gives to you? This also includes the seniority of course.&lt;/p&gt;

&lt;p&gt;I started to detect those back-end skills and gain more confidence about it. Tried to analyze what and how do we managed in that Node.js repo. We were in charge of the API layer by collecting all the external APIs the Java team brought to us, like an API for users, another one for bag items, and so on, then we made the proper functions and logic to use that data and transform it to be consumable by our front-end project.&lt;/p&gt;

&lt;p&gt;Does that sound familiar to you? Of course it is, because without knowing we were interacting every day in a &lt;strong&gt;MICROSERVICES ARCHITECTURE&lt;/strong&gt;, I know it doesn't sound like a big deal, but for me it was like founding the one piece 💰&lt;/p&gt;

&lt;p&gt;Why I'm so sure about this? well, after some research about microservices, a lot of things started to make sense to me, we had a Java team that created separate projects for each service, and those services were split by the business needs, being the case of an e-commerce. Then the DevOps team is in charge of all the infrastructure layer, to finally us getting all of those APIs to be consumed on a single Node.js server with Apollo.&lt;/p&gt;

&lt;p&gt;Then I asked ChatGPT to give me some topics to study for a back-end position with Node.js, microservices being one of them, followed by understanding HTTP protocol and other stuff, stuff that I already knew and it was just a matter of time to research, and remember all of those things!&lt;/p&gt;

&lt;h2&gt;
  
  
  DON'T close yourself to the possibilities!
&lt;/h2&gt;

&lt;p&gt;The point of all of this is to make you rethink your skill set and be able to know what you are capable of! don't close yourself just because someone told you that you're just a frontend or backend dev, junior or senior!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You always work with &lt;strong&gt;data structures&lt;/strong&gt;, so do your research about it! get to know how you interact with those and search for examples, I'm sure you've been working with a lot of these, and even you can start thinking about your further solutions by applying data structures specifically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn about algorithms! it is a topic you probably applied in some of the techniques in your daily problem-solving process. You will start to know about the complexity of a piece of code or function and you will start to think differently, seek how to improve performance, and solve memory leaks in your apps!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, the sooner you start to discover your hidden skills, the sooner you can start to open your range of possibilities when looking for a job!&lt;/p&gt;

&lt;p&gt;I stopped saying that I'm just a front-end developer, I know that I can perform well in a back-end position with Node.js, and I know that I can also apply for full-stack and backend positions without hesitation. So what are you waiting for? Go for it 💪🏻&lt;/p&gt;

&lt;p&gt;Recently, I applied for a Node.js position, it went very well and I was even surprised of myself in both HR and Technical interviews that they loved my profile and knowledge, but unfortunately, they rejected me because the client didn't like my solution for a code challenge, it was easy but I made the mistake to work on that challenge when I was too tired after three interviews and a lot of study before it! I was in zombie mode 🧟 I could get to the solution but made a mess with the code because I wasn't thinking with a fresh mind&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Yes, this is a reminder to all of you that rest is important, other than rushing your work and making a mess&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So that's it! this was the proof that I was able to apply to other positions. I would love to read your thoughts on this, I know it may vary depending on the role and technology, but sometimes there are core concepts and some experiences you had in the past that can make you able to get into other fields and succeed ✅&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
      <category>devjournal</category>
      <category>motivation</category>
    </item>
    <item>
      <title>How I Got Fired From my Dream Job</title>
      <dc:creator>Juanda Martínez</dc:creator>
      <pubDate>Wed, 27 Sep 2023 23:45:11 +0000</pubDate>
      <link>https://forem.com/juandadev/how-i-got-fired-from-my-dream-job-56hf</link>
      <guid>https://forem.com/juandadev/how-i-got-fired-from-my-dream-job-56hf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@clemono" rel="noopener noreferrer"&gt;Clem Onojeghuo&lt;/a&gt; on &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, I'm not proud to say that I got fired two weeks ago. It was the hardest thing that could happened to me because I loved that company, but at the same time, I realized that I was too comfortable and felt like my job would last forever.&lt;/p&gt;

&lt;p&gt;After two years working for a clothes store e-commerce, my skills in React grew exponentially. I learned a lot of stuff because it was my first huge project, working along with a lot of people with higher seniority and experience, it was pleasant to experience a lot of real problems that can come in a business and get rid of them, but then in my final days I realized that I was being like a robot just writing code and not understanding it at all, I was like in a rabbit hole for several months, then suddenly the business started to having budget problems, and guess what? we got laid off :)&lt;/p&gt;

&lt;p&gt;It's important to say that I was working for an IT consultant, so it didn't seem a big deal, because when a project comes to an end, you just need to find a new one and in the process, the company still pays your salary even though you are not being "productive" for them. The problem came when you also needed to take some interviews to see if they could ensure you're the best fit for the project, this means that is exactly like looking for a job outside, with the difference that you still get paid.&lt;/p&gt;

&lt;p&gt;I got a reality hit when I arrived at my first interview after two years and I just got in blank with basic Javascript questions! I felt so dumb at that moment, how could be possible to forget how the event loop works? or asynchronism? some basic stuff. The thing ended awful and obviously, I didn't get the project, and I realized how important is not to take things for granted! even though you are developing the most complex stuff in the world, it is important to go back to the basics from time to time.&lt;/p&gt;

&lt;p&gt;And if that was not enough, the industry now demands a lot of full-stack engineers! I have worked with PHP in the past, but it was in my beginnings doing "spaghetti code" all the way, then I jumped to Laravel without knowing too much about how PHP works behind the hood. Then I created a basic API with Node.js for my final project at university by just following a short course in a platform without knowing what was I doing, if it works it works, right? That was all the background I have for Backend development and for obvious reasons I didn't feel secure about my knowledge. So in my way to increase my tech stack, I spent a month and a half trying to learn Angular due to a lack of React projects, and also a bit of Node.js and looking for suitable projects, but then suddenly I got an HR call telling me that it was being hard to set me in a project, and they cannot afford to keeping me without being "productive" and... I got fired...&lt;/p&gt;

&lt;p&gt;And now here I am, after about a week of being a bit depressed for losing my dream job, and another week to seek my next job, right now the industry is leaning toward full-stack development; React, Redux, Node.js &amp;amp; AWS are the most common stack I've seen through LinkedIn, at least the opportunities here in Mexico 🇲🇽&lt;/p&gt;

&lt;p&gt;So, the whole point of this post is to take out in public what I have inside my chest because it makes me feel like a weight has been lifted off my shoulders and gives me motivation to keep going and compromise with this community (even though nobody reads me for the moment lol xD) to grow my tech stack and be the Software Engineer I always wanted to be. I feel like this is the perfect and emotive start for my &lt;strong&gt;#30DaysOfCode&lt;/strong&gt; with Node.js which I found is critical for my career, so starting tomorrow I will post every day (Maybe skipping Sundays because everybody needs to rest) my learning process of Node.js from a Frontend developer's perspective, and hopefully, to get a job soon because I can only survive 5 months until I have to sleep under a bridge or end up in the streets.&lt;/p&gt;

&lt;p&gt;I'm excited and happy though 🤩 Let me know in the comments if you guys have been through a similar situation and how you managed to succeed and find the light after the storm!&lt;/p&gt;

&lt;p&gt;Come and connect with me (in Spanish) on Twitter/X: &lt;a href="https://twitter.com/juandadotdev" rel="noopener noreferrer"&gt;@juandadotdev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>motivation</category>
      <category>discuss</category>
      <category>career</category>
    </item>
  </channel>
</rss>
