<?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: Amir Azhar</title>
    <description>The latest articles on DEV Community by Amir Azhar (@amehpls).</description>
    <link>https://dev.to/amehpls</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%2F764117%2Fd81fae08-4e2f-41db-8353-6a0b1cebccbf.jpeg</url>
      <title>DEV Community: Amir Azhar</title>
      <link>https://dev.to/amehpls</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amehpls"/>
    <language>en</language>
    <item>
      <title>Concurrency in Java: A Guide for Beginners!</title>
      <dc:creator>Amir Azhar</dc:creator>
      <pubDate>Fri, 21 Mar 2025 08:44:48 +0000</pubDate>
      <link>https://dev.to/amehpls/concurrency-in-java-a-guide-for-beginners-561e</link>
      <guid>https://dev.to/amehpls/concurrency-in-java-a-guide-for-beginners-561e</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In modern software development, &lt;strong&gt;concurrency&lt;/strong&gt; is a game-changer. It allows a program to handle multiple tasks at once, improving performance. For example, in a web server, while one thread is serving a user’s request, another can be processing a database query. This makes the system feel fast and responsive, even when there are many things going on behind the scenes.&lt;/p&gt;

&lt;p&gt;In this article, we’ll dive into concurrency in Java - what it is, how to use it, and how it can be applied in real-world applications. By the end, you’ll have a foundational understanding of how to handle multiple tasks in your Java programs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concurrency vs. Parallelism: What’s the Difference?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Concurrency
&lt;/h3&gt;

&lt;p&gt;Concurrency is when a program handles multiple tasks at once, making progress on them even if they aren't running at the same time. For example, a web server handles multiple requests by quickly switching between them, without running them all at once. It’s like a chef cooking several dishes at the same time - stirring one pot, chopping vegetables for another, and cooking rice - without fully focusing on any single task the whole time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallelism
&lt;/h3&gt;

&lt;p&gt;Parallelism is when tasks are actually executed at the same time, usually with multiple CPU cores or processors. For example, when working with a large dataset, the tasks can be divided and processed simultaneously across different cores. It’s like each chef in a kitchen working on different parts of the same dish at the same time - one chef is chopping vegetables, another is cooking the sauce, and another is grilling the meat - all working together to complete the dish faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use Concurrency vs. Parallelism?
&lt;/h3&gt;

&lt;p&gt;Knowing the difference is great, but when should you actually use concurrency or parallelism in your applications? To put it simply,&lt;/p&gt;

&lt;p&gt;Use concurrency when tasks need to make progress together but don’t have to run at the exact same time. It’s useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web servers - Handling multiple user requests without blocking.&lt;/li&gt;
&lt;li&gt;Mobile apps - Loading data while keeping the UI responsive.&lt;/li&gt;
&lt;li&gt;Chat applications - Sending and receiving messages without delays.&lt;/li&gt;
&lt;li&gt;Databases - Handling multiple queries without waiting for each to finish.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use parallelism when tasks can run at the exact same time, taking advantage of multiple CPU cores. It’s great for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image processing - Applying filters to different parts of an image in parallel.&lt;/li&gt;
&lt;li&gt;Machine learning - Running computations on large datasets simultaneously.&lt;/li&gt;
&lt;li&gt;Data analysis - Processing big data across multiple threads for faster insights.&lt;/li&gt;
&lt;li&gt;Video rendering - Encoding multiple frames at the same time to speed up processing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Threads: The Building Blocks of Concurrency
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;thread&lt;/strong&gt; is the smallest unit of execution within a program. In Java, a thread is like an individual worker responsible for performing a task. You can either create a thread by &lt;strong&gt;extending the &lt;code&gt;Thread&lt;/code&gt; class&lt;/strong&gt; or by &lt;strong&gt;implementing the &lt;code&gt;Runnable&lt;/code&gt; interface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a quick comparison:&lt;/p&gt;

&lt;h3&gt;
  
  
  Extending the &lt;code&gt;Thread&lt;/code&gt; Class:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyThread&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Thread is running!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MyThread&lt;/span&gt; &lt;span class="n"&gt;thread&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;MyThread&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Start the thread&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementing the &lt;code&gt;Runnable&lt;/code&gt; Interface:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyRunnable&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Runnable is running!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MyRunnable&lt;/span&gt; &lt;span class="n"&gt;runnable&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;MyRunnable&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;thread&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;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runnable&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Start the thread&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Does the &lt;code&gt;run()&lt;/code&gt; Method Do?
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;run()&lt;/code&gt; method is where you define the task that you want the thread to perform. When you create a thread, you don’t actually tell it what to do directly. Instead, you put that code inside the &lt;code&gt;run()&lt;/code&gt; method, and the thread will execute whatever is inside it when you start the thread.&lt;/p&gt;

&lt;p&gt;Think of the &lt;code&gt;run()&lt;/code&gt; method as the “to-do list” for your worker (thread). When you call the &lt;code&gt;start()&lt;/code&gt; method, the thread begins executing the instructions inside the &lt;code&gt;run()&lt;/code&gt; method, and that’s when the actual work happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Concurrency Works: Context Switching
&lt;/h2&gt;

&lt;p&gt;Now that you know what a thread is, let's take a step back to understand how concurrency actually works. &lt;/p&gt;

&lt;p&gt;When you have multiple threads running on a single CPU, only one thread can execute at a time. But how can multiple threads seem like they're running at once? The answer is &lt;strong&gt;context switching&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Context Switching?
&lt;/h3&gt;

&lt;p&gt;Context switching happens when the CPU rapidly switches between multiple threads. It makes it appear that several tasks are being run simultaneously, even though only one is running at any given time.&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;The CPU executes one thread&lt;/strong&gt;: The CPU runs the instructions of one thread.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Time slice ends&lt;/strong&gt;: After a small period, the operating system interrupts the running thread and schedules the next one. This is often done in time slices, which can be very short.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context switch&lt;/strong&gt;: The CPU saves the state (or context) of the current thread so it can resume it later. This includes things like the program counter and register values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next thread runs&lt;/strong&gt;: The CPU loads the state of the next thread and continues executing its instructions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Thread Lifecycle: Understanding the Process
&lt;/h2&gt;

&lt;p&gt;Threads go through a lifecycle, similar to workers in a production environment. Here’s what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;New&lt;/strong&gt;: Created but hasn’t started yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runnable&lt;/strong&gt;: Ready but might be waiting for CPU time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocked&lt;/strong&gt;: Waiting for access to a resource.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Waiting&lt;/strong&gt;: Paused until another thread signals it to resume.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminated&lt;/strong&gt;: Thread has completed its task.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Synchronization: Preventing Conflicts in Multi-threading
&lt;/h2&gt;

&lt;p&gt;When multiple threads access shared resources, you can run into issues like &lt;strong&gt;race conditions&lt;/strong&gt;. For example, if two threads try to update the same data simultaneously, the result could be incorrect or unpredictable.&lt;/p&gt;

&lt;p&gt;To handle this, Java provides &lt;code&gt;synchronization&lt;/code&gt; to ensure that only one thread can access a particular resource at a time. This is crucial in real-world applications like banking systems, where two users trying to withdraw money from the same account at the same time could lead to incorrect balances.&lt;/p&gt;

&lt;p&gt;Here’s an example of using synchronization in a Java class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;synchronized&lt;/code&gt; keyword ensures that no two threads can update the balance at the same time, preventing race conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;ExecutorService&lt;/code&gt;: Managing Multiple Tasks Efficiently
&lt;/h2&gt;

&lt;p&gt;In real-world applications, especially ones that need to handle multiple tasks simultaneously (like web servers, data processing pipelines, or task schedulers), managing threads manually can become complex and error-prone. That’s where &lt;code&gt;ExecutorService&lt;/code&gt; comes in.&lt;/p&gt;

&lt;p&gt;Imagine you have a file-processing system that needs to handle thousands of files. Instead of creating a new thread for each file (which would be inefficient and resource-intensive), you can use &lt;code&gt;ExecutorService&lt;/code&gt; to manage a pool of worker threads that handle the files concurrently. This makes your application both efficient and scalable.&lt;/p&gt;

&lt;p&gt;Here’s an example of using &lt;code&gt;ExecutorService&lt;/code&gt; to handle tasks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.concurrent.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileProcessingTask&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Callable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Simulate file processing&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"File processed successfully!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;ExecutionException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;ExecutorService&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newFixedThreadPool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pool of 5 threads&lt;/span&gt;
        &lt;span class="nc"&gt;FileProcessingTask&lt;/span&gt; &lt;span class="n"&gt;task&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;FileProcessingTask&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Output: File processed successfully!&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdown&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Close the executor after all tasks are done&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we’ve created an &lt;code&gt;ExecutorService&lt;/code&gt; with a fixed thread pool. This means that we can process multiple files concurrently, but without overwhelming the system by creating too many threads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use &lt;code&gt;ExecutorService&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;ExecutorService&lt;/code&gt; simplifies task management in production applications. It allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reuse threads&lt;/strong&gt;: Avoid the overhead of creating new threads every time you need one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schedule tasks&lt;/strong&gt;: Submit tasks without manually managing threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle results&lt;/strong&gt;: Easily get the results from tasks once they’re completed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  There's More?
&lt;/h3&gt;

&lt;p&gt;While we’ve focused on ExecutorService here, Java provides many other tools to make concurrency easier and more efficient as part of its concurrency utilities. Some of these tools are designed for specific use cases, like handling scheduled tasks (ScheduledExecutorService) or forking tasks to be processed in parallel (ForkJoinPool).&lt;/p&gt;

&lt;p&gt;In a future article, I’ll dive into more of these tools to give you a broader understanding of how to manage concurrency in Java. But for now, the ExecutorService is your go-to for most situations.&lt;/p&gt;

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

&lt;p&gt;Java’s concurrency features - such as threads, &lt;code&gt;synchronization&lt;/code&gt;, and &lt;code&gt;ExecutorService&lt;/code&gt; - are crucial for building efficient, scalable applications. By understanding and using these tools, you can build real-world systems that handle multiple tasks concurrently, ensuring your application is responsive and optimized.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;ExecutorService&lt;/code&gt;, you can easily manage concurrent tasks in production scenarios, from web servers to file-processing systems. While there’s much more to explore, this foundation will set you up for success as you dive deeper into Java’s powerful concurrency tools.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Exploring Redux-Persist with Pokémon!</title>
      <dc:creator>Amir Azhar</dc:creator>
      <pubDate>Thu, 20 Oct 2022 13:57:45 +0000</pubDate>
      <link>https://dev.to/amehpls/explaining-redux-persist-with-pokemon-101g</link>
      <guid>https://dev.to/amehpls/explaining-redux-persist-with-pokemon-101g</guid>
      <description>&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;This post is intended for developers with a basic understanding of using Redux and its concepts such as stores, actions and reducers. If you are unfamiliar with these concepts, I highly recommend starting with the &lt;a href="https://redux.js.org/tutorials/essentials/part-1-overview-concepts" rel="noopener noreferrer"&gt;Redux Essentials&lt;/a&gt; documentation or a concise &lt;a href="https://www.youtube.com/watch?v=CVpUuw9XSjY&amp;amp;t=985s&amp;amp;ab_channel=developedbyed" rel="noopener noreferrer"&gt;Redux for Beginners Tutorial video&lt;/a&gt;, if you’re looking for a sample project walkthrough.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple Recap on Redux
&lt;/h2&gt;

&lt;p&gt;Redux is an open-source JS library designed to help developers manage the state of variables in their applications. Redux does this by creating a centralized store, and creates processes such as dispatch and reducers. This ensures that the various components from any part of a complex application, can read and update the data from the same store, in a uniform and consistent manner. Hence, this allows easy communication between components in an application.&lt;/p&gt;

&lt;p&gt;In this blog post, I will not be going in-depth into the boilerplate setup of Redux and other miscellaneous steps in the projects (writing different React components or CSS). I will instead start by showing a simple application that uses Redux, and explain how Redux-Persist will tackle the pain point of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pokémon with Redux
&lt;/h2&gt;

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

&lt;p&gt;I will be showing a simple Next.js application, initialized with typescript. Additionally, we will be using 2 Redux libraries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;react-redux&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The library needed to have the core redux functionalities - Store, dispatching, actions and so on. Most of us should already be familiar with this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;@reduxjs/toolkit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A &lt;a href="https://redux.js.org/redux-toolkit/overview#:~:text=Redux%20Toolkit%20makes%20it%20easier,of%20skill%20level%20or%20experience." rel="noopener noreferrer"&gt;toolkit&lt;/a&gt; makes it easier to write good Redux applications and speeds up development, by baking in our recommended best practices, providing good default behaviours, catching mistakes, and allowing you to write simpler code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a new Next.js application, with typescript&lt;/span&gt;
npx create-next-app@latest &lt;span class="nt"&gt;--ts&lt;/span&gt;

&lt;span class="c"&gt;# Install redux related tools&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; @reduxjs/toolkit react-redux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Simple Features of Application
&lt;/h3&gt;

&lt;p&gt;Fast forward a little and we have ourselves a basic application that uses Redux. This is a simple Pokémon application, that you can use to create a team for your next Pokémon journey! If you’re unfamiliar with Pokémon, it is a role-playing game based around building a small team of monsters (Pokémon), to battle other wild monsters and players (Trainers) to become the very best! This application uses the RESTful Pokémon API that can be found &lt;a href="https://pokeapi.co/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Even if you’re unfamiliar with Pokémon, the features of this application will still be easy to understand, if you’re already familiar with Redux. For now, let’s just take a look at 2 Redux-related files, and the 3 main components of our application that uses the Redux functionalities. In the videos I included, I made use of Google Chrome’s Inspect tool and &lt;a href="https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en" rel="noopener noreferrer"&gt;Redux DevTools&lt;/a&gt;, a chrome extension that allows us to debug application state changes. &lt;/p&gt;

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

&lt;h4&gt;
  
  
  1. &lt;code&gt;pokemonSlice.ts&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This file declares the initial state value of our store. In our case, the state that we will be keeping track of, is the Pokémon in our team, in the form of an array. Additionally, we also create 3 reducers - &lt;code&gt;addPokemon&lt;/code&gt;, &lt;code&gt;removePokemon&lt;/code&gt; and &lt;code&gt;removeAllPokemon&lt;/code&gt; - that will mutate our state by adding or removing single/all Pokémon from the state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pokemonSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pokemon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;addPokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PayloadAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PokemonBasicInfo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;removePokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PayloadAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PokemonBasicInfo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&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="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;removeAllPokemon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RootState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pokemonTeam&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addPokemon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;removePokemon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;removeAllPokemon&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;pokemonSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;pokemonSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. &lt;code&gt;store.ts&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This is the file which holds the whole state tree of our application. &lt;code&gt;configureStore&lt;/code&gt;, similar to &lt;code&gt;createStore&lt;/code&gt; , initializes our store with the reducers and initial state that were declared in &lt;code&gt;pokemonSlice.ts&lt;/code&gt;.&lt;br&gt;
&lt;/p&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;configureStore&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;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;pokemonTeamReducer&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;./slices/pokemonSlice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;pokemonTeam&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pokemonTeamReducer&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="c1"&gt;// Infer the `RootState` and `AppDispatch` types from the store itself&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RootState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AppDispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.&lt;code&gt;Pokedex.tsx&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This component displays a grid of Pokémon, where users can add Pokémon to their team. Users also have the ability to remove a Pokémon from their team if needed. These are both accomplished using Redux’s &lt;code&gt;useSelector&lt;/code&gt; and &lt;code&gt;useDispatch&lt;/code&gt;, combined with the reducers that we declared previously&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Pokedex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pokedex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGetPokemon&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;myTeam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectValue&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;myTeamNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myTeam&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;poke&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;poke&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PokemonBasicInfo&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="nx"&gt;myTeamNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;myTeamNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;poke&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="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You can only have 6 Pokémon in your team! Remove one Pokémon to add another.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="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="nx"&gt;myTeamNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;removePokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pokedexWrapper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pokedexTitle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Kanto Pokédex&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pokedex&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pokedex&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;poke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PokemonBasicInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
                &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;
                  &lt;span class="nx"&gt;myTeamNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;poke&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="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pokemonChosen&lt;/span&gt;
                    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pokemon&lt;/span&gt;
                &lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Pokedex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. &lt;code&gt;Team.tsx&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This component showcases the Pokémon that we have already added into our team. It does this by reading the state from the store using Redux’s &lt;code&gt;useSelector&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myTeam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;teamContainer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My Team&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;myTeam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;teamWrapper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;teamListing&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;myTeam&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;poke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PokemonBasicInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pokemon&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pokemonName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clearButton&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;removeAllPokemon&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Reset
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emptyMessage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Click on a Pokémon to add it to your team!
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Team&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. &lt;code&gt;_app.tsx&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;The entry point for our app is then wrapped with a &lt;code&gt;Provider&lt;/code&gt; which provisions the &lt;code&gt;store&lt;/code&gt; we previously created. This allows all its children components to access the store and make modifications to the state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AppProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;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;For an in-depth look at the project, please visit my &lt;a href="https://github.com/Content-Creation-Amir/pokemon-redux-persist-tutorial/tree/no-redux-persist" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitations of Redux Alone
&lt;/h3&gt;

&lt;p&gt;But here’s a problem.&lt;/p&gt;

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

&lt;p&gt;Did you catch that? If you said that the problem was choosing &lt;em&gt;Oddish&lt;/em&gt; to be part of my team, technically you’re not wrong….. BUT a more drastic issue would be that my team selection gets wiped whenever I refresh the page. What if I forgot what my team selection was before? How would I make sure that the application remembers (persists) the choices (state) that I have made?&lt;/p&gt;

&lt;h2&gt;
  
  
  Redux-Persist
&lt;/h2&gt;

&lt;p&gt;Redux-Persist is an add-on library to Redux that will allow us to save our Redux store in the local or session storage. Before I dive deeper into how and why it works, let’s take a look at adding it into our application. This is a simple process as it only requires us to modify our &lt;code&gt;store.ts&lt;/code&gt; and &lt;code&gt;_app.tsx&lt;/code&gt; . But before that, let’s install the package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install redux-persist&lt;/span&gt;
npm i redux-persist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Changes /Additions Made
&lt;/h3&gt;

&lt;p&gt;Now, let’s delve deeper into the changes and additions that were made to our existing files.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;code&gt;store.ts&lt;/code&gt;
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function / Object&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;combineReducers()&lt;/td&gt;
&lt;td&gt;Merges all the reducers into a single reducer object. Think of it as throwing all our reducers into a giant box, so that we can easily reference all our reducers by pointing to that giant box.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;persistConfig&lt;/td&gt;
&lt;td&gt;This is a configuration object that is used to customize the persistence of our reducers in our store. The key configuration to include is the key and storage. For our case, we our key is simply root and the storage we are using is the session storage which is imported from redux-persist/lib/storage/session . Alternatively, to use local storage, we can instead import storage from redux-persist/lib/storage but of course, the choice is yours. This will determine where our store and state is being stored. You can look at it as the core of redux-persist as it allows the application to remember and persist the data using the local/session storage as its memory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;persistReducer()&lt;/td&gt;
&lt;td&gt;Takes in the persistConfig object we created earlier, together with the all-in-one reducer to create our persistedReducer. What we are doing is simply applying the persistence configuration on all our reducers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;configureStore()&lt;/td&gt;
&lt;td&gt;If you’re familiar with Redux’s createStore, this is a simply an abstraction/wrapper around that function which helps to add good default to our store setup. This function takes in a configuration object which in our case just includes the persistedReducer we created. This  store is exported and is the same one provisioned via the Provider wrapper in _app.tsx.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;persistStore()&lt;/td&gt;
&lt;td&gt;Finally, we pass our previously created store object into this function, to finalize the creation of a store that is able to persist state, by saving it in the local storage. This persistor is exported to be used in _app.tsx&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;persistConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reducers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;combineReducers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;pokemonTeam&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pokemonTeamReducer&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;persistedReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;persistReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persistConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;persistedReducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;persistor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;persistStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Infer the `RootState` and `AppDispatch` types from the store itself&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RootState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AppDispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. &lt;code&gt;_app.tsx&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Apart from the store that we already provisioned, to ensure that the persistence configuration is set for all the components in our application, we add another wrapper &lt;code&gt;PersistGate&lt;/code&gt;. This wrapper takes in the &lt;code&gt;persistor&lt;/code&gt; that we created in &lt;code&gt;store.ts&lt;/code&gt; and can also take in a loading component. e.g &lt;code&gt;loading={&amp;lt;Loading /&amp;gt;}&lt;/code&gt;. &lt;code&gt;PersistGate&lt;/code&gt; will help to delay the rendering of the app until the persisted state has been retrieved from the local/session storage and saved to redux.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AppProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PersistGate&lt;/span&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;persistor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;persistor&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;PersistGate&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;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;h3&gt;
  
  
  Final Product
&lt;/h3&gt;

&lt;p&gt;Add here’s the new and improved Pokémon team builder, now enhanced with redux-persist! As you can see, our application remembers our team, despite refreshing the page! When we look at the Redux DevTools deeper, we can see that Redux performs a persist and rehydrate, allowing our data to be ‘remembered’ on refresh. Additionally, we can also see that our information is being stored in the session storage, in the key &lt;code&gt;persist:root&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Once again, for an in-depth look at the project, please visit my &lt;a href="https://github.com/Content-Creation-Amir/pokemon-redux-persist-tutorial/tree/main" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. &lt;/p&gt;

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

&lt;p&gt;Redux-persist is a very helpful addon to Redux that allows our application to persist and remember our state, by saving the data in the browser’s persistent storage. This ensures that the data will still be available for our components to modify and utilise, despite a browser refresh. We are able to further specify which storage to use - local or session -  or customize the persistence of our store by including/excluding desired reducers. With that said, what’s stopping you from simply creating a helper function that adds the state to the storage whenever we do a &lt;code&gt;useDispatch()&lt;/code&gt;, and check that storage for existing any data whenever we perform a &lt;code&gt;useSelector()&lt;/code&gt; to retrieve the state? Instead, maybe we could have used &lt;code&gt;localStorage.setItem("team", [])&lt;/code&gt; and &lt;code&gt;localStorage.get('team')&lt;/code&gt; ? Let me know your thoughts on which you prefer or if you have any other alternatives for persisting Redux state!&lt;/p&gt;

&lt;p&gt;Lastly, if you’re looking for a more in depth understanding of redux-persist and its other features and configurability, here are other helpful articles/video you can visit!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://medium.com/async/redux-persist-your-state-7ad346c4dd07" rel="noopener noreferrer"&gt;&lt;em&gt;Redux: Persist Your State&lt;/em&gt;&lt;/a&gt; by Zack (2017)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.reactnativecoach.com/the-definitive-guide-to-redux-persist-84738167975" rel="noopener noreferrer"&gt;&lt;em&gt;The Definitive Guide to Redux Persist&lt;/em&gt;&lt;/a&gt; by Mark Newton (2017)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://codeburst.io/redux-persist-the-good-parts-adfab9f91c3b" rel="noopener noreferrer"&gt;&lt;em&gt;Redux-persist: The Good Parts&lt;/em&gt;&lt;/a&gt; by Feargal Walsh (2018)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=pEzvtMb0HSI&amp;amp;ab_channel=TheMinimalistCoder" rel="noopener noreferrer"&gt;&lt;em&gt;How to persist and rehydrate redux store efficiently&lt;/em&gt;&lt;/a&gt; by The Minimalist Coder (2021)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Basics of AWS Lambda</title>
      <dc:creator>Amir Azhar</dc:creator>
      <pubDate>Thu, 16 Dec 2021 16:47:59 +0000</pubDate>
      <link>https://dev.to/amehpls/basics-of-aws-lambda-1m5l</link>
      <guid>https://dev.to/amehpls/basics-of-aws-lambda-1m5l</guid>
      <description>&lt;h4&gt;
  
  
  YOU HAVE BEEN WARNED!
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;You see, I'm no expert at Amazon Web Services (AWS) or Lambda functions. As a matter of fact, I only just started learning about them 2 weeks ago and have since played around with it during my internship. So please don't come at me if this post isn't as informative as you might have expected. Maybe look at this post as a sort of learning diary by yours truly! With that said, let's get started!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is Lambda&lt;/li&gt;
&lt;li&gt;Why Lambda&lt;/li&gt;
&lt;li&gt;How Lambda&lt;/li&gt;
&lt;li&gt;Closing Remarks&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is Lambda
&lt;/h2&gt;

&lt;p&gt;Like many of you, I've seen the words AWS and Lambda before on the internet but never knew what they meant or what they represented. But now, I'm no longer a lost sheep. So here is some background of AWS and Lambda.&lt;/p&gt;

&lt;h4&gt;
  
  
  AWS
&lt;/h4&gt;

&lt;p&gt;Amazon Web Services or AWS in short, is a subsidiary of Amazon (thank you Papa Bezos) that provides on-demand &lt;em&gt;cloud computing&lt;/em&gt; platform and APIs for companies and individuals. To clarify the technical jargon &lt;em&gt;cloud computing&lt;/em&gt;, it is simply an access to required services such as servers, databases, networking without having to care about managing the actual computer resource. I know, sounds fancy, but that's just the tip of the iceberg of what AWS can offer. Once again, I'm no AWS sensei so we'll only be focusing on one of the services AWS offers - Lambda.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lambda
&lt;/h4&gt;

&lt;p&gt;As defined on the AWS website, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AWS Lambda is a serverless, event-driven compute service that lets you run code for virtually any type of application or backend service without provisioning or managing servers. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, the word &lt;em&gt;serverless&lt;/em&gt;, is a tad bit misleading. It doesn't mean that there aren't any servers. It just means that we don't have to worry about whether our servers have enough resources for our application. All that will be taken care of by AWS. With that said, Lambdas are simply functions that run on these servers that are provisioned by AWS. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Lambda
&lt;/h2&gt;

&lt;p&gt;All this is cool and all but why should YOU use AWS and Lambda? As mentioned earlier, AWS provides a myriad of services. If you're creating your next great startup that requires storage, computing power, databases, analytics and so on. AWS has you covered by being able to offer you all these services under one roof. It makes your development process much more efficient and scalable. So, if you have a resource hungry function that needs integration with a load of different services, why not use Lambda as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Lambda
&lt;/h2&gt;

&lt;p&gt;I know the section title is grammatically incorrect but I just wanted it to fit nicely with the rest of the section titles. Anyways, in this section I'll go through with you a simple step by step process on how I created my first Lambda using the AWS Console. If you haven't already created an AWS account, please do so because I'll be skipping that part and going straight into meat of the matter.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Navigating to the Lambda Service
&lt;/h4&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%2Flm3y6m61n3o797tcsd7t.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%2Flm3y6m61n3o797tcsd7t.png" alt="Navigating to the Lambda Service" width="800" height="455"&gt;&lt;/a&gt;Navigating around the AWS console is as simple as searching for the required service on the search bar located at the top of the screen. Once there, you can go ahead and click on 'Create Function'.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Creating the function
&lt;/h4&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%2F2gxlwwt52zrrrnohdn7q.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%2F2gxlwwt52zrrrnohdn7q.png" alt="Blueprint" width="800" height="348"&gt;&lt;/a&gt; Here, we have 4 options we can choose from but as beginners, we can choose to just focus on the first 2 options.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;u&gt;Author from scratch&lt;/u&gt; means to write the function from scratch&lt;/li&gt;
&lt;li&gt;
&lt;u&gt;Use a blueprint&lt;/u&gt; means that we can choose from a wide selection of templates to base our function off of.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In our case, we will be choosing the latter, and using a Node.js hello-world blueprint. Then, we can go ahead and continue configuring.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Configuration
&lt;/h4&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%2Fe1tu5thtzdhb46am5gql.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%2Fe1tu5thtzdhb46am5gql.png" alt="Basic Info" width="800" height="454"&gt;&lt;/a&gt;At this stage, you can set the name of your function and also set the execution role. &lt;em&gt;What's an execution role?&lt;/em&gt; As mentioned earlier, Lambdas have the power to access other services. By default, its access is not authorized. For starters, selecting the 'Create new role with basic Lambda permissions' will allow us to use the CloudWatch Logs service, a service that helps us collect and store the logs of our Lambda. This should suffice for now but the role can be further modified in the future to allow access to other services whenever you need them.&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%2F3hkzl4zbtwj4o6pdoml4.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%2F3hkzl4zbtwj4o6pdoml4.png" alt="Code" width="800" height="697"&gt;&lt;/a&gt;Lastly, the code from the blueprint is also shown right before you finalise the process by clicking 'Create function'.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4: Modifying the Code
&lt;/h4&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%2Fvbeodmytvex3gv0ocfaj.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%2Fvbeodmytvex3gv0ocfaj.png" alt="Modifying the Code" width="800" height="389"&gt;&lt;/a&gt; Now that we have created the Lambda, there seems to be a lot to unpack - code properties, runtime settings, layers, throttle bla bla bla. But today, we'll just focus on deploying and running the function. &lt;/p&gt;

&lt;p&gt;Before I give a rundown of the code, let me perform some modifications to it so I don't seem like such an amateur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;followers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;followers&lt;/span&gt;

    &lt;span class="c1"&gt;// Thank you to my followers&lt;/span&gt;
    &lt;span class="nx"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;follower&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;follower&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;! Thank you for following and reading my posts!`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// A shoutout to an interesting article&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;`Here's an article I read recently! &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; by &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;All Done!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me now give a quick breakdown of the template syntax. &lt;code&gt;handler&lt;/code&gt; in the &lt;code&gt;index.js&lt;/code&gt; (the entry point) is simply the function that will be called whenever the Lambda is being invoked. This function takes in 2 parameters - &lt;code&gt;event&lt;/code&gt; and &lt;code&gt;context&lt;/code&gt; - with the former being the more important one. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;event&lt;/code&gt; can be seen as the input to the function. This parameter can be in the form of a string, array or more commonly an object. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;context&lt;/code&gt; parameter is an object that provides methods and properties that provide information about the invocation, function, and execution environment. For this example, this parameter is not as important. &lt;/p&gt;

&lt;p&gt;Now, let's just straight into testing it so we can see what it does! Don't forget to click on 'Deploy' whenever you make any changes to the code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 5: Testing
&lt;/h4&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%2F9n1d6b4woxf89liqjpeh.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%2F9n1d6b4woxf89liqjpeh.png" alt="Testing" width="800" height="287"&gt;&lt;/a&gt; Under the testing tab is where can configure our input. Our input is an object that consists 2 properties - &lt;code&gt;article&lt;/code&gt; and &lt;code&gt;followers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;article&lt;/code&gt; is a nested object that has the &lt;code&gt;author&lt;/code&gt; and &lt;code&gt;title&lt;/code&gt; properties, corresponding to an insightful article that I recently read.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;followers&lt;/code&gt; is an array that contains my first 10 followers since I joined Dev.to 3 weeks ago.&lt;/p&gt;

&lt;p&gt;With our test input settled, we can go ahead and click 'Test'.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 6: Results
&lt;/h4&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%2Fta5up91fj94qlmvqwxgt.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%2Fta5up91fj94qlmvqwxgt.png" alt="Results" width="800" height="406"&gt;&lt;/a&gt; Given the simplicity of our function, the execution was completed in mere milliseconds. Let's now focus our attention to the Log Output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START RequestId: c9da68e2-f02a-49bd-ab0c-294fe5f1aeda Version: $LATEST
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @leeraiyan! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @tarantool! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @ravitejamannam! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @martinkr! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @xingtler! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @chawn! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @coder5010! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @sabiyatabassum! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @chesecheif! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Hello @smpofana! Thank you for following and reading my posts!
2021-12-16T15:50:49.461Z    c9da68e2-f02a-49bd-ab0c-294fe5f1aeda    INFO    Here's an article I read recently! 25 Website Performance Metrics to Watch in 2022 by anthonynsimon
END RequestId: c9da68e2-f02a-49bd-ab0c-294fe5f1aeda
REPORT RequestId: c9da68e2-f02a-49bd-ab0c-294fe5f1aeda  Duration: 19.03 ms  Billed Duration: 20 ms  Memory Size: 128 MB     Max Memory Used: 55 MB  Init Duration: 143.67 ms    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As expected, the output included all the logs that were intended, thanking my first 10 followers and giving a shoutout to  anthonysimon's article, &lt;a href="https://dev.to/panelbear/25-website-performance-metrics-to-watch-in-2022-4f60"&gt;25 Website Performance Metrics to Watch in 2022&lt;/a&gt;. In addition to that, we can see how long each step took, the total execution duration and how much memory was used.&lt;/p&gt;

&lt;p&gt;And that's it! We've created our first Lambda function using the AWS console! I know I know, it isn't super impressive but we all start somewhere!&lt;/p&gt;

&lt;h4&gt;
  
  
  Step ???: Additional Information
&lt;/h4&gt;

&lt;p&gt;Now, you might have been afraid when you saw 'Billed Duration' in the summary after invoking your Lambda function. If you're a broke university kid like me or you're just stingy with your money, fret not! AWS makes sure that you only pay for what you use, charged based on the number of function calls and the time it takes to execute it. Per month, users have 1 million free requests and 400,000 GB-seconds free (up to 3.2 million seconds of compute time) to play around with. Thereafter, Amazon charges users as little as $0.0000002 per request and $0.00001667 for every GB-second used, depending on your &lt;a href="https://aws.amazon.com/lambda/pricing/" rel="noopener noreferrer"&gt;region&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're just playing around and not trying to build the next unicorn company, then you won't have to worry about paying for now!&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Remarks
&lt;/h2&gt;

&lt;p&gt;There you have it! I hope this article gives a rough overview on how to create a Lambda on AWS and maybe even give you a glimpse on how you can use it in your next project. This tutorial handles all the intricacies of making a Lambda using the web console. However, if you want to feel more like a &lt;em&gt;hackerman&lt;/em&gt;, you can rest easy knowing that this entire process of creating, deploying and updating a Lambda can be done in a local environment like VSCode. I'll delve deeper into this topic in the future when we explore the &lt;a href="https://www.serverless.com/" rel="noopener noreferrer"&gt;Serverless Framework&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>lambda</category>
    </item>
    <item>
      <title>Just Another (Average) Full Stack Web Project</title>
      <dc:creator>Amir Azhar</dc:creator>
      <pubDate>Wed, 01 Dec 2021 05:26:41 +0000</pubDate>
      <link>https://dev.to/amehpls/just-another-average-full-stack-web-project-1d93</link>
      <guid>https://dev.to/amehpls/just-another-average-full-stack-web-project-1d93</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Background&lt;/li&gt;
&lt;li&gt;Beginnings&lt;/li&gt;
&lt;li&gt;Tech Stack&lt;/li&gt;
&lt;li&gt;Initial Design&lt;/li&gt;
&lt;li&gt;Challenges&lt;/li&gt;
&lt;li&gt;Grand Finale&lt;/li&gt;
&lt;li&gt;Reflections&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Background.
&lt;/h2&gt;

&lt;p&gt;Back in 2019 when I first started delving into web development out of my own interest, I never had the opportunity (or rather, I was massively procrastinating) to start my own full stack web project. My past personal projects were always frontend-focused, using technologies like React or Bootstrap. I always found frontend development to be more enjoyable and captivating, as it allowed me to visualize my work and explore my creative side when designing interfaces.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But it was time to get out of my comfort zone.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I started to dabble in backend technologies - ranging from MongoDB to Express - during the summer of 2021. I used this as an opportunity to learn more technology frameworks and tools, mainly through YouTube tutorials from &lt;a href="https://www.youtube.com/channel/UC29ju8bIPH5as8OGnQzwJyA" rel="noopener noreferrer"&gt;Traversy Media&lt;/a&gt; and &lt;a href="https://www.youtube.com/channel/UCQrQo7jTpOh8V9EDn9Tgnxg" rel="noopener noreferrer"&gt;Full Stack Junkie&lt;/a&gt;. It definitely brought me enjoyment, finally able to explore a whole different side to web development.&lt;/p&gt;

&lt;p&gt;It was not until my final year in National University of Singapore (NUS), August 2021, that I had the opportunity to create my very own full stack web project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beginnings.
&lt;/h2&gt;

&lt;p&gt;As Computer Engineering undergraduates in NUS, we had to complete the infamous CG4002 Capstone module. Why did I say infamous? Well, because this was our first project where we had to utilise all the knowledge and skills that we picked up over the past 3 years of our degree program. Embedded systems? &lt;em&gt;Yup&lt;/em&gt;. Socket programming? &lt;em&gt;Of course&lt;/em&gt;. Machine learning? &lt;em&gt;You bet&lt;/em&gt;. Vivado? &lt;em&gt;Absolutely hate it, but yes&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;I think you get the point.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It was a huge project with so many different components interacting with one another but luckily, we worked in groups, where each one of us played different roles, and became experts in our different fields. Of course, I picked the web development role. &lt;em&gt;Why would I be writing this post if there wasn't any web development.&lt;/em&gt; For just a bit of context, the problem statement of our project was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A wearable system that detects and coaches dance moves of a dance group&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We were given total design freedom, albeit a few guidelines to follow. We could decide the direction of the project and how we wanted to execute it. For my web development component, also known as the dashboard, I had a few requirements to fulfil:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How will the dashboard store, analyze, and display the data from&lt;br&gt;
the dancers in real-time? What analytics can you provide to coach the dancers? How can the dashboard handle many simultaneous  users? How will you assess user feedback of the dashboard?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simply put, dancers would have wearables (with sensors) strapped to their wrists. The data will be used to predict what dance move a dancer is performing. I had to create a dashboard that would display the result of the machine learning model and also provide real-time data visualisation and analytics while the dancers performed their moves. For now, let's not worry about the details of the data pipeline between the other components and mine.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;It's finally time to delve into the web development part that you've all been waiting for.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Tech Stack.
&lt;/h2&gt;

&lt;p&gt;I opted for the MERN tech stack for my project. Let me briefly go through the different components in MERN and why I chose them. It has to be said that the entire web application, both the client and server, was run locally ob my own device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;M&lt;/u&gt;ongoDB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MongoDB is one of the most famous NoSQL database. Unlike traditional databases, MongoDB represents its information in a schemaless series of JSON-like documents, as opposed to the table and row format of relational systems such as PostgreSQL or MySQL. I picked it for 2 main reasons - (1) it allowed me to watch for real-time changes in the database using &lt;a href="https://docs.mongodb.com/manual/changeStreams/" rel="noopener noreferrer"&gt;Change Streams&lt;/a&gt; and (2) I had a complicated love-hate relationship with SQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;E&lt;/u&gt;xpress&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Being a smart (and hard worker) I wanted to achieve my goals without having to write API functions or routes from scratch. Express comes to the rescue as a minimal web application framework that provides me with a myriad of HTTP utility methods and middleware, to ease the creation of APIs. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;R&lt;/u&gt;eact&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course I picked React. What else would I have chosen? React is &lt;em&gt;obviously&lt;/em&gt; the most superior frontend tool. All jokes aside, I was most comfortable with React as compared to other technologies like Vue and Angular, due to my extensive exploration of the library back when I was developing my &lt;a href="//amir-azhar.com"&gt;personal web portfolio&lt;/a&gt;. (sorry for the shameless plug.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;N&lt;/u&gt;ode&lt;/strong&gt;&lt;br&gt;
Using Node was essentially  a no brainer for me. Node would allow me to run JavaScript outside of the browser, hence, I am able to use it server side as well.&lt;/p&gt;


&lt;h2&gt;
  
  
  Initial Design.
&lt;/h2&gt;

&lt;p&gt;Having complete design freedom was definitely exciting, but it can be challenging because it may seem directionless at times. Thankfully, I tried to develop a proper workflow so that I could achieve an extraordinary end result.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I first started to look for &lt;u&gt;inspiration&lt;/u&gt; on this amazing website, &lt;a href="//dribbble.com"&gt;Dribbble&lt;/a&gt;. They had TONS of user-submitted  designs and animations which I then used to generate my own ideas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, I sent out a simple preliminary &lt;u&gt;survey&lt;/u&gt; to my group mates, friends and family. I would then use these (un)overwhelming responses to develop use cases, user stories, and feature lists, all centered around the users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Last step was the exciting part, which involved the &lt;u&gt;designing&lt;/u&gt; of the UI. Thankfully, I had paid for the entire Adobe Creative Suite which included Adobe Xd, which allowed me to create simple mockups.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fih4dl1wbdh4xs7ucs88n.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%2Fih4dl1wbdh4xs7ucs88n.png" alt="Adobe Xd Mockups" width="800" height="644"&gt;&lt;/a&gt; &lt;/p&gt;


&lt;h2&gt;
  
  
  Challenges.
&lt;/h2&gt;

&lt;p&gt;Considering it was my first full stack web project, I was met with quite a few challenges, which was to be expected from a newbie like me. Although I had Teaching Assistants and Professors that could guide my process, I wanted to be as independent as possible. This meant spending countless of sleepless nights debugging, re-designing and scouring the depths of StackOverflow. Here are just a few challenges I faced during the development of the application and I how I tried to overcome them or simply just ignore them (ignorance is bliss).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;u&gt;MongoDB&lt;/u&gt; provides a cloud-based solution, MongoDB Atlas, which handles all the complexity of deploying, managing, and handling of deployments on a cloud service provider of our choice. All I thought I had to do was to just set up the endpoints on my server that would connect to the cloud database and I would be good to go. &lt;em&gt;Boy was I wrong.&lt;/em&gt; Unfortunately, there were troubles connecting to the cloud service on the FPGA that we deployed to run ML predictions and send results to the database. The FPGA was sitting in a lab in campus (we had to connect to it remotely) throughout the course of the project and was connected to the campus network. The network apparently had a certain firewall which I never managed to get around. However, a workaround was to set up the MongoDB server locally on my laptop. Since I was staying on campus, my laptop and the FPGA would be on the same network!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I definitely had troubles displaying &lt;u&gt;real-time graphs&lt;/u&gt; on screen. Despite having MongoDB's Change Streams and &lt;a href="https://socket.io/" rel="noopener noreferrer"&gt;Socket.io&lt;/a&gt; to aid in my real-time streaming, I still faced troubles. The issue was that, my database was receiving data at frequency of 30Hz and my server would then vomit out the data at the same rate to the frontend, resulting in major latency issues. An easy fix I thought of was to sample the incoming data, reducing the frequency to only about 5Hz. On deciding the sampling rate, it was about finding the sweet spot between having minimal latency, and still meeting the requirement of 'real-time'.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The biggest obstacle I faced was the &lt;u&gt;lack of time&lt;/u&gt;. It was nearing the final evaluation but I had submissions for other modules to focus on too. My dashboard was mostly done, except for the sign up, login and logout functionalities. It was a shame as I spent quite a considerable amount of time learning about authentication using &lt;a href="https://jwt.io/introduction" rel="noopener noreferrer"&gt;JSON Web Tokens (JWT)&lt;/a&gt;, and &lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;Redux&lt;/a&gt; to manage and keep track of the state of the application. Since this was originally a 'Nice to Have', I decided to forgo the functionality and simplify the authentication process with just simple conditional checks and password encryption with &lt;a href="https://www.npmjs.com/package/bcrypt" rel="noopener noreferrer"&gt;bcrypt&lt;/a&gt;. I was definitely not proud of it, but considering it was not even a project requirement, and just something I wanted to have fun with, I was not too bummed for long.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Grand Finale.
&lt;/h2&gt;

&lt;p&gt;After almost 4 months of painstaking hard work, it was finally done. Our final evaluation went very smoothly, with the dashboard performing as it should. Since I had to show only a small part of my website during the evaluation, I thought maybe I could shamelessly show off my masterpiece here.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Enjoy&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Here are just some of the tools and npm packages I used in making some of the components of my dashboard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.blobmaker.app/" rel="noopener noreferrer"&gt;Blobmaker&lt;/a&gt; - A free web design tool to help quickly create random, unique, and organic-looking SVG shapes.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nivo.rocks/components" rel="noopener noreferrer"&gt;Nivo&lt;/a&gt; - A library that provides a myriad of highly customisable data visualisation tools.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.material-ui-datatables.com/" rel="noopener noreferrer"&gt;Material UI DataTables&lt;/a&gt; - A simple data table component that comes with features like filtering, view/hide columns, search and many more.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://react-bootstrap.github.io/" rel="noopener noreferrer"&gt;React Bootstrap&lt;/a&gt; - A library that provides many easy-to-use and highly customisable components, essential in any modern web application.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Reflections.
&lt;/h2&gt;

&lt;p&gt;Was I happy with my work? &lt;em&gt;Absolutely&lt;/em&gt;. Could I have done more? &lt;em&gt;Maybe?&lt;/em&gt; When all is said and done, I believed that it was a great experience finally doing a deep dive on the different aspects of full stack web development. From exploring my misconceptions in React to understanding how HTTP requests work, I definitely learned a lot throughout this journey. This project showed me that backend development was definitely not my cup of tea and I still had a very soft spot for frontend development. I would like to give a shoutout to my lovely groupmates Andrew, Billy, Jess, Jiayi and Alex for being such great teammates and for making my CG4002 journey memorable. To others, this project may seem trivial and simple, but it was definitely a stepping stone for me in becoming a proficient web developer.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here's to many more projects!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>react</category>
    </item>
  </channel>
</rss>
