<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[TheQoder's Blog (jideabdqudus)]]></title><description><![CDATA[Articles to help you learn and master modern software technologies.]]></description><link>https://blog.abdulqudus.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1631529410234/-RoHyUgmz.png</url><title>TheQoder&apos;s Blog (jideabdqudus)</title><link>https://blog.abdulqudus.com</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 12 May 2026 21:52:46 GMT</lastBuildDate><atom:link href="https://blog.abdulqudus.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Scalable REST API Architecture with NestJS, Prisma, Swagger, & Docker: How To.]]></title><description><![CDATA[Introduction
In today's rapidly evolving tech landscape, building robust, scalable, and maintainable backend services is a critical skill for developers. This article explores how to leverage modern technologies like NestJS, Docker, Swagger, and Pris...]]></description><link>https://blog.abdulqudus.com/scalable-rest-api-using-nest</link><guid isPermaLink="true">https://blog.abdulqudus.com/scalable-rest-api-using-nest</guid><category><![CDATA[nestjs]]></category><category><![CDATA[APIs]]></category><category><![CDATA[backend]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Mon, 12 May 2025 12:00:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744510533715/1f3fb461-c4d0-42c8-931c-4d83d1d2a6d8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>In today's rapidly evolving tech landscape, building robust, scalable, and maintainable backend services is a critical skill for developers. This article explores how to leverage modern technologies like NestJS, Docker, Swagger, and Prisma to create a production-ready REST API. You will learn the core fundamentals of NestJS and best practices while referencing code from <a target="_blank" href="https://github.com/jideabdqudus/task-manager-api">this repository</a>.</p>
<p>Modern applications require architectures that facilitate easy maintenance, testing, and scaling. NestJS, a progressive Node.js framework, provides an excellent foundation with its modular, TypeScript-based approach. Combined with Prisma for database operations, Swagger for API documentation, and Docker for containerization, you have a powerful stack for building server-side applications.</p>
<p>To follow step-by-step you can refer to the fully functional application available in this repository.</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/jideabdqudus/task-manager-api.git
</code></pre>
<h2 id="heading-stack-overview">Stack Overview</h2>
<ol>
<li><h3 id="heading-nestjs">NestJS</h3>
<p> NestJS is a progressive Node.js framework inspired by Angular's architecture. It uses TypeScript and follows object-oriented programming principles, making it ideal for building scalable server-side applications. Its modular structure encourages the separation of concerns, leading to more maintainable code. (<a target="_blank" href="https://nestjs.com/">Check out Nest</a>)</p>
</li>
<li><h3 id="heading-prisma">Prisma</h3>
<p> Prisma is a next-generation ORM (Object-Relational Mapping) that significantly simplifies database access. With its type-safe database client and schema-based approach, Prisma ensures that database operations are both secure and predictable. (<a target="_blank" href="https://www.prisma.io/">Check out Prisma</a>)</p>
</li>
<li><h3 id="heading-swagger">Swagger</h3>
<p> Swagger (OpenAPI) is a powerful tool for documenting and testing APIs. It provides interactive documentation that makes it easier for front-end developers and API consumers to understand and use your endpoints. (<a target="_blank" href="https://swagger.io/">Check out Swagger</a>)</p>
</li>
<li><h3 id="heading-docker">Docker</h3>
<p> Docker enables consistent application deployment across different environments through containerization. By packaging your application and its dependencies into containers, you ensure that it runs the same way in development, testing, and production. (<a target="_blank" href="https://www.docker.com/">Check out Docker</a>)</p>
</li>
</ol>
<h2 id="heading-architecture">Architecture</h2>
<p>Whether you’re new to NestJS or looking to expand your skills, this article provides step-by-step instructions to build a full-featured API.</p>
<p>The task management API follows a modular architecture:</p>
<pre><code class="lang-bash">src/
├── auth/             <span class="hljs-comment"># Authentication module</span>
├── tasks/            <span class="hljs-comment"># Task management module</span>
├── user/             <span class="hljs-comment"># User management module</span>
├── database/         <span class="hljs-comment"># Database module with Prisma service</span>
├── app.module.ts     <span class="hljs-comment"># Main application module</span>
└── main.ts           <span class="hljs-comment"># Application entry point</span>
</code></pre>
<p>This structure separates the application into domain-specific modules, each handling specific business logic. Each module contains controllers (handling HTTP requests), services/providers (implementing business logic), and DTOs (Data Transfer Objects).</p>
<p>The final result of your application should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744327308984/b406ba41-ee7e-4c43-ba1b-d9172da85a11.png" alt="Swagger docs showing the endpoints." class="image--center mx-auto" /></p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>This tutorial is designed to be beginner-friendly, but it would be helpful if you’re familiar with these:</p>
<ul>
<li><p>Basic NestJS</p>
</li>
<li><p>TypeScript</p>
</li>
<li><p>Docker</p>
</li>
</ul>
<p>Make sure you have the following installed before you begin:</p>
<ul>
<li><p><strong>Node.js</strong> (v16 or later)</p>
</li>
<li><p><strong>Node Package Manager</strong></p>
</li>
<li><p><strong>Docker &amp; Docker Compose</strong></p>
</li>
<li><p><strong>PostgreSQL</strong> (or your preferred database)</p>
</li>
</ul>
<h2 id="heading-step-1-setting-up-your-nestjs-project">Step 1: Setting Up Your NestJS Project</h2>
<p>Create a new NestJS project using the CLI:</p>
<pre><code class="lang-bash">npm i -g @nestjs/cli <span class="hljs-comment"># run if you don't have the NestJS CLI installed already</span>
nest new task-manager-api
<span class="hljs-built_in">cd</span> task-manager-api
</code></pre>
<p>This command scaffolds a basic NestJS application with all essential configurations. The CLI will prompt you to choose a package manager (npm or yarn). Select your preference, and NestJS will scaffold a basic project structure for you. This initial structure provides the foundation for the application.</p>
<p>As said earlier, Nest follows a modular architecture inspired by Angular. The file structure is of format:</p>
<ul>
<li><p><strong>Modules</strong>: Organize application components into logical units</p>
</li>
<li><p><strong>Controllers</strong>: Handle HTTP requests and return responses</p>
</li>
<li><p><strong>Services</strong>: Contain business logic used by controllers</p>
</li>
<li><p><strong>Providers</strong>: Injectable components that can be shared across the application</p>
</li>
</ul>
<p>The <code>src</code> directory is where the essential bits of the application would be and the majority of the codebase. On initializing the application, you’d find some key files in there.</p>
<ul>
<li><p><strong>src/main.ts:</strong> Entry point that bootstraps the application</p>
</li>
<li><p><strong>src/app.module.ts</strong>: Root module that imports and organizes all other modules</p>
</li>
<li><p><strong>src/app.controller.ts</strong>: Basic controller handling routes/endpoints</p>
</li>
<li><p><strong>src/app.service.ts</strong>: Contains business logic used by the controller</p>
</li>
</ul>
<p>Feel free to remove the <code>app.controller.spec.ts</code>, <code>./app.service</code>, and <code>./app.controller</code> files to emulate a fresh codebase.</p>
<p>To start the app, you can run <code>npm run start:dev</code></p>
<p><a target="_blank" href="https://github.com/jideabdqudus/task-manager-api/tree/initial-app-strucutre">⭐️ View Codebase</a></p>
<hr />
<h2 id="heading-step-2-setting-up-the-database-with-prisma">Step 2: <strong>Setting Up the Database with Prisma</strong></h2>
<p>Prisma provides a clean, type-safe interface to the PostgreSQL database.</p>
<ol>
<li><p><strong>Install Prisma:</strong></p>
<pre><code class="lang-bash"> npm install @prisma/client
 npm install --save-dev prisma
</code></pre>
</li>
<li><p><strong>Initialize Prisma:</strong></p>
<pre><code class="lang-bash"> npx prisma init
</code></pre>
<p> This creates a <code>prisma/</code> directory with a <code>schema.prisma</code> file. Update the file to define models for <strong>User</strong> and <strong>Task</strong>.</p>
<pre><code class="lang-typescript"> <span class="hljs-comment">// prisma/schema.prisma</span>
 generator client {
   provider = <span class="hljs-string">"prisma-client-js"</span>
 }

 datasource db {
   provider = <span class="hljs-string">"postgresql"</span>
   url      = env(<span class="hljs-string">"DATABASE_URL"</span>)
 }

 model User {
   id        Int     <span class="hljs-meta">@id</span> <span class="hljs-meta">@default</span>(autoincrement())
   email     <span class="hljs-built_in">String</span>  <span class="hljs-meta">@unique</span>
   password  <span class="hljs-built_in">String</span>
   name      <span class="hljs-built_in">String</span>
   tasks Task[]
   createdAt DateTime <span class="hljs-meta">@default</span>(now())
   updatedAt DateTime <span class="hljs-meta">@updatedAt</span>
 }

 model Task {
   id          Int      <span class="hljs-meta">@id</span> <span class="hljs-meta">@default</span>(autoincrement())
   title       <span class="hljs-built_in">String</span>
   description <span class="hljs-built_in">String</span>?
   status      Status   <span class="hljs-meta">@default</span>(PENDING)
   priority    Priority <span class="hljs-meta">@default</span>(MEDIUM)
   dueDate     DateTime?
   category    <span class="hljs-built_in">String</span>?
   labels      <span class="hljs-built_in">String</span>?
   ownerId     Int
   owner       User     <span class="hljs-meta">@relation</span>(fields: [ownerId], references: [id])
   createdAt   DateTime <span class="hljs-meta">@default</span>(now())
   updatedAt   DateTime <span class="hljs-meta">@updatedAt</span>
 }
 <span class="hljs-built_in">enum</span> Status {
   PENDING
   IN_PROGRESS
   COMPLETED
 }

 <span class="hljs-built_in">enum</span> Priority {
   LOW
   MEDIUM
   HIGH
 }
</code></pre>
</li>
<li><p><strong>Migrate the Database:</strong></p>
<p> Set your <code>DATABASE_URL</code> in a <code>.env</code> file and run:</p>
<pre><code class="lang-bash"> npx prisma migrate dev --name init
</code></pre>
<p> To find out how to create your Database URL, there are helpful guides based on the service you’d like to use (<a target="_blank" href="https://supabase.com/docs/guides/database/prisma">Supabase</a>, <a target="_blank" href="https://neon.tech/docs/guides/prisma">Neon</a> etc.)</p>
</li>
</ol>
<p>This schema defines the data models along with their relationships. Prisma generates a type-safe client from this schema, providing methods for CRUD operations with full TypeScript support.</p>
<p>Based on your chosen service, you should see the tables after migration.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744508411911/5b6d8633-2713-4e24-a6df-d2d025410d01.png" alt="Supabase Database Table" class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://github.com/jideabdqudus/task-manager-api/tree/prisma-integration">⭐️ View Codebase</a></p>
<hr />
<h2 id="heading-step-3-create-database-service">Step 3: <strong>Create Database Service</strong></h2>
<p>Let’s create a Database service to handle the Primsa operations. It makes it easy to interact with the database through the application.</p>
<p>You can create services, modules, and controllers directly through your CLI</p>
<pre><code class="lang-bash">nest g module     &lt;name&gt;  <span class="hljs-comment"># generates a module only</span>
nest g service    &lt;name&gt;  <span class="hljs-comment"># generates a service only  </span>
nest g controller &lt;name&gt;  <span class="hljs-comment"># generates a controller only</span>
nest g resource   &lt;name&gt;  <span class="hljs-comment"># generates all 3 of the above</span>
</code></pre>
<p>You can, therefore, generate the database service and module (no controller).</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/database.service.ts</span>
<span class="hljs-keyword">import</span> { Injectable, OnModuleInit, OnModuleDestroy } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { PrismaClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@prisma/client'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DatabaseService
  <span class="hljs-keyword">extends</span> PrismaClient
  <span class="hljs-keyword">implements</span> OnModuleInit, OnModuleDestroy
{
  <span class="hljs-keyword">async</span> onModuleInit() {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.$connect();
  }

  <span class="hljs-keyword">async</span> onModuleDestroy() {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.$disconnect();
  }
}
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/database.module.ts</span>
<span class="hljs-keyword">import</span> { Module, Global } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { DatabaseService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./database.service'</span>;

<span class="hljs-meta">@Global</span>()
<span class="hljs-meta">@Module</span>({
  providers: [DatabaseService],
  <span class="hljs-built_in">exports</span>: [DatabaseService],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DatabaseModule {}
</code></pre>
<p>Ordinarily, the newly created services and modules get imported into the <code>app.module.ts</code> file. So ensure they are found there.</p>
<p><a target="_blank" href="https://github.com/jideabdqudus/task-manager-api/tree/database-resource">⭐️ View Codebase</a></p>
<hr />
<h2 id="heading-step-4-configure-swagger">Step 4: <strong>Configure Swagger</strong></h2>
<p>The application uses Swagger to automatically generate interactive API documentation. You can configure Swagger in the <code>main.ts</code> file.</p>
<ol>
<li><p><strong>Install Swagger:</strong></p>
<pre><code class="lang-bash"> npm install --save @nestjs/swagger swagger-ui-express
</code></pre>
</li>
<li><p><strong>Update</strong> <code>main.ts</code> <strong>file:</strong></p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">import</span> { NestFactory } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/core'</span>;
 <span class="hljs-keyword">import</span> { AppModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.module'</span>;
 <span class="hljs-keyword">import</span> { SwaggerModule, DocumentBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/swagger'</span>;

 <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bootstrap</span>(<span class="hljs-params"></span>) </span>{
   <span class="hljs-keyword">const</span> app = <span class="hljs-keyword">await</span> NestFactory.create(AppModule);
   <span class="hljs-keyword">const</span> config = <span class="hljs-keyword">new</span> DocumentBuilder()
     .setTitle(<span class="hljs-string">'Tasks API'</span>)
     .setDescription(<span class="hljs-string">'Task Management API'</span>)
     .addBearerAuth({ <span class="hljs-comment">// Validation for Protected Routes</span>
       <span class="hljs-keyword">type</span>: <span class="hljs-string">'http'</span>,
       name: <span class="hljs-string">'JWT'</span>,
       scheme: <span class="hljs-string">'bearer'</span>,
       bearerFormat: <span class="hljs-string">'JWT'</span>,
     })
     .setVersion(<span class="hljs-string">'1.0'</span>)
     .addTag(<span class="hljs-string">'tasks'</span>)
     .build();
   <span class="hljs-keyword">const</span> <span class="hljs-built_in">document</span> = SwaggerModule.createDocument(app, config);
   SwaggerModule.setup(<span class="hljs-string">'api-docs'</span>, app, <span class="hljs-built_in">document</span>);
   <span class="hljs-keyword">await</span> app.listen(process.env.PORT ?? <span class="hljs-number">3000</span>);
 }
 bootstrap();
</code></pre>
<p> This setup creates an interactive documentation interface at the <code>/api-docs</code> endpoint, where developers can explore and test the API.</p>
<p> <a target="_blank" href="https://github.com/jideabdqudus/task-manager-api/tree/swagger-configuration">⭐️ View Codebase</a></p>
</li>
</ol>
<hr />
<h2 id="heading-step-5-restful-endpoints">Step 5: <strong>RESTful Endpoints</strong></h2>
<p>Before advancing into this section, it’s important you follow with the <a target="_blank" href="https://github.com/jideabdqudus/task-manager-api/tree/rest-endpoints">codebase</a> at this point as this would be an overview of what to expect.</p>
<p>In NestJS, when building a feature like task-management, you'll typically work with four main components: Modules, Controllers, Services, and DTOs. Let's dive deep into how these components interact and the development flow for creating a complete resource.</p>
<ol>
<li><p><strong>Modules</strong></p>
<p> In NestJS, <strong>modules</strong> are the organizational units that encapsulate related functionality. They help maintain a clean, organized codebase as applications grow in complexity. Each feature (like Tasks) typically has its own module.</p>
<p> Here's the possible structure of the TaskModule:</p>
<pre><code class="lang-typescript"> <span class="hljs-comment">// src/tasks.module.ts</span>
 <span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

 <span class="hljs-meta">@Module</span>({
   imports: [DatabaseModule], <span class="hljs-comment">// Import dependencies from other modules</span>
   controllers: [TasksController], <span class="hljs-comment">// Register controllers</span>
   providers: [TasksService], <span class="hljs-comment">// Register services</span>
   <span class="hljs-built_in">exports</span>: [TasksService], <span class="hljs-comment">// Export services for use in other modules</span>
 })
 <span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> TaskModule {}
</code></pre>
<p> This decorator-based configuration tells NestJS:</p>
<ul>
<li><p>Which other modules this module depends on</p>
</li>
<li><p>Which controllers handle the HTTP requests</p>
</li>
<li><p>Which providers (services) implement the business logic</p>
</li>
<li><p>Which providers should be available to other modules</p>
</li>
</ul>
</li>
<li><p><strong>Controllers</strong></p>
<p> <strong>Controllers</strong> are responsible for handling incoming HTTP requests and returning responses to the client. They define routes and use decorators to specify HTTP methods (GET, POST, etc.). Controllers depend on services to perform the actual business logic.</p>
<p> Here's your task controller with detailed annotations:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">import</span> {
   Controller,
   Get,
   Post,
   Body,
   Patch,
   Param,
   Delete,
 } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
 <span class="hljs-keyword">import</span> {
   ApiTags,
   ApiOperation,
   ApiResponse,
   ApiBearerAuth,
 } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/swagger'</span>;
 <span class="hljs-keyword">import</span> { CreateTaskDto } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dto/create-task.dto'</span>;
 <span class="hljs-keyword">import</span> { UpdateTaskDto } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dto/update-task.dto'</span>;
 <span class="hljs-keyword">import</span> { JwtAuthGuard } <span class="hljs-keyword">from</span> <span class="hljs-string">'../auth/guards/jwt-auth.guard'</span>;

 <span class="hljs-meta">@ApiTags</span>(<span class="hljs-string">'tasks'</span>) <span class="hljs-comment">// Swagger tag for grouping endpoints in documentation</span>
 <span class="hljs-meta">@Controller</span>(<span class="hljs-string">'tasks'</span>) <span class="hljs-comment">// Base route prefix (/api/tasks)</span>
 <span class="hljs-meta">@UseGuards</span>(JwtAuthGuard) <span class="hljs-comment">// Authentication guard applied to all endpoints</span>
 <span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> TasksController {
   <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> tasksService: TasksService</span>) {} <span class="hljs-comment">// Dependency injection</span>

   <span class="hljs-meta">@Post</span>() <span class="hljs-comment">// HTTP POST method for creating resources</span>
   <span class="hljs-meta">@ApiOperation</span>({ summary: <span class="hljs-string">'Create a new task'</span> }) <span class="hljs-comment">// Swagger documentation</span>
   <span class="hljs-meta">@ApiResponse</span>({
     status: <span class="hljs-number">201</span>,
     description: <span class="hljs-string">'The task has been successfully created.'</span>,
   })
   <span class="hljs-meta">@ApiBearerAuth</span>() <span class="hljs-comment">// Indicates authentication requirement in Swagger</span>
   create(<span class="hljs-meta">@Request</span>() req, <span class="hljs-meta">@Body</span>() createTaskDto: CreateTaskDto) {
     <span class="hljs-comment">// Extract user ID from JWT token payload</span>
     <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.tasksService.create({
       ...createTaskDto,
       ownerId: (req <span class="hljs-keyword">as</span> { user: { userId: <span class="hljs-built_in">number</span> } }).user.userId,
     });
   }

   <span class="hljs-meta">@Get</span>() <span class="hljs-comment">// HTTP GET method for retrieving resources</span>
   <span class="hljs-meta">@ApiOperation</span>({ summary: <span class="hljs-string">'Get all tasks'</span> })
   <span class="hljs-meta">@ApiResponse</span>({
     status: <span class="hljs-number">200</span>,
     description: <span class="hljs-string">'The tasks have been successfully retrieved.'</span>,
   })
   <span class="hljs-meta">@ApiBearerAuth</span>()
   findAll(<span class="hljs-meta">@Request</span>() req: unknown) {
     <span class="hljs-comment">// Return only tasks owned by the authenticated user</span>
     <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.tasksService.findAllByUser(
       (req <span class="hljs-keyword">as</span> { user: { userId: <span class="hljs-built_in">number</span> } }).user.userId,
     );
   }

   <span class="hljs-meta">@Get</span>(<span class="hljs-string">':id'</span>) <span class="hljs-comment">// Dynamic route parameter</span>
   <span class="hljs-meta">@ApiOperation</span>({ summary: <span class="hljs-string">'Get a task by id'</span> })
   <span class="hljs-meta">@ApiResponse</span>({
     status: <span class="hljs-number">200</span>,
     description: <span class="hljs-string">'The task has been successfully retrieved.'</span>,
   })
   <span class="hljs-meta">@ApiBearerAuth</span>()
   findOne(<span class="hljs-meta">@Request</span>() req: unknown, <span class="hljs-meta">@Param</span>(<span class="hljs-string">'id'</span>) id: <span class="hljs-built_in">string</span>) {
     <span class="hljs-comment">// Convert string ID to number with the + operator</span>
     <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.tasksService.findOne(
       +id,
       (req <span class="hljs-keyword">as</span> { user: { userId: <span class="hljs-built_in">number</span> } }).user,
     );
   }

   <span class="hljs-meta">@Patch</span>(<span class="hljs-string">':id'</span>) <span class="hljs-comment">// HTTP PATCH for partial updates</span>
   <span class="hljs-meta">@ApiOperation</span>({ summary: <span class="hljs-string">'Update a task'</span> })
   <span class="hljs-meta">@ApiResponse</span>({
     status: <span class="hljs-number">200</span>,
     description: <span class="hljs-string">'The task has been successfully updated.'</span>,
   })
   <span class="hljs-meta">@ApiBearerAuth</span>()
   update(
     <span class="hljs-meta">@Request</span>() req: unknown,
     <span class="hljs-meta">@Param</span>(<span class="hljs-string">'id'</span>) id: <span class="hljs-built_in">string</span>,
     <span class="hljs-meta">@Body</span>() updateTaskDto: UpdateTaskDto,
   ) {
     <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.tasksService.update(
       +id,
       updateTaskDto,
       (req <span class="hljs-keyword">as</span> { user: { userId: <span class="hljs-built_in">number</span> } }).user,
     );
   }

   <span class="hljs-meta">@Delete</span>(<span class="hljs-string">':id'</span>) <span class="hljs-comment">// HTTP DELETE for removing resources</span>
   <span class="hljs-meta">@ApiOperation</span>({ summary: <span class="hljs-string">'Delete a task'</span> })
   <span class="hljs-meta">@ApiResponse</span>({
     status: <span class="hljs-number">200</span>,
     description: <span class="hljs-string">'The task has been successfully deleted.'</span>,
   })
   <span class="hljs-meta">@ApiBearerAuth</span>()
   remove(<span class="hljs-meta">@Request</span>() req: unknown, <span class="hljs-meta">@Param</span>(<span class="hljs-string">'id'</span>) id: <span class="hljs-built_in">string</span>) {
     <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.tasksService.remove(
       +id,
       (req <span class="hljs-keyword">as</span> { user: { userId: <span class="hljs-built_in">number</span> } }).user,
     );
   }
 }
</code></pre>
<p> Notice how each method in the controller:</p>
<ol>
<li><p>Uses specific HTTP method decorators (<code>@Get()</code>, <code>@Post()</code>, etc).</p>
</li>
<li><p>Accepts parameters from various sources (<code>@Body()</code>, <code>@Param()</code>, <code>@Request()</code>)</p>
</li>
<li><p>Delegates the actual business logic to the injected service</p>
</li>
<li><p>Includes Swagger documentation for API explorability</p>
</li>
</ol>
</li>
<li><p><strong>Services</strong></p>
<p> <strong>Services</strong> implement the business logic and are responsible for data storage and retrieval. They abstract the database operations and provide a clean interface for controllers. In the architecture, services interact with the Prisma client to perform database operations.</p>
<p> Here's a simplified view of the task service:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">import</span> {
   Injectable,
   NotFoundException,
   ForbiddenException,
 } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

 <span class="hljs-meta">@Injectable</span>() <span class="hljs-comment">// Makes the service available for dependency injection</span>
 <span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> TasksService {
   <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> databaseService: DatabaseService</span>) {} <span class="hljs-comment">// Inject the Prisma client service</span>

   <span class="hljs-keyword">async</span> create(createTaskDto: CreateTaskDto &amp; { ownerId: <span class="hljs-built_in">number</span> }) {
     <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.databaseService.task.create({
       data: createTaskDto,
     });
   }

   <span class="hljs-keyword">async</span> findAllByUser(userId: <span class="hljs-built_in">number</span>) {
     <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.databaseService.task.findMany({
       where: { ownerId: userId },
       orderBy: { updatedAt: <span class="hljs-string">'desc'</span> },
     });
   }

   <span class="hljs-keyword">async</span> findOne(id: <span class="hljs-built_in">number</span>, user: { userId: <span class="hljs-built_in">number</span> }) {
     <span class="hljs-keyword">const</span> task = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.databaseService.task.findUnique({
       where: { id },
     });

     <span class="hljs-keyword">if</span> (!task) {
       <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotFoundException(<span class="hljs-string">`Task with ID <span class="hljs-subst">${id}</span> not found`</span>);
     }

     <span class="hljs-comment">// Authorization check</span>
     <span class="hljs-keyword">if</span> (task.ownerId !== user.userId) {
       <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ForbiddenException(<span class="hljs-string">'You can only access your own tasks'</span>);
     }

     <span class="hljs-keyword">return</span> task;
   }

   <span class="hljs-comment">// Update and delete methods follow a similar pattern</span>
 }
</code></pre>
<p> The service layer is where business rules, validations, and authorization checks should be implemented. The <code>TasksService</code> ensures that users can only access, modify, or delete their own tasks.</p>
</li>
<li><p><strong>DTOs (Data Transfer Objects)</strong></p>
<p> <strong>DTOs</strong> define the shape of data for a specific API operation. They provide type safety and validation through decorators, ensuring that incoming requests conform to expected formats.</p>
<p> The CreateTaskDto:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">import</span> { ApiProperty } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/swagger'</span>;
 <span class="hljs-keyword">import</span> {
   IsNotEmpty,
   IsString,
   IsOptional,
   IsEnum,
   IsISO8601,
 } <span class="hljs-keyword">from</span> <span class="hljs-string">'class-validator'</span>;
 <span class="hljs-keyword">import</span> { Status, Priority } <span class="hljs-keyword">from</span> <span class="hljs-string">'@prisma/client'</span>;

 <span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CreateTaskDto {
   <span class="hljs-meta">@ApiProperty</span>() <span class="hljs-comment">// Swagger documentation</span>
   <span class="hljs-meta">@IsString</span>() <span class="hljs-comment">// Validation: must be a string</span>
   <span class="hljs-meta">@IsNotEmpty</span>() <span class="hljs-comment">// Validation: cannot be empty</span>
   title: <span class="hljs-built_in">string</span>;

   <span class="hljs-meta">@ApiProperty</span>({ required: <span class="hljs-literal">false</span> })
   <span class="hljs-meta">@IsString</span>()
   <span class="hljs-meta">@IsOptional</span>() <span class="hljs-comment">// Marks the field as optional</span>
   description?: <span class="hljs-built_in">string</span>;

   <span class="hljs-meta">@ApiProperty</span>({ <span class="hljs-built_in">enum</span>: Status, <span class="hljs-keyword">default</span>: Status.PENDING })
   <span class="hljs-meta">@IsEnum</span>(Status) <span class="hljs-comment">// Validation: must be one of the enum values</span>
   <span class="hljs-meta">@IsOptional</span>()
   status?: Status;

   <span class="hljs-meta">@ApiProperty</span>({ <span class="hljs-built_in">enum</span>: Priority, <span class="hljs-keyword">default</span>: Priority.MEDIUM })
   <span class="hljs-meta">@IsEnum</span>(Priority)
   <span class="hljs-meta">@IsOptional</span>()
   priority?: Priority;

   <span class="hljs-meta">@ApiProperty</span>({ required: <span class="hljs-literal">false</span> })
   <span class="hljs-meta">@IsDateString</span>() <span class="hljs-comment">// Validates ISO date string format</span>
   <span class="hljs-meta">@IsOptional</span>()
   dueDate?: <span class="hljs-built_in">string</span>;

   <span class="hljs-meta">@ApiProperty</span>({ required: <span class="hljs-literal">false</span> })
   <span class="hljs-meta">@IsString</span>()
   <span class="hljs-meta">@IsOptional</span>()
   category?: <span class="hljs-built_in">string</span>;

   <span class="hljs-meta">@ApiProperty</span>({ required: <span class="hljs-literal">false</span> })
   <span class="hljs-meta">@IsString</span>()
   <span class="hljs-meta">@IsOptional</span>()
   labels?: <span class="hljs-built_in">string</span>;
 }
</code></pre>
<p> UpdateTaskDto extends from a partial version of CreateTaskDto, making all fields optional for updates. Basically, what this does is take a copy of the CreateTaskDto whilst making its fields optional. You can decide to extend it further depending on the needs of your application:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> UpdateTaskDto <span class="hljs-keyword">extends</span> PartialType(CreateTaskDto) {}
</code></pre>
<p> <a target="_blank" href="https://github.com/jideabdqudus/task-manager-api/tree/rest-endpoints">⭐️ View Codebase</a></p>
</li>
</ol>
<hr />
<h2 id="heading-understanding-the-building-blocks-of-nest"><strong>Understanding the building blocks of Nest</strong></h2>
<p>As you can tell, when developing a new feature or resource in NestJS, a typical workflow would be:</p>
<ol>
<li><p><strong>Define the Data Model</strong>: Start with the Prisma schema to define the database model for your resource (in our case, the Task model).</p>
</li>
<li><p><strong>Generate DTOs</strong>: Create Data Transfer Objects to define the shapes of requests and responses (CreateTaskDto, UpdateTaskDto).</p>
</li>
<li><p><strong>Create the Service</strong>: Implement the business logic that interacts with the database via Prisma (TasksService).</p>
</li>
<li><p><strong>Build the Controller</strong>: Define the API endpoints that map to service methods (TasksController).</p>
</li>
<li><p><strong>Configure the Module</strong>: Wire everything together in a module (TaskModule).</p>
</li>
<li><p><strong>Add Swagger Documentation</strong>: Add API documentation using decorators wherever necessary.</p>
</li>
<li><p><strong>Implement Authentication/Authorization</strong>: Add guards and strategies for protecting routes.</p>
</li>
<li><p><strong>Write Tests</strong>: Create unit and integration tests to verify the functionality.</p>
</li>
</ol>
<p>This modular approach allows developers to work on different parts of the feature independently and promotes code reusability and separation of concerns.</p>
<hr />
<h2 id="heading-step-6-containerization-with-docker">Step 6: <strong>Containerization with Docker</strong></h2>
<p>Docker ensures that the application runs consistently across environments. Our multi-stage Dockerfile optimizes for both development and production:</p>
<pre><code class="lang-dockerfile"><span class="hljs-comment"># Dockerfile</span>

<span class="hljs-comment"># Development stage</span>
<span class="hljs-keyword">FROM</span> node:<span class="hljs-number">20</span>-alpine AS development
<span class="hljs-keyword">WORKDIR</span><span class="bash"> /usr/src/app</span>
<span class="hljs-keyword">COPY</span><span class="bash"> package*.json ./</span>
<span class="hljs-keyword">RUN</span><span class="bash"> npm install</span>
<span class="hljs-keyword">COPY</span><span class="bash"> . .</span>
<span class="hljs-keyword">RUN</span><span class="bash"> npm run build</span>

<span class="hljs-comment"># Production stage</span>
<span class="hljs-keyword">FROM</span> node:<span class="hljs-number">20</span>-alpine AS production
<span class="hljs-keyword">ARG</span> NODE_ENV=production
<span class="hljs-keyword">ENV</span> NODE_ENV=${NODE_ENV}
<span class="hljs-keyword">WORKDIR</span><span class="bash"> /usr/src/app</span>
<span class="hljs-keyword">COPY</span><span class="bash"> package*.json ./</span>
<span class="hljs-keyword">RUN</span><span class="bash"> npm install --only=production</span>
<span class="hljs-keyword">COPY</span><span class="bash"> . .</span>
<span class="hljs-keyword">COPY</span><span class="bash"> --from=development /usr/src/app/dist ./dist</span>
<span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"node"</span>, <span class="hljs-string">"dist/main"</span>]</span>
</code></pre>
<p>This approach:</p>
<ol>
<li><p>Creates a development image with all dependencies for building</p>
</li>
<li><p>Creates a production image with only production dependencies</p>
</li>
<li><p>Copies the built application from the development stage to the production image</p>
</li>
</ol>
<p>Combined with docker-compose, this setup allows for easy orchestration of the API alongside its PostgreSQL database.</p>
<p>Next, you’ll need to create a <code>docker-compose.yml</code> file</p>
<pre><code class="lang-bash">touch docker-compose.yml     <span class="hljs-comment"># creates docker-compose.yml file</span>
</code></pre>
<p>You can then add the following code to the created file</p>
<pre><code class="lang-yaml"><span class="hljs-attr">version:</span> <span class="hljs-string">'3.8'</span>
<span class="hljs-attr">services:</span>
  <span class="hljs-attr">postgres:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">postgres:13.5</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">POSTGRES_USER:</span> <span class="hljs-string">postgres</span>
      <span class="hljs-attr">POSTGRES_PASSWORD:</span> <span class="hljs-string">postgres</span>
      <span class="hljs-attr">POSTGRES_DB:</span> <span class="hljs-string">nest_task</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">postgres-data:/var/lib/postgresql/data</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">'5432:5432'</span>
<span class="hljs-attr">volumes:</span>
  <span class="hljs-attr">postgres-data:</span>
</code></pre>
<p>To start the container, run <code>docker compose up</code> . Ensure you have docker installed before running this on your machine. By now, you should have the PostgreSQL container running. To stop the container, you can run <code>docker compose down</code>.</p>
<p><a target="_blank" href="https://github.com/jideabdqudus/task-manager-api/tree/containerization-with-docker">⭐️ View Codebase</a></p>
<hr />
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Building a scalable REST API involves combining the right technologies with solid architectural principles. NestJS provides an excellent foundation with its modular structure and TypeScript support. Prisma simplifies database operations with its type-safe client. Swagger automates API documentation, making it easier for others to use your API. Finally, Docker ensures consistent deployment across environments.</p>
<p>This approach results in an API that is not only powerful and flexible but also maintainable and testable. As your application grows, the modular architecture allows for easy extension without compromising stability.</p>
<p>By following the patterns demonstrated in this project, you can build professional-grade APIs that scale with your business needs.</p>
<p>Don't hesitate to explore the repository further, experiment with the code, and refer to the official NestJS documentation for a comprehensive understanding of the framework's capabilities. Happy coding!</p>
<p><a target="_blank" href="https://github.com/jideabdqudus/task-manager-api">⭐️ View Final Code</a>  </p>
<p>👉🏾 <a target="_blank" href="https://www.abdulqudus.com/"><strong>Learn more about me</strong></a></p>
<p>👉🏾 <a target="_blank" href="https://www.linkedin.com/in/jideabdqudus/"><strong>Connect on LinkedIn</strong></a></p>
<p>👉🏾 <a target="_blank" href="https://abdulqudus.com/newsletter"><strong>Subscribe to my blog</strong></a></p>
]]></content:encoded></item><item><title><![CDATA[How to Build a Basic Chatbot Using TensorFlow and JavaScript]]></title><description><![CDATA[We all come across chatbots when visiting various sites, while some of them operate behind real-human interaction, others are powered by AI.
In this article, we'll walk through building a simple AI-powered chatbot using TensorFlow and JavaScript. The...]]></description><link>https://blog.abdulqudus.com/how-to-build-a-basic-chatbot-using-tensorflow-and-javascript</link><guid isPermaLink="true">https://blog.abdulqudus.com/how-to-build-a-basic-chatbot-using-tensorflow-and-javascript</guid><category><![CDATA[TensorFlow]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[chatbot]]></category><category><![CDATA[AI]]></category><category><![CDATA[Customer Experience]]></category><category><![CDATA[Startups]]></category><category><![CDATA[chatgpt]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Mon, 15 Jul 2024 11:19:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1720896945960/c5bf3e7b-d2d3-43e1-91c6-db86ae23d5c9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We all come across chatbots when visiting various sites, while some of them operate behind real-human interaction, others are powered by AI.</p>
<p>In this article, we'll walk through building a simple AI-powered chatbot using <a target="_blank" href="https://github.com/tensorflow/tfjs">TensorFlow</a> and JavaScript. The chatbot will recognize user commands and respond with predefined answers.</p>
<h3 id="heading-step-by-step-guide"><strong>Step-by-Step Guide</strong></h3>
<ol>
<li><p><strong>Setting Up Our Project</strong></p>
<p> First, we create a new directory for our project and initialize it with npm, ensure you have <a target="_blank" href="https://nodejs.org/en/learn/getting-started/how-to-install-nodejs">Node.js</a> installed on your system before starting this step.</p>
<pre><code class="lang-bash"> mkdir chatbot
 <span class="hljs-built_in">cd</span> chatbot
 npm init -y
</code></pre>
</li>
<li><p><strong>Install necessary packages</strong></p>
<p> We would be using the following npm packages for our simple project:</p>
<ul>
<li><p><code>@tensorflow/tfjs</code>: TensorFlow.js library for machine learning.</p>
</li>
<li><p><code>@tensorflow-models/universal-sentence-encoder</code>: Pre-trained Universal Sentence Encoder model for intent recognition.</p>
<pre><code class="lang-bash">  npm install @tensorflow/tfjs @tensorflow-models/universal-sentence-encoder
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Create intents</strong></p>
<p> Create a file named <code>intents.js</code> to store intents/commands. These are categories of user inputs that the chatbot will recognize (e.g., greetings, product inquiries, order status).</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// intents.js</span>
 <span class="hljs-keyword">const</span> intents = {
   <span class="hljs-attr">greeting</span>: [<span class="hljs-string">"hello"</span>, <span class="hljs-string">"hi"</span>, <span class="hljs-string">"hey"</span>, <span class="hljs-string">"good morning"</span>, <span class="hljs-string">"good evening"</span>, <span class="hljs-string">"howdy"</span>],
   <span class="hljs-attr">goodbye</span>: [<span class="hljs-string">"bye"</span>, <span class="hljs-string">"goodbye"</span>, <span class="hljs-string">"see you later"</span>, <span class="hljs-string">"farewell"</span>, <span class="hljs-string">"catch you later"</span>],
   <span class="hljs-attr">thanks</span>: [<span class="hljs-string">"thank you"</span>, <span class="hljs-string">"thanks"</span>, <span class="hljs-string">"much appreciated"</span>, <span class="hljs-string">"thank you very much"</span>],
   <span class="hljs-attr">product_inquiry</span>: [<span class="hljs-string">"tell me about your products"</span>, <span class="hljs-string">"what do you sell?"</span>, <span class="hljs-string">"product information"</span>, <span class="hljs-string">"what can I buy?"</span>, <span class="hljs-string">"show me your products"</span>],
   <span class="hljs-attr">order_status</span>: [<span class="hljs-string">"where is my order?"</span>, <span class="hljs-string">"order status"</span>, <span class="hljs-string">"track my order"</span>, <span class="hljs-string">"order tracking"</span>, <span class="hljs-string">"order update"</span>],
   <span class="hljs-attr">shipping_info</span>: [<span class="hljs-string">"shipping information"</span>, <span class="hljs-string">"how do you ship?"</span>, <span class="hljs-string">"shipping methods"</span>, <span class="hljs-string">"delivery options"</span>, <span class="hljs-string">"how long does shipping take?"</span>],
   <span class="hljs-attr">return_policy</span>: [<span class="hljs-string">"return policy"</span>, <span class="hljs-string">"how to return?"</span>, <span class="hljs-string">"return process"</span>, <span class="hljs-string">"can I return?"</span>, <span class="hljs-string">"returns"</span>],
   <span class="hljs-attr">payment_methods</span>: [<span class="hljs-string">"payment options"</span>, <span class="hljs-string">"how can I pay?"</span>, <span class="hljs-string">"payment methods"</span>, <span class="hljs-string">"available payments"</span>],
   <span class="hljs-attr">support_contact</span>: [<span class="hljs-string">"contact support"</span>, <span class="hljs-string">"how to contact support?"</span>, <span class="hljs-string">"customer support contact"</span>, <span class="hljs-string">"support info"</span>, <span class="hljs-string">"customer service contact"</span>],
   <span class="hljs-attr">business_hours</span>: [<span class="hljs-string">"business hours"</span>, <span class="hljs-string">"working hours"</span>, <span class="hljs-string">"when are you open?"</span>, <span class="hljs-string">"opening hours"</span>, <span class="hljs-string">"store hours"</span>]
 };

 <span class="hljs-built_in">module</span>.exports = { intents }
</code></pre>
</li>
<li><p><strong>Create responses</strong></p>
<p> Create another file named <code>responses.js</code> to store predefined responses. These are the predefined responses the chatbot will give based on the recognized intent.</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// responses.js</span>
 <span class="hljs-keyword">const</span> responses = {
   <span class="hljs-attr">greeting</span>: <span class="hljs-string">"Hello! How can I help you today?"</span>,
   <span class="hljs-attr">goodbye</span>: <span class="hljs-string">"Goodbye! Have a great day!"</span>,
   <span class="hljs-attr">thanks</span>: <span class="hljs-string">"You're welcome! If you have any other questions, feel free to ask."</span>,
   <span class="hljs-attr">product_inquiry</span>: <span class="hljs-string">"We offer a variety of products including electronics, books, clothing, and more. How can I assist you further?"</span>,
   <span class="hljs-attr">order_status</span>: <span class="hljs-string">"Please provide your order ID, and I will check the status for you."</span>,
   <span class="hljs-attr">shipping_info</span>: <span class="hljs-string">"We offer various shipping methods including standard, express, and next-day delivery. Shipping times depend on the method chosen and your location."</span>,
   <span class="hljs-attr">return_policy</span>: <span class="hljs-string">"Our return policy allows you to return products within 30 days of purchase. Please visit our returns page for detailed instructions."</span>,
   <span class="hljs-attr">payment_methods</span>: <span class="hljs-string">"We accept multiple payment methods including credit/debit cards, PayPal, and bank transfers. Please choose the method that suits you best at checkout."</span>,
   <span class="hljs-attr">support_contact</span>: <span class="hljs-string">"You can contact our support team via email at support@example.com or call us at 1-800-123-4567."</span>,
   <span class="hljs-attr">business_hours</span>: <span class="hljs-string">"Our business hours are Monday to Friday, 9 AM to 5 PM. We are closed on weekends and public holidays."</span>
 };

 <span class="hljs-built_in">module</span>.exports = { responses };
</code></pre>
</li>
<li><p><strong>Loading TensorFlow and the Sentence Encoder</strong></p>
<p> Create a main script file named <code>chatbot.js</code> and load the necessary libraries and models, we load the universal sentence encoder model asynchronously and start the chatbot once the model is loaded.</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// chatbot.js</span>
 <span class="hljs-keyword">const</span> tf = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@tensorflow/tfjs'</span>);
 <span class="hljs-keyword">const</span> use = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@tensorflow-models/universal-sentence-encoder'</span>);
 <span class="hljs-keyword">const</span> { intents } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./intents'</span>);
 <span class="hljs-keyword">const</span> { responses } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./responses'</span>);
 <span class="hljs-keyword">const</span> readline = <span class="hljs-built_in">require</span>(<span class="hljs-string">'readline'</span>);

 <span class="hljs-comment">// Load the Universal Sentence Encoder model</span>
 <span class="hljs-keyword">let</span> model;
 use.load().then(<span class="hljs-function">(<span class="hljs-params">loadedModel</span>) =&gt;</span> {
   model = loadedModel;
   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Model loaded"</span>);
   startChatbot();
 });
</code></pre>
</li>
<li><p><strong>Implementing Intent Recognition</strong></p>
<p> Add a function to recognize the intent of the user's input, we embed the user input into a high-dimensional vector using the universal encoder and then track the highest similarity score based on the intent.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">recognizeIntent</span>(<span class="hljs-params">userInput</span>) </span>{
   <span class="hljs-keyword">const</span> userInputEmb = <span class="hljs-keyword">await</span> model.embed([userInput]);
   <span class="hljs-keyword">let</span> maxScore = <span class="hljs-number">-1</span>;
   <span class="hljs-keyword">let</span> recognizedIntent = <span class="hljs-literal">null</span>;

   <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> [intent, examples] <span class="hljs-keyword">of</span> <span class="hljs-built_in">Object</span>.entries(intents)) {
     <span class="hljs-comment">// Embedding the example phrases for each intent &amp; Calculating similarity scores between the user input embedding and the example embeddings</span>
     <span class="hljs-keyword">const</span> examplesEmb = <span class="hljs-keyword">await</span> model.embed(examples);
     <span class="hljs-keyword">const</span> scores = <span class="hljs-keyword">await</span> tf.matMul(userInputEmb, examplesEmb, <span class="hljs-literal">false</span>, <span class="hljs-literal">true</span>).data();
     <span class="hljs-keyword">const</span> maxExampleScore = <span class="hljs-built_in">Math</span>.max(...scores);
     <span class="hljs-keyword">if</span> (maxExampleScore &gt; maxScore) {
       maxScore = maxExampleScore;
       recognizedIntent = intent;
     }
   }
   <span class="hljs-keyword">return</span> recognizedIntent;
 }
</code></pre>
</li>
<li><p><strong>Generating Responses</strong></p>
<p> Add a function to generate responses based on the recognized intent:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateResponse</span>(<span class="hljs-params">userInput</span>) </span>{
   <span class="hljs-keyword">const</span> intent = <span class="hljs-keyword">await</span> recognizeIntent(userInput);
   <span class="hljs-keyword">if</span> (intent &amp;&amp; responses[intent]) {
     <span class="hljs-keyword">return</span> responses[intent];
   } <span class="hljs-keyword">else</span> {
     <span class="hljs-keyword">return</span> <span class="hljs-string">"I'm sorry, I don't understand that. Can you please rephrase?"</span>;
   }
 }
</code></pre>
</li>
<li><p><strong>Implementing Chatbot Interaction</strong></p>
<p> Finally, implement the interaction loop with the chatbot by setting up the interface for reading user input from the command line, prompting the user for input and generating responses accordingly:</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">startChatbot</span>(<span class="hljs-params"></span>) </span>{
   <span class="hljs-keyword">const</span> rl = readline.createInterface({
     <span class="hljs-attr">input</span>: process.stdin,
     <span class="hljs-attr">output</span>: process.stdout
   });

   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Welcome to the customer service chatbot! Type 'quit' to exit."</span>);
   rl.prompt();

   rl.on(<span class="hljs-string">'line'</span>, <span class="hljs-keyword">async</span> (line) =&gt; {
     <span class="hljs-keyword">const</span> userInput = line.trim();
     <span class="hljs-keyword">if</span> (userInput.toLowerCase() === <span class="hljs-string">'quit'</span>) {
       <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Chatbot: Goodbye!"</span>);
       rl.close();
       <span class="hljs-keyword">return</span>;
     }

     <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> generateResponse(userInput);
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chatbot: <span class="hljs-subst">${response}</span>`</span>);
     rl.prompt();
   });
 }
</code></pre>
<p> Here is the completed code for <code>chatbot.js</code> :</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// chatbot.js</span>

 <span class="hljs-keyword">const</span> tf = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@tensorflow/tfjs'</span>);
 <span class="hljs-keyword">const</span> use = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@tensorflow-models/universal-sentence-encoder'</span>);
 <span class="hljs-keyword">const</span> { intents } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./intents'</span>);
 <span class="hljs-keyword">const</span> { responses } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./responses'</span>);
 <span class="hljs-keyword">const</span> readline = <span class="hljs-built_in">require</span>(<span class="hljs-string">'readline'</span>);

 <span class="hljs-comment">// Load the Universal Sentence Encoder model</span>
 <span class="hljs-keyword">let</span> model;
 use.load().then(<span class="hljs-function">(<span class="hljs-params">loadedModel</span>) =&gt;</span> {
   model = loadedModel;
   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Model loaded"</span>);
   startChatbot();
 });

 <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">recognizeIntent</span>(<span class="hljs-params">userInput</span>) </span>{
   <span class="hljs-keyword">const</span> userInputEmb = <span class="hljs-keyword">await</span> model.embed([userInput]);
   <span class="hljs-keyword">let</span> maxScore = <span class="hljs-number">-1</span>;
   <span class="hljs-keyword">let</span> recognizedIntent = <span class="hljs-literal">null</span>;

   <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> [intent, examples] <span class="hljs-keyword">of</span> <span class="hljs-built_in">Object</span>.entries(intents)) {
     <span class="hljs-keyword">const</span> examplesEmb = <span class="hljs-keyword">await</span> model.embed(examples);
     <span class="hljs-keyword">const</span> scores = <span class="hljs-keyword">await</span> tf.matMul(userInputEmb, examplesEmb, <span class="hljs-literal">false</span>, <span class="hljs-literal">true</span>).data();
     <span class="hljs-keyword">const</span> maxExampleScore = <span class="hljs-built_in">Math</span>.max(...scores);
     <span class="hljs-keyword">if</span> (maxExampleScore &gt; maxScore) {
       maxScore = maxExampleScore;
       recognizedIntent = intent;
     }
   }

   <span class="hljs-keyword">return</span> recognizedIntent;
 }

 <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateResponse</span>(<span class="hljs-params">userInput</span>) </span>{
   <span class="hljs-keyword">const</span> intent = <span class="hljs-keyword">await</span> recognizeIntent(userInput);
   <span class="hljs-keyword">if</span> (intent &amp;&amp; responses[intent]) {
     <span class="hljs-keyword">return</span> responses[intent];
   } <span class="hljs-keyword">else</span> {
     <span class="hljs-keyword">return</span> <span class="hljs-string">"I'm sorry, I don't understand that. Can you please rephrase?"</span>;
   }
 }

 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">startChatbot</span>(<span class="hljs-params"></span>) </span>{
   <span class="hljs-keyword">const</span> rl = readline.createInterface({
     <span class="hljs-attr">input</span>: process.stdin,
     <span class="hljs-attr">output</span>: process.stdout
   });

   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Welcome to the customer service chatbot! Type 'quit' to exit."</span>);
   rl.prompt();

   rl.on(<span class="hljs-string">'line'</span>, <span class="hljs-keyword">async</span> (line) =&gt; {
     <span class="hljs-keyword">const</span> userInput = line.trim();
     <span class="hljs-keyword">if</span> (userInput.toLowerCase() === <span class="hljs-string">'quit'</span>) {
       <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Chatbot: Goodbye!"</span>);
       rl.close();
       <span class="hljs-keyword">return</span>;
     }

     <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> generateResponse(userInput);
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chatbot: <span class="hljs-subst">${response}</span>`</span>);
     rl.prompt();
   });
 }
</code></pre>
</li>
<li><p><strong>To run the chatbot, execute the</strong><code>chatbot.js</code><strong>file:</strong></p>
<pre><code class="lang-bash"> node chatbot.js
</code></pre>
</li>
</ol>
<p>Voila! Our command output should have the chatbot running:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720896212004/236baea2-465f-483b-9cc8-4fd29e5878f1.png" alt="Comand Line Interface" class="image--center mx-auto" /></p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In this article, we've built a simple customer service chatbot using TensorFlow and JavaScript. The model used in this article is basic and doesn't have the ability to generate complex responses, in a real-world scenario an extensive dataset would be used to handle generating user queries.<br />Likewise, you can expand this project by integrating APIs using AXIOS, adding more intents and responses, or deploying it on a web platform.</p>
<p>Happy coding!</p>
<p>👉🏾 <a target="_blank" href="https://www.abdulqudus.com/">Learn more about me</a></p>
<p>👉🏾 <a target="_blank" href="https://www.linkedin.com/in/jideabdqudus/">Connect on LinkedIn</a></p>
<p>👉🏾 <a target="_blank" href="https://abdulqudus.com/newsletter">Subscribe to my blog</a></p>
]]></content:encoded></item><item><title><![CDATA[How to Run Localhost on Your Mobile Phone - A Step-by-Step Guide]]></title><description><![CDATA[Running localhost on your mobile phone can be a valuable tool for developers and tech enthusiasts alike. With localhost, you can test and run applications and websites on your mobile device, without the need for an external server. This of course is ...]]></description><link>https://blog.abdulqudus.com/how-to-run-localhost-on-your-mobile-phone-a-step-by-step-guide</link><guid isPermaLink="true">https://blog.abdulqudus.com/how-to-run-localhost-on-your-mobile-phone-a-step-by-step-guide</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Mobile Development]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Mon, 30 Jan 2023 09:00:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1675025242360/b4d1d6ad-2ca3-46a5-a210-a2d329032224.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Running <em>localhost</em> on your mobile phone can be a valuable tool for developers and tech enthusiasts alike. With <em>localhost</em>, you can test and run applications and websites on your mobile device, without the need for an external server. This of course is a substitute for running the dev-tools mobile emulator provided by chrome, firefox, or other browsers. As there’s nothing that will perfectly imitate an actual mobile browser better than the mobile device itself. This helps in catching mobile-specific bugs before they surface as a problem for users.</p>
<p>In this article, we will provide a step-by-step guide on how to run a <em>localhost</em> on your mobile phone, both for Android and iOS devices.</p>
<h3 id="heading-step-1-connect-your-devices-to-the-same-network">Step 1: Connect your devices to the same network</h3>
<p>This is probably the easiest step, all you have to do is make sure your computer is connected to the same wifi network as your mobile devices.</p>
<h3 id="heading-step-2-serve-your-app-to-localhost-and-get-the-port">Step 2: Serve your app to Localhost and get the Port</h3>
<p>On your computer/laptop, run your app as you usually do and get the localhost address, it is usually in the form <strong>http://localhost:&lt;port&gt;</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675021809833/c8d60dcc-8ff2-48f1-a894-bd22026b3a3d.png" alt="localhost sample image" class="image--center mx-auto" /></p>
<p>For instance, the port from the image above is <strong><em>9999.</em></strong></p>
<h3 id="heading-step-3-find-your-computers-local-ip-address">Step 3: Find your computer's Local IP Address</h3>
<p>There are different ways to find the IP address on your machine, to find out the IP address of your computer:</p>
<p><strong>For Mac:</strong></p>
<ol>
<li><p>Open System Preferences -&gt; Network</p>
</li>
<li><p>Next to the Status, you should see the IP address. It should write out - “WiFi is connected to WIFI_NAME and has the IP address YOUR_IP.” See how it looks in the screenshot below:</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675022384861/18ca4fac-c480-4476-b508-e3e6a4ea68ee.png" alt="Mac OS Network Tab" class="image--center mx-auto" /></p>
</li>
</ol>
<p>Take note of that address, also, bear in mind that It’s common for your Local IP Address to change automatically when your device or other devices connect/disconnect from the network.</p>
<p><strong>For Linux:</strong><br />Run in your terminal <code>hostname -I</code>. Or, run <code>ifconfig | grep "inet " | grep -v 127.0.0.1</code></p>
<p><strong>For Windows:</strong></p>
<ol>
<li><p>Select Start &gt; Settings &gt; Network &amp; internet &gt; Wi-Fi and then select the Wi-Fi network you’re connected to.</p>
</li>
<li><p>Under Properties, look for your IP address listed next to IPv4 address.</p>
</li>
</ol>
<p>Great, now that we got our computer’s local IP address, we need to run our app.</p>
<h3 id="heading-step-4-view-the-app-on-your-phone">Step 4: View the app on your phone</h3>
<p>On your mobile device’s browser, you can now navigate to <code>http://&lt;Local IP Address&gt;:&lt;port number&gt;</code>. For example, If your application is running on <a target="_blank" href="http://localhost:8080"><code>localhost:9999</code></a> and your IP address is like <code>172.32.44.160</code>, then on mobile, we navigate to <code>172.32.44.160:9999</code></p>
<p>In conclusion, running localhost on your mobile phone is a useful tool for developers and tech enthusiasts. By following these six simple steps, you can easily set up localhost on your mobile device, and test and run applications and websites right on your phone.</p>
]]></content:encoded></item><item><title><![CDATA[Downloading base64 PDF in Javascript / React]]></title><description><![CDATA[I ran into this problem while trying to download a PDF from an API response and figured I'd create a post that solves this for myself and other Front-End developers. 
The Problem
Files could be saved in the backend as base64 encoded strings, this is ...]]></description><link>https://blog.abdulqudus.com/downloading-base64-pdf-in-javascript-react</link><guid isPermaLink="true">https://blog.abdulqudus.com/downloading-base64-pdf-in-javascript-react</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Mon, 19 Sep 2022 08:00:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1663456876578/zbRR5n5VV.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I ran into this problem while trying to download a PDF from an API response and figured I'd create a post that solves this for myself and other Front-End developers. </p>
<p><strong>The Problem</strong></p>
<p>Files could be saved in the backend as base64 encoded strings, this is to ensure that the data remains intact without modification during transport. <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Base64">Base64</a> is commonly used in a number of applications. So how do we download a file sent from the Backend as base 64 as it's just a string usually in this format <em>(data:application/pdf;base64,[base64]..)</em></p>
<p><strong>The Solution</strong></p>
<p>In a situation whereby the user isn't making any request to an endpoint, the base64 file could be downloaded just like so (using the typical HTML anchor tag): </p>
<p><code>&lt;a href="data:application/pdf;base64,[base64]" download="file_name.pdf"&gt;</code></p>
<p>Otherwise, In a situation whereby the user has to fetch data from an endpoint and pass data <code>onClick</code>, this can be done simply by creating a function that accepts the <em>base64 encoded string</em>and creating the <code>anchor</code> tag element with the file link as an <code>href</code> attribute, adds a <code>download</code> attribute and clicks on the created <code>anchor</code> element.</p>
<pre><code>let pdf <span class="hljs-operator">=</span> {
  file: <span class="hljs-string">"data:application/pdf;base64,[base64]......"</span>,
  file_name: <span class="hljs-string">"Purchase Invoice"</span>
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">downloadPDF</span>(<span class="hljs-params">pdf</span>) </span>{
    const pdfLink <span class="hljs-operator">=</span> `${pdf.file}`;
    const anchorElement <span class="hljs-operator">=</span> document.createElement(<span class="hljs-string">'a'</span>);
    const fileName <span class="hljs-operator">=</span> `${pdf.file_name}.pdf`;
    anchorElement.href <span class="hljs-operator">=</span> pdfLink;
    anchorElement.download <span class="hljs-operator">=</span> fileName;
    anchorElement.click();
}
</code></pre><p>I hope I'm able to help with this implementation, let me know in the comments. </p>
<p>Read more articles from me: <a target="_blank" href="https://blog.abdulqudus.com/">blog.abdulqudus.com</a></p>
]]></content:encoded></item><item><title><![CDATA[How to use Debounce in React (Lodash)]]></title><description><![CDATA[As a user typing in an input field or performing a particular action - an efficient method of making requests from the API is to allow for user action to be completed before interacting with the API. This prevents your UI code from needing to process...]]></description><link>https://blog.abdulqudus.com/how-to-use-debounce-in-react-lodash</link><guid isPermaLink="true">https://blog.abdulqudus.com/how-to-use-debounce-in-react-lodash</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Fri, 20 May 2022 08:58:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1652131702200/9Swg2fqzX.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a user typing in an <code>input</code> field or performing a particular action - an efficient method of making requests from the <em>API</em> is to allow for user action to be completed before interacting with the <em>API</em>. This prevents your UI code from needing to process every event and also drastically reduces the number of calls sent to your server.</p>
<p>One of the solutions to this is to use debounce/throttle, and a <strong>Lodash</strong> provides us with the <code>debounce</code> function. <strong>Lodash’s</strong> debounce function delays invoking a function passed into it; It can help performance in some situations.</p>
<p>In this article, we would be taking a look at the right implementation of <code>debounce</code> in a <strong>React App.</strong></p>
<h2 id="heading-our-app">Our App</h2>
<p>Let's take this sample React Application that contains a search input field and each time the user types a request is made that loads the data into the UI. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [users, setUsers] = React.useState([]);

  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">search</span>(<span class="hljs-params">value</span>) </span>{
    <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(
      <span class="hljs-comment">// Fake API </span>
      <span class="hljs-string">`https://api.github.com/?search=<span class="hljs-subst">${value}</span>`</span>
    );
    <span class="hljs-keyword">const</span> body = <span class="hljs-keyword">await</span> res.json();
    <span class="hljs-keyword">return</span> body.results.map(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> result.name);
  }

  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleChange</span>(<span class="hljs-params">event</span>) </span>{
    setUsers(<span class="hljs-keyword">await</span> search(event.target.value));
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"search"</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your search"</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {users.map((user) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{user.id}</span>&gt;</span>{user.firstname}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>With the above code, the search request is made every time the user makes a keystroke in the input element. Ideally, we want the search request to be made only when the user has stopped typing. We can use the <code>debounce</code> function from <strong>Lodash</strong> to do this. The <code>debounce</code> function delays the processing of the key-up event until the user has stopped typing for a predetermined amount of time. </p>
<h2 id="heading-implementing-debounce-in-react">Implementing Debounce in React</h2>
<pre><code class="lang-jsx">npm install lodash
</code></pre>
<p>Create a <code>debounce</code> function, and call it inside of the <code>handlechange</code>, a timer is set to the debounced function that determines the intervals between each call.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { debounce } <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;

<span class="hljs-keyword">const</span> handleSearchDebounce = debounce(<span class="hljs-keyword">async</span> (value) =&gt; {
    setUser(<span class="hljs-keyword">await</span> search(value));
}, <span class="hljs-number">300</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleChange</span>(<span class="hljs-params">event</span>) </span>{
  handleSearchDebounce(event.target.value);
}
</code></pre>
<h4 id="heading-approach-2">Approach 2</h4>
<p>With the first method, a new version of the debounced method is created on every render. We can use the <code>useRef</code> hook to store the debounced function across renders instead:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { debounce } <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;

<span class="hljs-keyword">const</span> handleSearchDebounce = React.useRef(
  debounce(<span class="hljs-keyword">async</span> (value) =&gt; {
    setUsers(<span class="hljs-keyword">await</span> search(value));
  }, <span class="hljs-number">300</span>)
).current;

<span class="hljs-comment">/* We can use the `useEffect` hook to cancel the debounced function 
so whenever the component unmounts the search stops running, and
the function gets canceled */</span>
React.useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    handleSearchDebounce.cancel();
  };
}, [handleSearchDebounce]);
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, I showed you how to implement a <code>debounce</code> function in React using <strong>Lodash</strong>. However, you don’t need to use <strong>Lodash's</strong> implementation of <code>debounce</code> in your projects if you don’t want to. You can decide to <a target="_blank" href="https://www.freecodecamp.org/news/javascript-debounce-example">write your own</a> debounce function and some other libraries offer this same debounce function. </p>
<p>👉🏾 <a target="_blank" href="https://www.abdulqudus.com/">Learn more about me</a></p>
<p>👉🏾 <a target="_blank" href="https://www.linkedin.com/in/jideabdqudus/">Connect on LinkedIn</a></p>
<p>👉🏾 <a target="_blank" href="blog.abdulqudus.com">Subscribe to my blog, let's feast</a></p>
]]></content:encoded></item><item><title><![CDATA[Image Optimization with NextJS]]></title><description><![CDATA[NextJS is fast becoming my favorite frontend framework because of the endless advantages over a basic React application, one of those said benefits would be the Built-in Image Component.
In this article, we would take a look at the Image component fr...]]></description><link>https://blog.abdulqudus.com/image-optimization-with-nextjs</link><guid isPermaLink="true">https://blog.abdulqudus.com/image-optimization-with-nextjs</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[javascript framework]]></category><category><![CDATA[optimization]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Thu, 05 May 2022 23:50:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1651572688783/gdafKEjJh.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>NextJS</strong> is fast becoming my favorite frontend framework because of the endless advantages over a basic React application, one of those said benefits would be the Built-in Image Component.</p>
<p>In this article, we would take a look at the Image component from <a target="_blank" href="https://nextjs.org/">NextJS</a> and learn how to use it to optimize an image in our web app.</p>
<p>By the end of this article, you should understand the following concepts:</p>
<ul>
<li><p>Image Optimization</p>
</li>
<li><p>Using <code>next/image</code></p>
</li>
<li><p>Image Props</p>
</li>
<li><p>Configuring <code>next.config.js</code></p>
</li>
<li><p>Usage of the native <code>&lt; img &gt;</code> tag in NextJS</p>
</li>
</ul>
<h2 id="heading-image-optimization">Image Optimization</h2>
<p>Ordinarily, if you were going to make use of an image in your website/app you would do this ( assuming the image is in the same directory as the webpage it is accessing ):</p>
<pre><code class="lang-javascript">&lt;img src=<span class="hljs-string">"./apple.jpg"</span>&gt;
</code></pre>
<p>You can go further by adding an alternative text (for screen readers or when the image cannot be loaded) by doing this:</p>
<pre><code class="lang-javascript">&lt;img src=<span class="hljs-string">"./apple.jpg"</span> alt=<span class="hljs-string">"Image of an apple"</span>/&gt;
</code></pre>
<p>However, this format doesn't solve image optimization aspects like image size, web formats, and responsiveness with this single usage.</p>
<p><strong>NextJS</strong> offers automatic image optimization which solves all of the above as well as common tasks like internalization and routing.</p>
<p>The golden rule for any performance optimization simply put is giving users what they want in the shortest possible time or providing a fall-back if need be.</p>
<p>Hence <strong>NextJS</strong> provides us with a built-in image optimization API, <code>next/image</code>, a canonical form for native automatic image optimization.</p>
<h2 id="heading-using-nextimage">Using <code>next/image</code></h2>
<p>The Image component in <strong>NextJS</strong> is quite similar to the native html <code>&lt;img&gt;</code>, it's an extension of this element and can be used by importing it from <code>next/image</code> and using it like you'd use a component with props.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">'next/image'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SampleImage</span>(<span class="hljs-params">{source}</span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Image</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{source}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">'Image alt text'</span>/&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}
</code></pre>
<p>The Image tag has a couple of props available to it for use asides the src and alt prop, we'd take a look at some of them</p>
<ul>
<li><h3 id="heading-width-and-height-prop"><code>width</code> and <code>height</code> prop</h3>
</li>
</ul>
<p>The width and height of the image is in <em>pixels</em> , when adding the width and height be sure to add the correct dimension. If a different aspect ratio is added, the image would adjust accordingly. For example if the width and height of a (1400 x 700) image gets changed to (400 x400) as shown below, it could result in a skewed image.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">'next/image'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SampleImage</span>(<span class="hljs-params">{source}</span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Image</span> 
               <span class="hljs-attr">src</span>=<span class="hljs-string">{source}</span> 
               <span class="hljs-attr">alt</span>=<span class="hljs-string">'Image alt text'</span>
               <span class="hljs-attr">height</span>=<span class="hljs-string">{400}</span>
               <span class="hljs-attr">width</span>=<span class="hljs-string">{400}</span>
             /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}
</code></pre>
<ul>
<li><h3 id="heading-layout-prop"><code>layout</code> prop</h3>
</li>
</ul>
<p>There may be times you do not know the width and height of an image, but still want it to fill the entire space while keeping its aspect ratio. In this situation, you can leave out the width and height prop on the Image component. Instead, add a prop of <code>layout="fill"</code>. This will stretch the image to the width and the height of the parent element. When using the <code>layout="fill"</code> prop, it is often best to pair it with <code>objectFit="cover"</code>. This will allow the image to maintain its aspect ratio while filling the element’s entire content box. To achieve this, wrap the Image component as a child of a <code>&lt;div&gt;</code> element. Then add a width and height to the parent <code>&lt;div&gt;</code> element, along with giving it a <code>position="relative"</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">'next/image'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SampleImage</span>(<span class="hljs-params">{source}</span>) </span>{
    <span class="hljs-keyword">const</span> myStyle = {
       <span class="hljs-attr">height</span>: <span class="hljs-string">'400px'</span>,
       <span class="hljs-attr">width</span>: <span class="hljs-string">'400px'</span>,
       <span class="hljs-attr">position</span>: <span class="hljs-string">'relative'</span> 
   }
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{myStyle}</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Image</span> 
               <span class="hljs-attr">src</span>=<span class="hljs-string">{source}</span> 
               <span class="hljs-attr">alt</span>=<span class="hljs-string">'Image alt text'</span>
               <span class="hljs-attr">layout</span>=<span class="hljs-string">'fill'</span>
               <span class="hljs-attr">objectFit</span>=<span class="hljs-string">'cover'</span>
             /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}
</code></pre>
<p>This way, we can see that the image is taking up the 400-pixel square that we wanted, but the aspect ratio of the image is still in place. The parts of the image that do not fit within the parent element are clipped.</p>
<p>Other <code>layout</code> values are intrinsic, fixed, and responsive.</p>
<ul>
<li><h3 id="heading-loader-prop"><code>loader</code> prop</h3>
</li>
</ul>
<p>A loader is a function returning a URL string for the image, given the following parameters (<code>src</code>, <code>width</code>, <code>quality</code>). Setting the loader as a prop on the Image component overrides the default loader defined in the images section of <code>next.config.js</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">'next/image'</span>

<span class="hljs-keyword">const</span> sampleLoader = <span class="hljs-function">(<span class="hljs-params">{ src, width, quality }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-string">`https://example.com/<span class="hljs-subst">${src}</span>?w=<span class="hljs-subst">${width}</span>&amp;q=<span class="hljs-subst">${quality || <span class="hljs-number">75</span>}</span>`</span>
}

<span class="hljs-keyword">const</span> MyImage = <span class="hljs-function">(<span class="hljs-params">props</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Image</span>
      <span class="hljs-attr">loader</span>=<span class="hljs-string">{sampleLoader}</span>
      <span class="hljs-attr">src</span>=<span class="hljs-string">"me.png"</span>
      <span class="hljs-attr">alt</span>=<span class="hljs-string">"My Picture"</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">{500}</span>
      <span class="hljs-attr">height</span>=<span class="hljs-string">{500}</span>
    /&gt;</span></span>
  )
}
</code></pre>
<ul>
<li><h3 id="heading-sizes-prop"><code>sizes</code> prop</h3>
</li>
</ul>
<p>You can specify a list of image widths using the <code>images.imageSizes</code> property in your <code>next.config.js</code> file. These widths are concatenated with the array of device sizes to form the full array of sizes used to generate image srcsets.</p>
<pre><code class="lang-jsx"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">images</span>: {
    <span class="hljs-attr">imageSizes</span>: [<span class="hljs-number">16</span>, <span class="hljs-number">32</span>, <span class="hljs-number">48</span>, <span class="hljs-number">64</span>, <span class="hljs-number">96</span>, <span class="hljs-number">128</span>, <span class="hljs-number">256</span>, <span class="hljs-number">384</span>],
  },
}
</code></pre>
<p>Or by defining it in your component like,</p>
<pre><code class="lang-jsx">&lt;Image
    src={src}
    alt=<span class="hljs-string">"image-alt-text"</span>
    sizes=<span class="hljs-string">"320 640 700"</span>
    layout=<span class="hljs-string">"responsive"</span>
/&gt;
</code></pre>
<p>Keep in mind that it is recommended to define <code>sizes</code> only when using a <code>responsive</code> or <code>fill</code> layout.</p>
<ul>
<li><h3 id="heading-quality-prop"><code>quality</code> prop</h3>
</li>
</ul>
<p>The quality of the optimized image, is an integer between <code>1</code> and <code>100</code> where <code>100</code> is the best quality. Defaults to <code>75</code>.</p>
<pre><code class="lang-jsx">&lt;Image
    src={src}
    alt=<span class="hljs-string">"image-alt-text"</span>
    quality={<span class="hljs-number">100</span>}
    layout=<span class="hljs-string">"fill"</span>
/&gt;
</code></pre>
<ul>
<li><h3 id="heading-priority-prop"><code>priority</code> prop</h3>
</li>
</ul>
<p>By default, images are not prioritized (because they are lazy-loaded), meaning priority defaults to <code>false</code>. When <code>true</code>, the image is considered high-priority and preloaded. You should use the <code>priority</code> property on any image detected as the Largest Contentful Paint (LCP) element. Should only be used when the image is visible above the fold. Defaults to <code>false</code>.</p>
<pre><code class="lang-jsx">&lt;Image
    src={src}
    alt=<span class="hljs-string">"image-alt-text"</span>
    width={<span class="hljs-number">500</span>}
    height={<span class="hljs-number">300</span>}
    priority
/&gt;
</code></pre>
<ul>
<li><h3 id="heading-placeholder-prop"><code>placeholder</code> prop</h3>
</li>
</ul>
<p>This <code>placeholder</code> property is used as a fallback image when an image is loading. Its possible values are <code>blur</code> or <code>empty</code>. When <code>empty</code>, there will be no placeholder while the image is loading, only empty space. When <code>blur</code>, the <code>blurDataURL</code> property will be used as the placeholder. If <code>src</code> is an object from a static import and the imported image is .jpg, .png, .webp, or .avif, then blurDataURL will be automatically populated.</p>
<pre><code class="lang-jsx">&lt;Image
    src={src}
    alt=<span class="hljs-string">"image-alt-text"</span>
    width={<span class="hljs-number">500</span>}
    height={<span class="hljs-number">300</span>}
    placeholder=<span class="hljs-string">"blur"</span>
/&gt;
</code></pre>
<ul>
<li><h3 id="heading-blurdataurl-prop"><code>blurDataURL</code> prop</h3>
</li>
</ul>
<p>The <code>blurDataURL</code> prop is a placeholder image that loads before the src image successfully loads and must be a base64-encoded data URL image that is effectual only when used in combination with <code>placeholder=“blur”</code>.</p>
<pre><code class="lang-jsx">&lt;Image
  src={src}
  alt=<span class="hljs-string">"image-alt-text"</span>
  width={<span class="hljs-number">600</span>}
  height={<span class="hljs-number">450</span>}
  placeholder=<span class="hljs-string">"blur"</span>
  blurDataURL=”data:image/png;base64,[IMAGE_CODE_FROM_PNG_PIXEL]”
/&gt;
</code></pre>
<ul>
<li><h3 id="heading-objectfit-prop"><code>objectFit</code> prop</h3>
</li>
</ul>
<p>The <code>objectFit</code> prop defines how the image will fit into the container of it's parent, quite similar to the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit">object-fit CSS property</a>. It is used with <code>layout=fill</code> or an image with a set <code>width</code> and <code>height</code>.</p>
<pre><code class="lang-jsx">&lt;Image 
    src={src}
    alt=<span class="hljs-string">"image-alt-text"</span>
    layout=<span class="hljs-string">"fill"</span>
    objectFit=<span class="hljs-string">"contain"</span>
/&gt;
</code></pre>
<p>It has a possible value of: <code>contain</code>, <code>cover</code>, <code>fill</code>, <code>none</code>, and <code>scale-down</code>.</p>
<ul>
<li><h3 id="heading-unoptimized-prop"><code>unoptimized</code> prop</h3>
</li>
</ul>
<p>When <code>true</code>, the source image will be served as-is instead of changing quality, size, or format. Defaults to <code>false</code>.</p>
<pre><code class="lang-jsx">&lt;Image
    src={src}
    alt=<span class="hljs-string">"image-alt-text"</span>
    width={<span class="hljs-number">700</span>}
    height={<span class="hljs-number">450</span>}
    unoptimized
/&gt;
</code></pre>
<h2 id="heading-configuring-nextconfigjs">Configuring <code>next.config.js</code></h2>
<p>You can configure your <strong>NextJS</strong> image through the <code>next.config.js</code> file</p>
<ul>
<li><h3 id="heading-domains"><code>domains</code></h3>
</li>
</ul>
<p>When using an external URL to load images, you must add it to <code>domains</code> in <code>next.config.js</code></p>
<pre><code class="lang-jsx"><span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">images</span>: {
        <span class="hljs-attr">domains</span>: [<span class="hljs-string">'example.com'</span>],
    }
}
</code></pre>
<ul>
<li><h3 id="heading-loader"><code>loader</code></h3>
</li>
</ul>
<p>By default, <strong>NextJS</strong> handles image optimization but you can hand that responsibility over to a cloud provider such as <a target="_blank" href="https://cloudinary.com/">Cloudinary</a> or <a target="_blank" href="https://imgix.com/">imgix</a> that is more dedicated to images than just general optimization.</p>
<pre><code class="lang-jsx"><span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">images</span>: {
        <span class="hljs-attr">loader</span>: <span class="hljs-string">'cloudinary'</span>,
        <span class="hljs-attr">path</span>: <span class="hljs-string">'https://your-site.com/assets/images/'</span>
    }
}
</code></pre>
<p>Keep in mind that when <code>loader</code> is set to an external image service, the <code>domains</code> config is ignored.</p>
<p>For more advanced cases of props in <strong>NextJS</strong>, there are other props that you can add to the Image component as well as configurations. Check out the full <a target="_blank" href="https://nextjs.org/docs/api-reference/next/image">documentation here</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Image optimization in Next.js improves the user and developer experience but just like every other thing in programming, the Image component has some limitations one of which is its inability to adjust <em>CSS</em> directly. Unlike the native <code>&lt;img&gt;</code> element whereby you can pass a <code>style</code> prop to override its <em>CSS</em>. The <strong>NextJS</strong> image component doesn't support the <code>style</code> property at all. Hence to style the source image, name it with a <code>className</code> then target it with your CSS.</p>
<pre><code class="lang-jsx">&lt;Image
    src={src}
    alt=<span class="hljs-string">"image-alt-text"</span>
    width={<span class="hljs-number">700</span>}
    height={<span class="hljs-number">450</span>}
    className=<span class="hljs-string">"myImage"</span>
/&gt;
</code></pre>
<p>P.S: Next.js forces using their</p>
<p><img src="undefined" alt /></p>
<p>component instead of the native <code>&lt;img&gt;</code> tag by including the corresponding linter check to the app build process. So if you're going to make use of the <code>&lt;img&gt;</code> tag in a NextJS application you'd add the following to disable the check</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// eslint-disable-next-line @next/next/no-img-element</span>
 &lt;img
     src={src}
     alt=<span class="hljs-string">'myImg'</span>
     className=<span class="hljs-string">'myImage'</span>
 /&gt;
</code></pre>
<p>Or by adding <code>"@next/next/no-img-element": "off"</code> in the <code>.eslintrcconfig</code> file.</p>
<blockquote>
<p>I hope you enjoyed reading this as much as I enjoyed writing it and would be building your NextJS app as soon as possible.</p>
</blockquote>
<p>Resources used:</p>
<ul>
<li><p><a target="_blank" href="https://nextjs.org/docs/api-reference/next/image">NextJS Doc</a></p>
</li>
<li><p><a target="_blank" href="https://blog.logrocket.com/next-js-automatic-image-optimization-next-image/">Log Rocket</a></p>
</li>
<li><p><a target="_blank" href="https://uploadcare.com/blog/next-js-image-optimization/">UploadCare</a></p>
</li>
<li><p><a target="_blank" href="https://levelup.gitconnected.com/optimize-images-from-an-external-website-with-the-image-component-from-next-js-aa104a1f78e0">Level Up Coding</a></p>
</li>
</ul>
<p>👉🏾 <a target="_blank" href="https://www.abdulqudus.com/">Learn more about me</a></p>
<p>👉🏾 <a target="_blank" href="https://www.linkedin.com/in/jideabdqudus/">Connect on LinkedIn</a></p>
<p>👉🏾 <a target="_blank" href="https://blog.abdulqudus.com/">Subscribe to my blog, let's feast</a></p>
]]></content:encoded></item><item><title><![CDATA[Using Vuex in a Nuxt application.]]></title><description><![CDATA[In this article, I would show you how to get started with Vuex in a Nuxt project and build a small counter application in the easiest way possible. I will not be going into much detail on how Vuex works as the major focus would be its implementation ...]]></description><link>https://blog.abdulqudus.com/using-vuex-in-a-nuxt-application</link><guid isPermaLink="true">https://blog.abdulqudus.com/using-vuex-in-a-nuxt-application</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[Nuxt]]></category><category><![CDATA[Redux]]></category><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Fri, 12 Nov 2021 10:48:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1636713950698/5PcWSP61d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I would show you how to get started with <strong>Vuex</strong> in a Nuxt project and build a small counter application in the easiest way possible. I will not be going into much detail on how <strong>Vuex</strong> works as the major focus would be its implementation in <strong>Nuxt</strong>. </p>
<p><em>Side-note: I started writing Vue a month ago and the experience has been fantastic, do check it out as it has a faster learning curve (if you are fairly good in react)</em></p>
<h3 id="what-is-vuex">What is Vuex?</h3>
<p><strong>Vuex</strong> is a state management tool for <strong>Vue</strong> <em>(as Redux is for React)</em>. It holds a global state that can be accessed and modified within your application. It enables you to work with state in a controlled way and to use actions, getters, and mutations to handle changes to the state.
Vuex, just like every global state management system should only be used when you need some global state or a centralized place to hold data</p>
<h3 id="what-is-nuxt">What is Nuxt?</h3>
<p><strong>Nuxt.js</strong> <em>(as Next.js is for React)</em> is a frontend framework built upon <strong>Vue.js</strong> that offers great development features such as server-side rendering, automatically generated routes, improved meta tags managing, and SEO improvement.</p>
<h3 id="setting-up-vuex-with-nuxt">Setting up Vuex with Nuxt</h3>
<p>The good news, Nuxt comes with Vuex by default! When scaffolding a new project you might have noticed an empty folder called <code>store</code>.  This is where all of the logic for our Vuex takes place, it is disabled by default but will be activated as soon as we create a <code>.js</code> file in there.</p>
<ul>
<li>Create <code>index.js</code>
Inside of the Store folder create an <code>index.js</code> file, if you don't have a Store folder you can go ahead and create this as well. The <code>index.js</code> would be the root module and contain the four building blocks of a Vuex module:</li>
</ul>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> state = () =&gt; {}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> mutations = {}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> actions = {}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getters = {}
</code></pre><ul>
<li>Update the state in the <code>index.js</code> file
For the purpose of this article, we are building a small counter app, and we'd initiate our counter state in our <code>index.js</code> file. </li>
</ul>
<pre><code><span class="hljs-comment">//updated code</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> state = () =&gt; ({
  counter: <span class="hljs-number">0</span>
})
</code></pre><ul>
<li>Update the mutation inside <code>index.js</code> file<pre><code><span class="hljs-comment">//updated code</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> mutations = {
<span class="hljs-attr">increment</span>: <span class="hljs-function"><span class="hljs-params">state</span> =&gt;</span> (
  state.counter++
 )
}
</code></pre></li>
</ul>
<p>Our <code>index.js</code> file should look like this now</p>
<pre><code><span class="hljs-keyword">export</span> const state = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ({
  counter: <span class="hljs-number">0</span>
})
<span class="hljs-keyword">export</span> const mutations = {
  increment: state =&gt; (
    state.counter++
  )
}
<span class="hljs-keyword">export</span> const actions = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {}
<span class="hljs-keyword">export</span> const modules = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {}
</code></pre><p>Don't worry about the actions and modules as we wouldn't be going in-depth on Vuex.</p>
<ul>
<li><p>Now create a button and dispatch the action inside of the pages folder. </p>
</li>
<li><p>Inside of the <code>pages/index.vue</code> file</p>
</li>
</ul>
<pre><code>// pages/index.vue
<span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    Counter: {{ this.$store.state.counter }}
    <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"add_one"</span>&gt;</span>Add<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">methods</span>: {
    add_one() {
      <span class="hljs-built_in">this</span>.$store.commit(<span class="hljs-string">"increment"</span>);
    },
  },
};
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre><p>What the code above does, we get the current value of the counter state from the store, then on button click, we commit(dispatch) the increment action that changes the value of the state.</p>
<p>Our final result should be this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636712975069/ODF71kuHR.gif" alt="ezgif.com-gif-maker.gif" /></p>
<h3 id="conclusion">Conclusion</h3>
<p>Working with Vuex in a Nuxt application is simple and easy to get started with. It provides module creation based on folder and file structure under the store folder. The context helper property <code>$store</code> is useful when accessing the store from a component. Other than that there are no Nuxt specific ways of working with Vuex compared to a plain Vue application. Nuxt lets you quickly get up and running so you can focus on implementation rather than configuration.</p>
<p>Thanks for reading!</p>
<p>Resources used: </p>
<ul>
<li><a target="_blank" href="https://langvad.dev/blog/working-with-nuxt-and-vuex/">Langvad</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=R_ShKJ7PJ3U">Nakita Kejser</a></li>
</ul>
<p>👉🏾  <a target="_blank" href="https://abdulqudus.com">Learn more about me</a>  👉🏾  <a target="_blank" href="https://www.linkedin.com/in/jideabdqudus/">Connect on LinkedIn</a>  👉🏾  <a target="_blank" href="https://blog.abdulqudus.com">Subscribe to my blog, let's feast</a>   </p>
<p><code>QOTD: It always seems impossible until it's done</code></p>
]]></content:encoded></item><item><title><![CDATA[Code Splitting in React (An Overview)]]></title><description><![CDATA[Have you seen a message like this when you generate  lighthouse report  for an application?

This is caused by sending large JavaScript payloads which in turn impacts the speed of your site significantly. Instead of shipping all the JavaScript to you...]]></description><link>https://blog.abdulqudus.com/code-splitting-in-react</link><guid isPermaLink="true">https://blog.abdulqudus.com/code-splitting-in-react</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[best practices]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Fri, 05 Nov 2021 10:03:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1636106501920/7qbFZVdYP.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you seen a message like this when you generate  <a target="_blank" href="https://developers.google.com/web/tools/lighthouse">lighthouse report</a>  for an application?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636102820284/zqASHhlws.png" alt="p0Ahh3pzXog3jPdDp6La.png" /></p>
<p>This is caused by sending large <em>JavaScript</em> payloads which in turn impacts the speed of your site significantly. Instead of shipping all the <em>JavaScript</em> to your user as soon as the first page of your application is loaded, split your bundle into multiple pieces and only send what's necessary at the very beginning.</p>
<h3 id="what-is-code-splitting">What is Code Splitting?</h3>
<p>Many <em>JavaScript</em> frameworks bundle all dependencies into one large file. This makes it easy to add your <em>JavaScript</em> to an <em>HTML</em> page. The bundle requires only one link tag, and there are fewer calls needed to set up the page since all the <em>JavaScript</em> is in one place. In theory, bundling <em>JavaScript</em> in this way should speed up page loads and lower the amount of traffic that page needs to handle.</p>
<p><strong>Code splitting</strong> is a common practice in large <strong>React</strong> applications, and the increase in speed it provides can determine whether a user continues using a web application or leaves. Many studies have shown that pages have less than three seconds to make an impression with users, so shaving off even fractions of a second could be significant. Therefore, aiming for three seconds or less of load time is ideal.</p>
<p>Popular module bundlers like <a target="_blank" href="https://webpack.js.org/guides/code-splitting/">webpack</a>, allow you to split your bundles using dynamic imports. For example;</p>
<pre><code><span class="hljs-comment">// math.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subtract</span>(<span class="hljs-params">a, b</span>) </span>{
  <span class="hljs-keyword">return</span> a - b;
}
</code></pre><h4 id="without-code-splitting">Without Code Splitting</h4>
<pre><code><span class="hljs-comment">//index.js</span>
<span class="hljs-keyword">import</span> { subtract } <span class="hljs-keyword">from</span> <span class="hljs-string">'./math.js'</span>;

<span class="hljs-built_in">console</span>.log(subtract(<span class="hljs-number">26</span>, <span class="hljs-number">16</span>)); <span class="hljs-comment">// 10</span>
</code></pre><h4 id="with-code-splitting">With Code Splitting</h4>
<pre><code><span class="hljs-keyword">import</span>(<span class="hljs-string">"./math"</span>).then(<span class="hljs-function"><span class="hljs-params">math</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(math.subtract(<span class="hljs-number">26</span>, <span class="hljs-number">16</span>)); <span class="hljs-comment">//10</span>
});
</code></pre><p>When Webpack comes across this syntax, it automatically starts code-splitting your app. If you’re using <em>Create React App</em>, this is already configured for you and you can start using it immediately. It’s also supported out of the box in  <a target="_blank" href="https://nextjs.org/docs/advanced-features/dynamic-import">Next.js</a>.</p>
<h3 id="how-does-code-splitting-work-in-react">How does Code Splitting work In React</h3>
<p>There are several ways to implement code splitting in <em>React</em>. Different bundlers work in different ways, but React has multiple methods to customize bundling regardless of the bundler used.</p>
<h4 id="using-dynamic-imports">Using Dynamic Imports</h4>
<p>The <strong>Dynamic import</strong> syntax works for both static site generation and server-side rendering. Dynamic imports use the then function to import only the code that is needed. Any call to the imported code must be inside that function (as seen above and below).</p>
<pre><code><span class="hljs-keyword">import</span>(<span class="hljs-string">"./math"</span>).then(<span class="hljs-function"><span class="hljs-params">math</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(math.subtract(<span class="hljs-number">26</span>, <span class="hljs-number">16</span>)); <span class="hljs-comment">//10</span>
});
</code></pre><h4 id="using-react-lazy">Using React Lazy</h4>
<p><strong>React.lazy</strong> allows for lazy loading of imports in many contexts. It is not yet available for server-side rendering, but its diversity of functions makes up for that. The <code>React.lazy</code> method makes it easy to code-split a React application on a component level using dynamic imports. However, there will always be a slight delay that users have to experience when a code-split component is being fetched over the network, so it's important to display a useful loading state. Using <code>React.lazy</code> with the Suspense component helps solve this problem. </p>
<pre><code><span class="hljs-comment">//Without Suspense Fallback</span>
<span class="hljs-keyword">import</span> React, { lazy } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> HeaderComponent = lazy(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./HeaderComponent'</span>));

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">HeaderComponent</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)
</code></pre><pre><code><span class="hljs-comment">//With Suspense Fallback</span>
<span class="hljs-keyword">import</span> React, { lazy, Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> HeaderComponent = lazy(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./HeaderComponent'</span>));

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}&gt;
    <span class="hljs-tag">&lt;<span class="hljs-name">HeaderComponent</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span></span>
)
</code></pre><pre><code><span class="hljs-comment">//Suspense Fallback With Multiple Components</span>
<span class="hljs-keyword">import</span> React, { lazy, Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> HeaderComponent = lazy(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./HeaderComponent'</span>));
<span class="hljs-keyword">const</span> FooterComponent = lazy(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./FooterComponent'</span>));


<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}&gt;
    <span class="hljs-tag">&lt;<span class="hljs-name">HeaderComponent</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">FooterComponent</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span></span>
)
</code></pre><h4 id="loading-failures">Loading Failures</h4>
<p>If any module fails to load, for example, due to network failure, we will get an error that can handle these errors with Error Boundaries. Once we have created the <strong>Error Boundary</strong>, we can use it anywhere above our lazy components to display an error state.</p>
<pre><code><span class="hljs-keyword">import</span> React, { lazy, Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> HeaderComponent = lazy(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./HeaderComponent'</span>));
<span class="hljs-keyword">const</span> FooterComponent = lazy(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./FooterComponent'</span>));


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ErrorBoundary</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-built_in">super</span>(props);
    <span class="hljs-built_in">this</span>.state = {<span class="hljs-attr">hasError</span>: <span class="hljs-literal">false</span>};
  }

  <span class="hljs-keyword">static</span> getDerivedStateFromError(error) {
    <span class="hljs-keyword">return</span> {<span class="hljs-attr">hasError</span>: <span class="hljs-literal">true</span>};
  }

  render() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.state.hasError) {
      <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading failed! Please reload.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
    }

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.props.children;
  }
}

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ErrorBoundary</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">div</span>&gt;</span>Loading<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">HeaderComponent</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">FooterComponent</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ErrorBoundary</span>&gt;</span></span>
)
</code></pre><h3 id="conclusion">Conclusion</h3>
<p>With the above resource, I hope you're better suited to optimize your React application and have what it takes to split a project.</p>
<p>If you are unsure where to begin applying code splitting to your React application, follow these steps:</p>
<ul>
<li>Begin at the route level. Routes are the simplest way to identify points of your application that can be split. The React docs show how Suspense can be used along with react-router.</li>
<li>Identify any large components on a page on your site that only render on certain user interactions (like clicking a button). Splitting these components will minimize your JavaScript payloads.</li>
<li>Consider splitting anything else that is offscreen and not critical for the user.</li>
</ul>
<h4 id="resources-used">Resources Used:</h4>
<ul>
<li><a target="_blank" href="https://web.dev/code-splitting-suspense/">Web.Dev</a></li>
<li><a target="_blank" href="https://blog.logrocket.com/code-splitting-in-react-an-overview/">Log Rocket</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/error-boundaries.html">React Docs</a></li>
</ul>
<p>👉🏾  <a target="_blank" href="https://abdulqudus.com">Learn more about me</a><br />👉🏾  <a target="_blank" href="https://www.linkedin.com/in/jideabdqudus/">Connect on LinkedIn</a><br />👉🏾  <a target="_blank" href="blog.abdulqudus.com">Subscribe to my blog, let's feast</a></p>
<p><code>QOTD: Whatever is worth doing at all, is worth doing well</code>   </p>
]]></content:encoded></item><item><title><![CDATA[8 UI Frameworks for your React App]]></title><description><![CDATA[React  is an open-source front-end JavaScript library for building user interfaces or UI components. It is maintained by Facebook and has over 170k Github Stars making it the most popular framework (although stars may not be the best-ranking factor),...]]></description><link>https://blog.abdulqudus.com/8-ui-frameworks-for-your-react-app</link><guid isPermaLink="true">https://blog.abdulqudus.com/8-ui-frameworks-for-your-react-app</guid><category><![CDATA[React]]></category><category><![CDATA[javascript framework]]></category><category><![CDATA[Bootstrap]]></category><category><![CDATA[UI]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Fri, 22 Oct 2021 09:00:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1634893073289/BvPlL8wDW.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://reactjs.org/">React</a>  is an open-source front-end JavaScript library for building user interfaces or UI components. It is maintained by <em>Facebook</em> and has over 170k Github Stars making it the most popular framework (although stars may not be the best-ranking factor), according to the  <a target="_blank" href="https://insights.stackoverflow.com/survey/2020">stack-overflow 2020 survey</a>, React ranks #1 on the list of most-wanted tools. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1634889693290/rddbZqxIi.png" alt="CleanShot_2021-07-24_at_10.53.33_2x_sapbkojasjas.png" /></p>
<p>In this article, we would look at some of the <em>UI Frameworks</em> you can use alongside your <strong>React</strong> project, judging based on sources such as:</p>
<ul>
<li>GitHub </li>
<li>Npm </li>
<li>StackShare</li>
<li>Stackoverflow</li>
</ul>
<p>So let's start;</p>
<h3 id="1-ant-design">1. Ant Design</h3>
<p><em>Ant Design</em> (or AntD) is an enterprise-class UI design language with a set of high-quality React UI components. It is one of the best React UI libraries for enterprises. It offers many polished components that could be used to build an entire application. The documentation is extensive, with tons of examples, and stays up to date. It's also my personal favorite :) </p>
<h4 id="maintained-by-ant-designhttpsantdesign">Maintained by:  <a target="_blank" href="https://ant.design/">Ant Design</a>.</h4>
<h4 id="github-stars-734k">Github Stars: 73.4k</h4>
<h4 id="website-statisics-used-by-13-741-websiteshttpstrendsbuiltwithcomwebsitelistant-designhistorical">Website Statisics: Used by  <a target="_blank" href="https://trends.builtwith.com/websitelist/ANT-Design/Historical">13, 741 websites</a></h4>
<h4 id="used-by-binance-alibaba-alipay-coinrule">Used by: Binance, Alibaba, Alipay, Coinrule</h4>
<h4 id="pros">Pros:</h4>
<ul>
<li>Good Documentation and Examples</li>
<li>Typescript Support </li>
<li>Internationalization Support </li>
<li><p>Quality Icons </p>
<p><a target="_blank" href="https://ant.design/components/overview/">Visit Ant Design</a> </p>
</li>
</ul>
<h3 id="2-material-ui">2. Material UI</h3>
<p><em>Material-UI</em> is the most popular React UI framework that provides Google Material Design out of the box. Material design takes inspiration from the physical world and textures while keeping the actual UI elements to a minimum.</p>
<h4 id="maintained-by-material-ui-and-googlehttpsmuicom">Maintained by:  <a target="_blank" href="https://mui.com/">Material UI &amp; Google</a>.</h4>
<h4 id="github-stars-701k">Github Stars: 70.1k</h4>
<h4 id="website-statisics-used-by-193-121-websiteshttpstrendsbuiltwithcomwebsitelistmaterial-uihistorical">Website Statisics: Used by  <a target="_blank" href="https://trends.builtwith.com/websitelist/Material-UI/Historical">193, 121 websites</a></h4>
<h4 id="used-by-medium-roast-meisterplan">Used by: Medium, Roast, Meisterplan</h4>
<h4 id="pros">Pros:</h4>
<ul>
<li>Good Documentation and Examples</li>
<li>Exciting React themes and templates</li>
<li><p>Wide range of components</p>
<p><a target="_blank" href="https://mui.com/">Visit Material UI</a> </p>
</li>
</ul>
<h3 id="3-react-bootstrap">3. React Bootstrap</h3>
<p><em>React-Bootstrap</em> replaces Bootstrap JavaScript. Each component has been built from scratch as a true React component, without unneeded dependencies like jQuery. React Bootstrap is one of the oldest React UI libraries and has grown steadily with React itself. While React-Bootstrap doesn’t offer any official support, there is a massive, active community and plenty of resources supporting Bootstrap.</p>
<h4 id="maintained-by-mark-ottohttpsmarkdottocomabout">Maintained by:  <a target="_blank" href="https://markdotto.com/about">Mark Otto</a>.</h4>
<h4 id="github-stars-191k">Github Stars: 19.1k</h4>
<h4 id="website-statisics-used-by-11-221-websites">Website Statisics: Used by  11, 221 websites</h4>
<h4 id="used-by-butterflynetwork-scoutbee-isgoodai">Used by: Butterflynetwork, Scoutbee, Isgood.ai</h4>
<h4 id="pros">Pros:</h4>
<ul>
<li>Bootstrap’s grid system allows a fully responsive series of containers, rows, and columns for your layout.</li>
<li><p>Easy to use and edit</p>
<p><a target="_blank" href="https://react-bootstrap.github.io/">Visit React Bootstrap</a> </p>
</li>
</ul>
<h3 id="4-semantic-ui">4. Semantic UI</h3>
<p><em>Semantic UI</em> React is the official plugin for Semantic UI. The library boasts a collection of over fifty components, including segments, progress bars, transitions, pagination, and more. However, despite all of its unique features, if you do not have hands-on experience in JavaScript, you may find the library a bit complex.</p>
<h4 id="maintained-by-jack-lukichttpswwwcrunchbasecompersonjack-lukictextjack20lukic20has20220current2dfounder20at20myfaves20">Maintained by:  <a target="_blank" href="https://www.crunchbase.com/person/jack-lukic#:~:text=Jack%20Lukic%20has%202%20current,%2Dfounder%20at%20Myfav.es%20.">Jack Lukic</a>.</h4>
<h4 id="github-stars-124k">Github Stars: 12.4k</h4>
<h4 id="website-statisics-used-by-7-033-websites">Website Statisics: Used by  7, 033 websites</h4>
<h4 id="used-by-lumeneo-hackerworks-revio">Used by: Lumeneo, Hacker.works, Rev.io</h4>
<h4 id="pros">Pros:</h4>
<ul>
<li>Impressive customization and theming capabilities.</li>
<li>Wide collection for UI Components.</li>
<li>Zero traces of any jQuery code, simplifying the application development.</li>
<li><p>Declarative API.</p>
<p><a target="_blank" href="https://react.semantic-ui.com/">Visit Semantic UI</a> </p>
</li>
</ul>
<h3 id="5-chakra-ui">5. Chakra UI</h3>
<p><em>Chakra UI</em> provides a set of accessible, reusable, and composable React UI components that make it easy to create websites and apps. Chakra UI components are built on top of a React UI Primitive for endless composability. The community of Chakra UI is very active. You will get all the help required whenever you feel stuck.</p>
<h4 id="maintained-by-segun-adebayohttpsnglinkedincominthesegunadebayo">Maintained by:  <a target="_blank" href="https://ng.linkedin.com/in/thesegunadebayo">Segun Adebayo</a>.</h4>
<h4 id="github-stars-196k">Github Stars: 19.6k</h4>
<h4 id="used-by-bonton-orbital-luggit">Used by: Bonton, Orbital, LUGGIT</h4>
<h4 id="pros">Pros:</h4>
<ul>
<li>Chakra UI contains a set of layout components like Box and Stack that make it easy to style your components by passing props.</li>
<li>You can use the same react component as much as you want and customize it for further use.</li>
<li><p>This library does not require any heavy set up to implement and is simple and easy to use.</p>
<p><a target="_blank" href="https://chakra-ui.com/">Visit Chakra UI</a> </p>
</li>
</ul>
<h3 id="6-blueprint">6. Blueprint</h3>
<p><em>Blueprint</em> is a newly open-sourced design system implemented as a collection of composable React components and optimized for desktop applications. This is not a mobile-first UI toolkit.</p>
<h4 id="maintained-by-palantirhttpswwwpalantircom">Maintained by:  <a target="_blank" href="https://www.palantir.com/">Palantir</a>.</h4>
<h4 id="github-stars-182k">Github Stars: 18.2k</h4>
<h4 id="used-by-allocate-natml-onedot">Used by: Allocate, NatML, Onedot</h4>
<h4 id="pros">Pros:</h4>
<ul>
<li>The React UI library has over forty components optimized in particular for complex data-dense interfaces for desktop applications.</li>
<li><p>Contains many useful components like breadcrumbs, buttons, callouts, cards, dividers, navbars, tabs, tags, and much more.</p>
<p><a target="_blank" href="https://blueprintjs.com/">Visit Blueprint</a></p>
</li>
</ul>
<h3 id="7-fluent">7. Fluent</h3>
<p><em>Fluent UI</em> web represents a collection of utilities, React components, and web components for building web applications. It has Web Components and native libraries for iOS, macOS, Android, and Windows.</p>
<h4 id="maintained-by-microsofthttpswwwmicrosoftcomen-us">Maintained by:  <a target="_blank" href="https://www.microsoft.com/en-us">Microsoft</a>.</h4>
<h4 id="github-stars-118k">Github Stars: 11.8k</h4>
<h4 id="website-statisics-used-by-97-websiteshttpstrendsbuiltwithcomwebsitelistfluent-uihistorical">Website Statisics: Used by  <a target="_blank" href="https://trends.builtwith.com/websitelist/Fluent-UI/Historical">97 websites</a></h4>
<h4 id="npm-downloads-53498week">Npm Downloads: 53,498/Week</h4>
<h4 id="used-by-microsoft">Used by: Microsoft</h4>
<h4 id="pros">Pros:</h4>
<ul>
<li>It has components for building forms and lists but also offers very specific ones like a PeoplePicker for example.</li>
<li><p>Good default styling capabilities without any code.</p>
<p><a target="_blank" href="https://developer.microsoft.com/en-us/fluentui/">Visit Fluent</a></p>
</li>
</ul>
<h3 id="8-grommet">8. Grommet</h3>
<p><em>Grommet</em> is a React-based framework that provides accessibility, modularity, responsiveness, and themes in a tidy package. Grommet is a component library designed for responsive, accessible, and mobile-first web projects. It even has a list of SVG icons.</p>
<h4 id="maintained-by-hewlett-packard-enterpriseshttpswwwhpcomin-enhomehtml">Maintained by:  <a target="_blank" href="https://www.hp.com/in-en/home.html">Hewlett Packard Enterprises</a>.</h4>
<h4 id="github-stars-73k">Github Stars: 7.3k</h4>
<h4 id="npm-downloads-23278week">Npm Downloads: 23,278/Week</h4>
<h4 id="used-by-netflix-uber-boeing-hp">Used by: Netflix, Uber, Boeing, HP</h4>
<h4 id="pros">Pros:</h4>
<ul>
<li>It embraces atomic design methods and allows for keyboard navigation, screen reader tags, and more.</li>
<li><p>Powerful theming tools which let you tailor the component library to align with your color, type, and layout needs. You can even control component interaction.</p>
<p><a target="_blank" href="https://v2.grommet.io/">Visit Grommet</a></p>
</li>
</ul>
<h3 id="conclusion">Conclusion</h3>
<p>With the above resource, you now have a list of 8 different UI Frameworks to pick from while building your next React project. </p>
<p>Let me know if I'm missing any in the comment section 🤔</p>
<h4 id="resources-used">Resources used:</h4>
<ul>
<li><a target="_blank" href="https://www.raftlabs.co/development/top-react-ui-frameworks?utm_source=medium&amp;utm_campaign=crosspost">Raftlabs</a></li>
<li><a target="_blank" href="https://trends.builtwith.com/websitelist">TrendsBuiltWith</a></li>
</ul>
<p>👉🏾  <a target="_blank" href="https://abdulqudus.com">Learn more about me</a>  👉🏾  <a target="_blank" href="https://www.linkedin.com/in/jideabdqudus/">Connect on LinkedIn</a>  👉🏾  <a target="_blank" href="https://blog.abdulqudus.com">Subscribe to my blog, let's feast</a> </p>
<p><code>QOTD: We are what we repeatedly do. Excellence then is not an act, but a habit.</code></p>
]]></content:encoded></item><item><title><![CDATA[Props vs State - React]]></title><description><![CDATA[In building a React project, you make use of props or states ( as the case may be ) across your application, in this article you would learn:

What props are
What states are 
How to use props and states in React components
The difference between prop...]]></description><link>https://blog.abdulqudus.com/props-vs-state-react</link><guid isPermaLink="true">https://blog.abdulqudus.com/props-vs-state-react</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Fri, 15 Oct 2021 11:33:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1634243358461/5vUZ2OWEx.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In building a <strong>React</strong> project, you make use of <em>props</em> or <em>states</em> ( as the case may be ) across your application, in this article you would learn:</p>
<ul>
<li>What props are</li>
<li>What states are </li>
<li>How to use props and states in React components</li>
<li>The difference between props and states</li>
</ul>
<h2 id="what-exactly-are-props">What exactly are Props?</h2>
<p><em>Props</em> is just a short form of saying <code>properties</code>, think of <code>props</code> as arguments passed into a <em>function</em>. 
React components are functions that return JSX (or more generally something that's renderable like React elements, null, a string, etc.). Typically when you have a piece of code that you would like to reuse, you can place that code into a function, and any dynamic values that code used before can be accepted as arguments. </p>
<p>That being said, <code>props</code> can be anything. In our example they're numbers, but they can also be (and often are) strings, arrays, objects, functions, etc. </p>
<p>In the example below, the parent component can pass a prop to its child component like:</p>
<pre><code><span class="hljs-tag">&lt;<span class="hljs-name">AdditionComponent</span> <span class="hljs-attr">n1</span>=<span class="hljs-string">{2}</span> <span class="hljs-attr">n2</span>=<span class="hljs-string">{3}</span> /&gt;</span>
</code></pre><p>The child component can make use of the passed props by getting the props and using in this format:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AdditionComponent</span>(<span class="hljs-params">props</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {props.n1} + {props.n2} = {props.n1 + props.n2}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre><p>Which would in turn render <code>2 + 3 = 5</code> on the UI.</p>
<blockquote>
<p>Props are immutable so we cannot modify the props from inside the component. Modifying the props passed into the Add component would throw an error; </p>
</blockquote>
<p>In your react app, you can <strong>destructure</strong> your props so as to make your code more readable and still get the same output. <em>Destructuring</em> the example above would give us this output:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AdditionComponent</span>(<span class="hljs-params">props</span>) </span>{
<span class="hljs-keyword">const</span> { n1, n2 } = props  
<span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {n1} + {n2} = {n1 + n2}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre><p>Another way of destrcturing is doing it at the top level of your fucntion declaration:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AdditionComponent</span>(<span class="hljs-params">{n1,n2}</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {n1} + {n2} = {n1 + n2}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre><p>After agreeing that props are immutable, what happens if we want to change  a particular prop value based on an action? We get an <code>error</code> and this is where <strong>states</strong> come in...</p>
<h2 id="what-is-a-react-state">What is a React State?</h2>
<p>Like <code>props</code>, <code>state</code> holds information about the component. However, the kind of information and how it is handled is different. The <code>state</code> is an updatable structure that is used to contain data or information about the component and can change over time. The change in <code>state</code> can happen as a response to user action or system event. </p>
<p>To define a state in a <em>React (Functional Component)</em> all we have to do is import the <code>useState</code> hook into our app and use accordingly, like below:</p>
<pre><code><span class="hljs-keyword">import</span> {useState} <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> AdditionForm = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [num, setNum] = useState(<span class="hljs-number">0</span>)

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleInputChange</span>(<span class="hljs-params">event</span>) </span>{
    setNum(event.target.value)
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{num}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleInputChange}</span> /&gt;</span> =  {num}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre><p>Now, for each change in the input field, num gets tracked according to the state change.</p>
<p>Where as, for  a <em>Class based component</em>, we can achieve the same action by doing this:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AdditionForm</span> <span class="hljs-title">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-keyword">super</span>();
    <span class="hljs-keyword">this</span>.state = {
      num: <span class="hljs-number">0</span>,
    };
  }
handleInputChange(event) {
    <span class="hljs-keyword">this</span>.setState({num: event.target.value });
  }
render() {
    <span class="hljs-keyword">return</span> (
      &lt;input type=<span class="hljs-string">"number"</span> value={<span class="hljs-keyword">this</span>.state.num} onChange={<span class="hljs-keyword">this</span>.handleInputChange} /&gt; = {<span class="hljs-keyword">this</span>.state.num}
 );
 }
}
</code></pre><p>Now, state is changeable and can be reused across our application 😉</p>
<h2 id="conclusion">Conclusion</h2>
<p>We now have a proper idea of what states and props are, how they can be used, and the difference between both. </p>
<blockquote>
<p>Go ahead and test your knowledge on what you've learnt and tell me in the comment section if you can pass <code>states</code> as <code>props</code> in a React application 🙋🏾‍♂️❔</p>
</blockquote>
<h4 id="resources-used">Resources used:</h4>
<ul>
<li><a target="_blank" href="https://medium.com/@itIsMadhavan/reactjs-props-vs-state-ff3a7680930d">Madhavan Nagarajan</a> </li>
<li><a target="_blank" href="https://kentcdodds.com/blog/props-vs-state">Kent Dodds</a> </li>
</ul>
<p>👉🏾 <a target="_blank" href="https://abdulqudus.com">Learn more about me</a>
👉🏾 <a target="_blank" href="https://linkedin.com/in/jideabdqudus/">Connect on LinkedIn</a> 
👉🏾 <a target="_blank" href="https://blog.abdulqudus.com">Subscribe to my blog, let's feast</a>  </p>
]]></content:encoded></item><item><title><![CDATA[Setting up Redux with your React App]]></title><description><![CDATA[When building medium or large-scale applications it's a better practice to use a State management system like Context or Redux.
In this guide, you will learn:

What Redux is
How Redux works
How to setup Redux in a React app

What is Redux?
Redux is a...]]></description><link>https://blog.abdulqudus.com/setting-up-redux-with-your-react-app</link><guid isPermaLink="true">https://blog.abdulqudus.com/setting-up-redux-with-your-react-app</guid><category><![CDATA[React]]></category><category><![CDATA[Redux]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Fri, 08 Oct 2021 10:43:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1633376590665/TyuXuTD1b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When building medium or large-scale applications it's a better practice to use a State management system like Context or Redux.</p>
<p>In this guide, you will learn:</p>
<ul>
<li>What Redux is</li>
<li>How Redux works</li>
<li>How to setup Redux in a React app</li>
</ul>
<h3 id="what-is-redux">What is Redux?</h3>
<p>Redux is a predictable state container for JavaScript apps. It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time-traveling debugger. In layman's terms, It's <em>a state management system for javascript apps</em>.</p>
<p>I personally recommend redux for medium/large scale applications and context for small applications.</p>
<h3 id="how-does-redux-work">How does Redux work?</h3>
<p>In <em>Redux</em> you have to remember 3 things:</p>
<ul>
<li>Action</li>
<li>Reducer</li>
<li>Store</li>
</ul>
<p>So in redux, you will create only one <code>store</code> and pass the store in your topmost react component. Normally in App Component in <code>src/app.js</code> file or <code>index.js file</code>. <strong>Store</strong> holds all the app state or global state for the application in <em>Redux</em>.</p>
<p>As the store will be passed to the React application or view part, we can pass any information or command. This is called <strong>action</strong> in the <em>Redux</em> way. That means you want to dispatch an action to send some command.</p>
<p>Basically the <strong>actions</strong> will be <strong>dispatched</strong> to the <strong>reducer</strong> which is a fancy term of function. The <strong>reducer</strong> will get the current state from the <strong>store</strong> and will use the <strong>actions</strong> to create a new state based on the old state and will update in the <strong>store</strong>.</p>
<p>Finally, if a view component is connected to the <strong>store</strong>, it will re-render when the state in the <strong>Redux</strong> store will be updated.</p>
<h3 id="how-to-setup-redux-in-a-react-app">How to setup Redux in a React app</h3>
<h4 id="installing-the-dependencies">Installing the dependencies</h4>
<p>The first step is installing our dependencies from NPM, so on our command-line interface.</p>
<pre><code>npm i redux react-redux redux-thunk redux-devtools-<span class="hljs-keyword">extension</span>
</code></pre><p><strong>Redux</strong> is stand-alone and <code>react-redux</code> gives us access to several hooks that make life easier, <code>redux-thunk</code> is a middleware that allows you to write action creators that return a function instead of an action,  <code>redux-devtools-extension</code> is an optional dependency that I make use of to improve debugging and view states on the web.</p>
<h4 id="create-folders-and-files">Create folders and files</h4>
<p>A lot of people set up their folder structures in different ways with <strong>Redux</strong>,  I like to create a <code>redux</code> folder and place my <code>actions</code> and <code>reducers</code> in separate folders within this particular folder, and a separate file in this folder for my <code>types</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633344724276/OMNMkUO4F.jpeg" alt="redux_structure912102.JPG" /></p>
<p>By the way, actions are objects that determine what will be done. Reducers, on the other hand, check which action is performed and update the state based on the action.</p>
<p>For the purpose of this article, we are building a small counter app. </p>
<h4 id="define-the-types-constants">Define the Types (constants)</h4>
<ul>
<li>Start by defining the <strong>types</strong> that would be used across the application, I like placing this in a separate file (<code>Types.js</code>) for clarity and reusability. Since we are building a simple project, it's quite easy to determine what all the types would be.</li>
</ul>
<pre><code><span class="hljs-comment">//Types.Js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> INCREMENT = <span class="hljs-string">"INCREMENT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> DECREMENT = <span class="hljs-string">"DECREMENT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> RESET = <span class="hljs-string">"RESET"</span>;
</code></pre><h4 id="create-reducer">Create Reducer</h4>
<ul>
<li>Now create a <code>counterReducer.js</code> file inside the reducer folder you created earlier on.</li>
</ul>
<pre><code><span class="hljs-comment">//counterReducer.js</span>
<span class="hljs-keyword">import</span> { INCREMENT, DECREMENT, RESET } <span class="hljs-keyword">from</span> <span class="hljs-string">'../Types.js'</span>
<span class="hljs-keyword">const</span> initialState = {
    counter: <span class="hljs-number">0</span>
}
<span class="hljs-keyword">const</span> counterReducer = <span class="hljs-function">(<span class="hljs-params">state = initialState, action</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (action.type) {
    <span class="hljs-keyword">case</span> INCREMENT:
      <span class="hljs-keyword">return</span> {
        state,
        counter: state.counter + <span class="hljs-number">1</span>
      }
    <span class="hljs-keyword">case</span> DECREMENT:
      <span class="hljs-keyword">return</span> {
        state,
        counter: state.counter - <span class="hljs-number">1</span>
      }
    <span class="hljs-keyword">case</span> RESET:
      <span class="hljs-keyword">return</span> {
        state,
        counter: <span class="hljs-number">0</span>
      }
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">return</span> state;
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> counterReducer
</code></pre><p>For the snippet of code above, we've basically created our reducer by defining its initial state and what happens when a particular action type is fired; A lot of people typically create the reducer with a switch statement, but it is also possible to use an if statement. </p>
<h4 id="create-index-reducer">Create "Index" Reducer</h4>
<ul>
<li>Next, we create an <code>index.js</code> file inside of our reducers folder, for an application with more than one reducer, we make use of the <code>combineReducer</code> function, this function turns our reducers into a single reducer that we can pass to the <code>createStore</code> API. Now our demo application only has one reducer, but for the purpose of subsequent projects we are going to make use of the <code>combineReducer</code> function.</li>
</ul>
<pre><code><span class="hljs-comment">//Index.js(Reducer)</span>
<span class="hljs-keyword">import</span> { combineReducers } <span class="hljs-keyword">from</span> <span class="hljs-string">'redux'</span>
<span class="hljs-keyword">import</span> counterReducer <span class="hljs-keyword">from</span> <span class="hljs-string">'./counterReducer'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> combineReducers({<span class="hljs-attr">counter</span>: counterReducer})
</code></pre><h4 id="create-global-store">Create global store</h4>
<ul>
<li>Now let's create a <code>store.js</code> file inside of our <code>src</code> folder, see this as the logic and the connector between react and redux. To use the store, we are going to add it as a prop inside of a <strong>Provider</strong> that's going to wrap our entire application. </li>
</ul>
<pre><code><span class="hljs-comment">//store.js</span>
<span class="hljs-keyword">import</span> { applyMiddleware, createStore } <span class="hljs-keyword">from</span> <span class="hljs-string">'redux'</span>
<span class="hljs-keyword">import</span> { composeWithDevTools } <span class="hljs-keyword">from</span> <span class="hljs-string">'redux-devtools-extension'</span>
<span class="hljs-keyword">import</span> thunk <span class="hljs-keyword">from</span> <span class="hljs-string">'redux-thunk'</span>
<span class="hljs-keyword">import</span> rootReducer <span class="hljs-keyword">from</span> <span class="hljs-string">'./redux/reducers'</span>

<span class="hljs-keyword">const</span> initialState = {}
<span class="hljs-keyword">const</span> middleware = [thunk]
<span class="hljs-keyword">const</span> store = createStore(
  rootReducer,
  initialState,
  composeWithDevTools(applyMiddleware(...middleware))
)
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> store
</code></pre><ul>
<li>Import <code>store.js</code> into <code>Index.js</code>:</li>
</ul>
<pre><code><span class="hljs-comment">//index.js</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./index.css'</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App'</span>;
<span class="hljs-comment">//New code</span>
<span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-redux'</span>
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>


ReactDOM.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>,
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)
);
</code></pre><h4 id="create-actions">Create actions</h4>
<ul>
<li>Let's create the actions that would be used inside of our application, the actions determine what happens to the reducers (this is where your <code>API</code> calls happen too). Inside the <code>actions</code> folder, let's create <code>counterActions.js</code>.</li>
</ul>
<pre><code><span class="hljs-comment">//counterActions.js</span>
<span class="hljs-keyword">import</span> { INCREMENT, DECREMENT, RESET } <span class="hljs-keyword">from</span> <span class="hljs-string">'../Types.js'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> increment = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-keyword">type</span>: INCREMENT,
  };
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> decrement = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-keyword">type</span>: DECREMENT,
  };
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> reset = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-keyword">type</span>: RESET,
  };
};
</code></pre><ul>
<li>Finally, we can make use of the actions in our app, where we have the counter:</li>
</ul>
<pre><code><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> logo <span class="hljs-keyword">from</span> <span class="hljs-string">"./logo.svg"</span>
<span class="hljs-keyword">import</span> { useSelector, useDispatch } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> {  decrement,  increment, reset, } <span class="hljs-keyword">from</span> <span class="hljs-string">"./redux/actions/counterAction"</span>;

<span class="hljs-keyword">const</span> App =<span class="hljs-function">()=&gt;</span> {
  <span class="hljs-comment">//dispatch is the hook to fire off our actions</span>
  <span class="hljs-keyword">const</span> dispatch = useDispatch();
  <span class="hljs-comment">//useSelector helps access the states across the application.</span>
  <span class="hljs-keyword">const</span> counter = useSelector(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> state.counter);
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{logo}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-logaso"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"logo"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Redux project<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Counter<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>{counter.counter}<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> dispatch(increment())}&gt;Increase<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> dispatch(reset())}&gt;Reset<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> dispatch(decrement())}&gt;Decrease<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre><p>Now we should have a fully working react-redux application.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633375272479/HjVHV8ha1.gif" alt="React_App_-_Google_Chrome_2021-10-04_20-14-43_SparkVideo (1).gif" /></p>
<h3 id="conclusion">Conclusion</h3>
<p>We now have a fully running react-redux application, new reducers can be created in the reducers folder, actions created in the actions folder then connected to the combineReducers export.</p>
<p>While <strong>Redux</strong> is by far the popular and widely used state management system, I highly recommend using Redux for large and medium-sized applications alone. </p>
<p>There are other state management systems I've come across like Mobx, Context API, and Apollo for GraphQL to use at your disposal likewise.</p>
<p>I hope you enjoyed reading this and would be building your next Redux application without hassle. </p>
<p>Thanks to the creator of Redux and one of my Favorite Software developers,  <a target="_blank" href="https://twitter.com/dan_abramov">Dan Abramov</a> </p>
<p>👉🏾 <a target="_blank" href="https://abdulqudus.com">Learn more about me</a> </p>
<p>👉🏾 <a target="_blank" href="https://twitter.com/jideabdqudus">Follow me on Twitter</a> </p>
<p>👉🏾 <a target="_blank" href="blog.abdulqudus.com">Subscribe to my blog</a> </p>
]]></content:encoded></item><item><title><![CDATA[Progressive Web Apps in React (PWA Guide)]]></title><description><![CDATA[In this article you will learn:

What Progressive Web Apps (PWAs) are
Rules of a PWA
Create a React App as a PWA
How to convert your existing React app to a PWA

What is a Progressive Web App?
A progressive web application (or PWA) is a web applicati...]]></description><link>https://blog.abdulqudus.com/progressive-web-apps-in-react-pwa-guide</link><guid isPermaLink="true">https://blog.abdulqudus.com/progressive-web-apps-in-react-pwa-guide</guid><category><![CDATA[React]]></category><category><![CDATA[PWA]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Fri, 01 Oct 2021 00:43:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1632678712440/aO2IU7v9NA.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article you will learn:</p>
<ul>
<li>What Progressive Web Apps (PWAs) are</li>
<li>Rules of a PWA</li>
<li>Create a React App as a PWA</li>
<li>How to convert your existing React app to a PWA</li>
</ul>
<h3 id="what-is-a-progressive-web-app">What is a Progressive Web App?</h3>
<p>A progressive web application (or PWA) is a web application that is built to look and behave like native apps, operates offline, allows installation, and is optimized for a variety of screens.
Basically, a Progressive Web App (PWA) is an application that expands the functionality of a regular website <strong>progressively</strong> by adding features that previously were exclusive for native applications.</p>
<p>A couple of big companies have switched to using PWAs since its creation in 2015, let's take a look;</p>
<ul>
<li>Twitter:  The benefits of using PWA over the traditional app? Well, it takes up less storage for a start, 3% less disk space to be exact for the Android version. Twitter has credited this with a 75% increase in the number of Tweets, a 65% increase in pages per session, and a 20% decrease in bounce rates.</li>
<li>Uber: Uber’s PWA, m.uber, allows you to hail a ride without downloading and installing the traditional Uber mobile app. It’s absolutely tiny, with the core service only taking up 50kb which means it loads quickly even on the poorest of connections. </li>
<li>Instagram:  If you visit Instagram on your mobile browser now, you’ll be accessing it via a PWA. Previously you’d have struggled with a lack of functionality, only really being able to browse your timeline or profile. Now the PWA looks just like the traditional app and gives you some extra functionality as well.</li>
<li>Pinterest: built a PWA when they discovered that their website experience is too slow. On Pinterest’s PWA, users spend 40% more time compared to the previous version. Its PWA requires only 150 KB of data storage.</li>
</ul>
<h3 id="rules-of-a-pwa">Rules of a PWA</h3>
<ul>
<li>PWAs must implement service workers, service workers act as a proxy between the web browsers and API servers, which allows web apps to message and cache network requests and assets.</li>
<li>PWAs must be served over a secure network, i.e the application must be served over HTTPS.</li>
<li>PWAs must have a web manifest, which is a JSON file that provides basic information about the PWA, such as name, icons, splash screen, description, version of the app e.t.c.</li>
</ul>
<p>Okay, now we understood all the benefits and reasons why your app should be a PWA, it's time to create our first PWA.</p>
<h3 id="create-a-react-app-as-a-pwa">Create a React App as a PWA</h3>
<p>Starting with <strong>Create React App 4</strong>, you can now create your react app as a PWA from scratch in one easy step. So I wouldn't be spending so much time on this. </p>
<pre><code>npx <span class="hljs-keyword">create</span>-react-app my-app <span class="hljs-comment">--template cra-template-pwa</span>
</code></pre><p>By typing the above command, you get a react app with a PWA template containing the Service-Workers and App Manifest.</p>
<p> 👉🏾 <a target="_blank" href="https://create-react-app.dev/docs/making-a-progressive-web-app/">TS; WM?</a> </p>
<h3 id="how-to-convert-a-react-app-to-a-pwa">How to convert a react app to a PWA</h3>
<p>Now the exciting part, converting an existing react project to a Progressive web application;
Before going over the steps, let's take a look at the lighthouse report of our React App to verify the PWA status. This can be done by navigating to <strong>lighthouse</strong> in the developer tools and clicking on <strong>Generate report</strong>. 
This is what you should have (or similar):
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632681239579/X3CQjHGRR.jpeg" alt="pwa_0219.JPG" /></p>
<p>This shows that our react app isn't progressive (yet)! We are going to change this in the following steps:</p>
<h4 id="1-creating-a-service-worker">1. Creating a service worker</h4>
<p>What is a service worker? The service worker provides a programmatic way to cache app resources, be it javascript files or JSON data from HTTP requests.
Create a file called <code>service-worker.js</code> inside of your public folder, and add the following code:</p>
<pre><code><span class="hljs-keyword">var</span> CACHE_NAME = <span class="hljs-string">'pwa-example'</span>;
<span class="hljs-keyword">var</span> urlsToCache = [
  <span class="hljs-string">'/'</span>,
  <span class="hljs-string">'/completed'</span>
];

<span class="hljs-comment">// Install a service worker</span>
self.addEventListener(<span class="hljs-string">'install'</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  <span class="hljs-comment">// Perform install steps</span>
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">cache</span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Opened cache'</span>);
        <span class="hljs-keyword">return</span> cache.addAll(urlsToCache);
      })
  );
});

<span class="hljs-comment">// Cache and return requests</span>
self.addEventListener(<span class="hljs-string">'fetch'</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  event.respondWith(
    caches.match(event.request)
      .then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">response</span>) </span>{
        <span class="hljs-comment">// Cache hit - return response</span>
        <span class="hljs-keyword">if</span> (response) {
          <span class="hljs-keyword">return</span> response;
        }
        <span class="hljs-keyword">return</span> fetch(event.request);
      }
    )
  );
});

<span class="hljs-comment">// Update a service worker</span>
self.addEventListener(<span class="hljs-string">'activate'</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  <span class="hljs-keyword">var</span> cacheWhitelist = [<span class="hljs-string">'pwa-task-manager'</span>];
  event.waitUntil(
    caches.keys().then(<span class="hljs-function"><span class="hljs-params">cacheNames</span> =&gt;</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.all(
        cacheNames.map(<span class="hljs-function"><span class="hljs-params">cacheName</span> =&gt;</span> {
          <span class="hljs-keyword">if</span> (cacheWhitelist.indexOf(cacheName) === <span class="hljs-number">-1</span>) {
            <span class="hljs-keyword">return</span> caches.delete(cacheName);
          }
        })
      );
    })
  );
});
</code></pre><p>What the code in <code>service-worker.js</code> does is - define a callback for the install event and choose what to cache. Inside the callback, we open a cache, cache the files, and get confirmation that assets are cached. </p>
<h4 id="2-update-indexhtml">2. Update Index.html</h4>
<p>Now, update your <code>index.html</code> file <em>(in the public folder)</em> to verify the status of a service worker in the application when it loads.  Place this code inside of your <code>body</code> tag</p>
<pre><code><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">if</span> (<span class="hljs-string">'serviceWorker'</span> <span class="hljs-keyword">in</span> navigator) {
       <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'load'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
         navigator.serviceWorker.register(<span class="hljs-string">'serviceWorker.js'</span>).then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">registration</span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Worker registration successful'</span>, registration.scope);
           }, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>) </span>{
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Worker registration failed'</span>, err);
             }).catch(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>) </span>{
            <span class="hljs-built_in">console</span>.log(err);
            });
            });
    } <span class="hljs-keyword">else</span> {
       <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Service Worker is not supported by browser.'</span>);
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre><h4 id="3-update-indexjs">3. Update Index.js</h4>
<p>Update your <code>index.js</code> in the src folder <em>(src/index.js)</em> from serviceWorker.unregister() to <strong>serviceWorker.register()</strong>.</p>
<pre><code><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./index.css'</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App'</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> serviceWorker <span class="hljs-keyword">from</span> <span class="hljs-string">'./serviceWorker'</span>;

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>));

<span class="hljs-comment">//Updated Code here</span>
serviceWorker.register();
</code></pre><h4 id="4-update-manifestjson">4. Update manifest.json</h4>
<p>Your react app comes with a <strong>manifest</strong> by default, but if not, then create a <code>manifest.json</code> file inside the <code>public</code> folder with the following code:</p>
<pre><code>{
  <span class="hljs-attr">"short_name"</span>: <span class="hljs-string">"React App"</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Create React App Sample"</span>,
  <span class="hljs-attr">"icons"</span>: [
    {
      <span class="hljs-attr">"src"</span>: <span class="hljs-string">"favicon.ico"</span>,
      <span class="hljs-attr">"sizes"</span>: <span class="hljs-string">"64x64 32x32 24x24 16x16"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"image/x-icon"</span>
    },
    {
      <span class="hljs-attr">"src"</span>: <span class="hljs-string">"logo192.png"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"image/png"</span>,
      <span class="hljs-attr">"sizes"</span>: <span class="hljs-string">"192x192"</span>
    },
    {
      <span class="hljs-attr">"src"</span>: <span class="hljs-string">"logo512.png"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"image/png"</span>,
      <span class="hljs-attr">"sizes"</span>: <span class="hljs-string">"512x512"</span>
    }
  ],
  <span class="hljs-attr">"start_url"</span>: <span class="hljs-string">"."</span>,
  <span class="hljs-attr">"display"</span>: <span class="hljs-string">"standalone"</span>,
  <span class="hljs-attr">"theme_color"</span>: <span class="hljs-string">"#000000"</span>,
  <span class="hljs-attr">"background_color"</span>: <span class="hljs-string">"#ffffff"</span>
}
</code></pre><p>The app manifest file describes the resources your app will need, this includes your app's display name, icons as well as a splash screen. You can edit the file to suit your needs </p>
<p>Run the application again (npm run start) you should have a running PWA, verify this  by opening  the Developer tools and check the <code>Lighthouse reports</code>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632683542166/hXZy_zhJy.jpeg" alt="ajasia.JPG" /></p>
<h3 id="conclusion">Conclusion</h3>
<p>An important feature of PWAs is the security (HTTPS), deploying your app would take care of this step for you. Once your app is deployed and secure, all your audit tests will be passed and users would be able to fully access a PWA :)</p>
<p>I hope you enjoyed reading this and could build a PWA using this article :)</p>
<p>Thanks! 
<a target="_blank" href="https://abdulqudus.com">Learn more about me</a></p>
<p>Oh, one more thing, my website is built as a PWA. Check out the mobile and desktop look here:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632678112257/uZF9_26de.jpeg" alt="screenshot_pwa_copy.jpg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632678750050/6iNxE2Tfa.jpeg" alt="blur_pwa.jpg" /></p>
<p> Resources:</p>
<ul>
<li><a target="_blank" href="https://create-react-app.dev/docs/making-a-progressive-web-app/">Create React App</a></li>
<li><a target="_blank" href="https://web.dev/what-are-pwas/">What are PWAs</a> </li>
<li><a target="_blank" href="https://www.biggerpicture.agency/insights/9-examples-of-brilliant-progressive-web-apps-pwas">Brilliant Progressive Web Apps</a>   </li>
<li><a target="_blank" href="https://web.dev/drive-business-success/">How PWAs can drive business success</a></li>
</ul>
<p><em>Header image was designed by myself, feel free to use :)</em></p>
]]></content:encoded></item><item><title><![CDATA[Implementing a Linked List in Python: Easy as 1,2,3.]]></title><description><![CDATA[If you are learning data structures, a Linked List is one of the data structures you should know, albeit not so common, linked lists are similar to Lists (or arrays); you probably never heard or used them until now, but in the right context they prov...]]></description><link>https://blog.abdulqudus.com/implementing-a-linked-list-in-python</link><guid isPermaLink="true">https://blog.abdulqudus.com/implementing-a-linked-list-in-python</guid><category><![CDATA[Python]]></category><category><![CDATA[data structures]]></category><category><![CDATA[algorithms]]></category><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Mon, 20 Sep 2021 11:10:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631666945058/tV1Gh_sQk.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are learning data structures, a <strong>Linked List</strong> is one of the data structures you should know, albeit not so common, linked lists are similar to <em>Lists (or arrays)</em>; you probably never heard or used them until now, but in the right context they prove to be useful.</p>
<p>In this article, you will learn:</p>
<ul>
<li>What linked lists are.</li>
<li>Performance of linked lists.</li>
<li>Types of linked lists.</li>
<li>How to Implement your own linked list.</li>
</ul>
<h2 id="what-are-linked-lists">What are linked lists?</h2>
<p>A <strong>linked list</strong> is a sequence of data elements, which are connected together via links. Each element <em>(node)</em> in a linked list contains a connection to another data element in form of a pointer. </p>
<h3 id="you-should-know">You should know:</h3>
<p>That every element in a linked list is called a Node, and every node contains a <strong>data</strong> (value to be stored) and <strong>next</strong> (reference to the next node) fields.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631660678835/wMly27lxq.jpeg" alt="ll_node.jpg" /></p>
<p>A linked list therefore is a collection of nodes, with the last node pointing to <code>None</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631661130804/R_HNEHB9C.jpeg" alt="ll_fulllist.jpg" /></p>
<h2 id="performance-of-linked-lists">Performance of linked lists.</h2>
<p>In a linked list, the time complexity for the operations is given as:</p>
<ul>
<li>Indexing - O(n)</li>
<li>Insertion - O(1)</li>
<li>Deletion - O(1)</li>
<li>Search - O(n)</li>
</ul>
<p>Space complexity however is O(n).</p>
<h2 id="types-of-linked-lists">Types of linked lists.</h2>
<p>There are 3 main types of linked lists;</p>
<ul>
<li>Singly-linked lists: Each node consists of only one pointer to the next (which we are learning)</li>
<li>Doubly-linked lists: Each node contains two pointers, a pointer to the next node and a pointer to the previous node. </li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631661821627/506epzxdh.jpeg" alt="ll_doubly.jpg" /></p>
<ul>
<li>Circular-linked lists: In a circular linked list the last node points to the first node or any other node before it thereby forming a loop</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631662489705/X_m1w1cbD.jpeg" alt="ll_circular.jpg" /></p>
<h1 id="implementing-a-linked-list-in-python">Implementing a linked list in Python</h1>
<p>This comes in 2 parts, creating our list Node, and the Linked List itself. So, first thing first, create a class to represent each <em>Node</em> of the linked list</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, data)</span></span>:
        <span class="hljs-keyword">self</span>.data = data
        <span class="hljs-keyword">self</span>.<span class="hljs-keyword">next</span> = None
</code></pre><p><em>As you can see each node contains just 2 fields, the data, and next</em>.</p>
<p>Next, create a class to represent your linked list :</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinkedList</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, nodes=None)</span></span>:
        <span class="hljs-keyword">self</span>.head = None
        <span class="hljs-keyword">if</span> nodes is <span class="hljs-keyword">not</span> <span class="hljs-symbol">None:</span>
            node = Node(data=nodes.pop(<span class="hljs-number">0</span>))
            <span class="hljs-keyword">self</span>.head = node
            <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> <span class="hljs-symbol">nodes:</span>
                node.<span class="hljs-keyword">next</span> = Node(data=n)
                node = node.<span class="hljs-keyword">next</span>
</code></pre><h3 id="putting-it-all-together">Putting it all together</h3>
<p>Let's update each of our classes with a  <a target="_blank" href="https://docs.python.org/3/reference/datamodel.html#object.__repr__"><strong>repr</strong> function</a>  so our new code looks like this : </p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, data)</span></span>:
        <span class="hljs-keyword">self</span>.data = data
        <span class="hljs-keyword">self</span>.<span class="hljs-keyword">next</span> = None

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__repr__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>)</span></span>:
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">self</span>.data

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinkedList</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, nodes=None)</span></span>:
        <span class="hljs-keyword">self</span>.head = None
        <span class="hljs-keyword">if</span> nodes is <span class="hljs-keyword">not</span> <span class="hljs-symbol">None:</span>
            node = Node(data=nodes.pop(<span class="hljs-number">0</span>))
            <span class="hljs-keyword">self</span>.head = node
            <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> <span class="hljs-symbol">nodes:</span>
                node.<span class="hljs-keyword">next</span> = Node(data=n)
                node = node.<span class="hljs-keyword">next</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__repr__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>)</span></span>:
        node = <span class="hljs-keyword">self</span>.head
        nodes = []
        <span class="hljs-keyword">while</span> node is <span class="hljs-keyword">not</span> <span class="hljs-symbol">None:</span>
            nodes.append(node.data)
            node = node.<span class="hljs-keyword">next</span>
        nodes.append(<span class="hljs-string">"None"</span>)
        <span class="hljs-keyword">return</span> <span class="hljs-string">" -&gt; "</span>.join(nodes)
</code></pre><p>The code above would rightly allow us to create a linked list, notice that in the LinkedList <code>init</code> function if the node is not passed we initialized it to <code>None</code>.</p>
<pre><code>my_list = LinkedList()
firstNode = Node(<span class="hljs-string">"1"</span>)
my_list.head = firstNode
secondNode = Node(<span class="hljs-string">"2"</span>)
firstNode.next = secondNode
print(my_list)

&gt;&gt;&gt; 1 -&gt; 2 -&gt; None
</code></pre><h3 id="linked-lists-methods">Linked Lists Methods</h3>
<p>To help us use our linked lists even more efficiently, we would implement some methods to:</p>
<ul>
<li>Traverse a linked list.</li>
<li>Insert a new node at the beginning.</li>
<li>Insert a new node at the end.</li>
</ul>
<h3 id="traverse-a-linked-list">Traverse a linked list</h3>
<p>Traversing a linked list means iterating through the list, and we add the  <a target="_blank" href="https://docs.python.org/3/reference/datamodel.html#object.__iter__">iter function</a> to allow us to replicate the same behavior from regular lists (arrays)</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__iter__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>)</span></span>:
    node = <span class="hljs-keyword">self</span>.head
    <span class="hljs-keyword">while</span> node is <span class="hljs-keyword">not</span> <span class="hljs-symbol">None:</span>
        <span class="hljs-keyword">yield</span> node
        node = node.<span class="hljs-keyword">next</span>
</code></pre><p>The code above goes through the list if it does not equal to <code>None</code> and  <a target="_blank" href="https://docs.python.org/3/reference/simple_stmts.html#yield">yields</a> every node before re-assigning the node to the <code>next node</code> if it exists.</p>
<h3 id="insert-node-at-the-beginning">Insert node at the beginning</h3>
<pre><code><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_at_beginning</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, node)</span></span>:
    node.<span class="hljs-keyword">next</span> = <span class="hljs-keyword">self</span>.head
    <span class="hljs-keyword">self</span>.head = node
</code></pre><p>In the above code, you're setting the next value to the present head value before re-assigning head to the new node</p>
<h3 id="insert-node-at-the-end">Insert node at the end</h3>
<pre><code><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_at_end</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, node)</span></span>:
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.head is <span class="hljs-symbol">None:</span>
        <span class="hljs-keyword">self</span>.head = node
        <span class="hljs-keyword">return</span>
    <span class="hljs-keyword">for</span> current <span class="hljs-keyword">in</span> <span class="hljs-symbol">self:</span>
        pass
    current.<span class="hljs-keyword">next</span> = node
</code></pre><p>While inserting at the end is similar to inserting at the beginning, first, you want to traverse the whole list until you reach the end. Next, you want to set <code>current</code> as the last node on the list. Finally, you want to add the new node as the next value of that <code>current</code>.</p>
<h4 id="our-final-code-containing-our-methods-should-look-like-this">Our final code containing our methods should look like this</h4>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, data)</span></span>:
        <span class="hljs-keyword">self</span>.data = data
        <span class="hljs-keyword">self</span>.<span class="hljs-keyword">next</span> = None

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__repr__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>)</span></span>:
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">self</span>.data

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinkedList</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, nodes=None)</span></span>:
        <span class="hljs-keyword">self</span>.head = None
        <span class="hljs-keyword">if</span> nodes is <span class="hljs-keyword">not</span> <span class="hljs-symbol">None:</span>
            node = Node(data=nodes.pop(<span class="hljs-number">0</span>))
            <span class="hljs-keyword">self</span>.head = node
            <span class="hljs-keyword">for</span> elem <span class="hljs-keyword">in</span> <span class="hljs-symbol">nodes:</span>
                node.<span class="hljs-keyword">next</span> = Node(data=elem)
                node = node.<span class="hljs-keyword">next</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__repr__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>)</span></span>:
        node = <span class="hljs-keyword">self</span>.head
        nodes = []
        <span class="hljs-keyword">while</span> node is <span class="hljs-keyword">not</span> <span class="hljs-symbol">None:</span>
            nodes.append(node.data)
            node = node.<span class="hljs-keyword">next</span>
        nodes.append(<span class="hljs-string">"None"</span>)
        <span class="hljs-keyword">return</span> <span class="hljs-string">" -&gt; "</span>.join(nodes)

    <span class="hljs-comment"># Traverse a Linked List</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__iter__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>)</span></span>:
        node = <span class="hljs-keyword">self</span>.head
        <span class="hljs-keyword">while</span> node is <span class="hljs-keyword">not</span> <span class="hljs-symbol">None:</span>
            <span class="hljs-keyword">yield</span> node
            node = node.<span class="hljs-keyword">next</span>

    <span class="hljs-comment"># Insert a new node at the beginning</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_at_beginning</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, node)</span></span>:
        node.<span class="hljs-keyword">next</span> = <span class="hljs-keyword">self</span>.head
        <span class="hljs-keyword">self</span>.head = node

    <span class="hljs-comment"># Insert a new node at the end</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_at_end</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, node)</span></span>:
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.head is <span class="hljs-symbol">None:</span>
            <span class="hljs-keyword">self</span>.head = node
            <span class="hljs-keyword">return</span>
        <span class="hljs-keyword">for</span> current_node <span class="hljs-keyword">in</span> <span class="hljs-symbol">self:</span>
            pass
        current_node.<span class="hljs-keyword">next</span> = node
</code></pre><p> To wrap up a final example, have a look at how it works:</p>
<pre><code>my_list = LinkedList()
firstNode = Node(<span class="hljs-string">"1"</span>)
secondNode = Node(<span class="hljs-string">"2"</span>)
my_list .head = firstNode
firstNode.next = secondNode
my_list.add_at_beginning(Node(<span class="hljs-string">"3"</span>))
my_list.add_at_end(Node(<span class="hljs-string">"4"</span>))
print(my_list)

&gt;&gt;&gt;  <span class="hljs-number">3</span> -&gt; <span class="hljs-number">1</span> -&gt; <span class="hljs-number">2</span> -&gt; <span class="hljs-number">4</span> -&gt; <span class="hljs-literal">None</span>
</code></pre><h2 id="conclusion">Conclusion</h2>
<p>In this article, you learned quite a few things, The most important are:</p>
<ul>
<li>What linked lists are</li>
<li>What the other types of linked lists are</li>
<li>Time and Space Complexities of a linked list</li>
<li>How to implement your own linked list and node classes, plus relevant methods</li>
</ul>
<p>I hope you enjoyed reading it as much as I enjoyed writing it :)</p>
<p> <a target="_blank" href="https://abdulqudus.com">Learn more about me</a>  </p>
]]></content:encoded></item><item><title><![CDATA[Fetching data in React: Quick guide]]></title><description><![CDATA[Dog Fetching Stick (Cred: Pixabay)
Fetching data from an API either from an external source or from the Backend of your application can be done in many ways.
In this Quick guide, I would show you how to fetch data in a react app by making an HTTP req...]]></description><link>https://blog.abdulqudus.com/fetching-data-in-react-quick-guide-2a25e276a18a</link><guid isPermaLink="true">https://blog.abdulqudus.com/fetching-data-in-react-quick-guide-2a25e276a18a</guid><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Wed, 26 May 2021 12:37:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537191727/xFRxxj_gb.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dog Fetching Stick (Cred: Pixabay)</p>
<p>Fetching data from an API either from an external source or from the Backend of your application can be done in many ways.</p>
<p>In this Quick guide, I would show you how to fetch data in a react app by making an HTTP request to a REST API using 4 different patterns.</p>
<p>Before I begin, let’s have a refresher on what REST APIs are:</p>
<p><strong>What is a REST API?</strong></p>
<p>A <a target="_blank" href="https://restfulapi.net/">REST API</a> (also known as <strong>RESTful API</strong>) is an application programming interface (<strong>API</strong> or web <strong>API</strong>) that conforms to the constraints of <strong>REST</strong> architectural style and allows for interaction with <strong>RESTful</strong> web services. REST stands for “<strong>RE</strong>presentational <strong>S</strong>tate <strong>T</strong>ransfer”.</p>
<p>In this guide, we would be making use of the <a target="_blank" href="https://docs.github.com/en/rest">Github REST API</a> and its sample response looks like this:</p>
<pre><code class="lang-json">{
<span class="hljs-attr">"login"</span>: <span class="hljs-string">"jideabdqudus"</span>,
<span class="hljs-attr">"id"</span>: <span class="hljs-number">45945474</span>,
<span class="hljs-attr">"node_id"</span>: <span class="hljs-string">"MDQ6VXNlcjQ1OTQ1NDc0"</span>,
<span class="hljs-attr">"avatar_url"</span>: <span class="hljs-string">"https://avatars.githubusercontent.com/u/45945474?v=4"</span>,
<span class="hljs-attr">"gravatar_id"</span>: <span class="hljs-string">""</span>,
<span class="hljs-attr">"url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus"</span>,
<span class="hljs-attr">"html_url"</span>: <span class="hljs-string">"https://github.com/jideabdqudus"</span>,
<span class="hljs-attr">"followers_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/followers"</span>,
<span class="hljs-attr">"following_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/following{/other_user}"</span>,
<span class="hljs-attr">"gists_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/gists{/gist_id}"</span>,
<span class="hljs-attr">"starred_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/starred{/owner}{/repo}"</span>,
<span class="hljs-attr">"subscriptions_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/subscriptions"</span>,
<span class="hljs-attr">"organizations_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/orgs"</span>,
<span class="hljs-attr">"repos_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/repos"</span>,
<span class="hljs-attr">"events_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/events{/privacy}"</span>,
<span class="hljs-attr">"received_events_url"</span>: <span class="hljs-string">"https://api.github.com/users/jideabdqudus/received_events"</span>,
<span class="hljs-attr">"type"</span>: <span class="hljs-string">"User"</span>,
<span class="hljs-attr">"site_admin"</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">"name"</span>: <span class="hljs-string">"Jide Abdul-Qudus."</span>,
<span class="hljs-attr">"company"</span>: <span class="hljs-literal">null</span>,
<span class="hljs-attr">"blog"</span>: <span class="hljs-string">"www.abdulqudus.com"</span>,
<span class="hljs-attr">"location"</span>: <span class="hljs-string">"Lagos, Nigeria."</span>,
<span class="hljs-attr">"email"</span>: <span class="hljs-literal">null</span>,
<span class="hljs-attr">"hireable"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"bio"</span>: <span class="hljs-string">"Software Engineer."</span>,
<span class="hljs-attr">"twitter_username"</span>: <span class="hljs-literal">null</span>,
<span class="hljs-attr">"public_repos"</span>: <span class="hljs-number">57</span>,
<span class="hljs-attr">"public_gists"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"followers"</span>: <span class="hljs-number">12</span>,
<span class="hljs-attr">"following"</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">"created_at"</span>: <span class="hljs-string">"2018-12-17T15:57:35Z"</span>,
<span class="hljs-attr">"updated_at"</span>: <span class="hljs-string">"2021-04-06T20:48:07Z"</span>
}
</code></pre>
<p>Whenever a GET request is made to this (https://api.github.com/users/jideabdqudus) endpoint it returns this Javascript Object as its response &amp; we can decide to use this data in our application.</p>
<h2 id="fetching-data-using-the-fetch-api"><strong>Fetching data using the Fetch API</strong></h2>
<p>The <strong>Fetch API</strong> is an inbuilt JavaScript method for getting resources from a server or an API endpoint. It s a tool that’s built into most modern browsers on the window object (<code>window.fetch</code>) and enables us to make HTTP requests very easily using JavaScript promises.</p>
<p>To make a simple GET request with fetch we just need to include the URL endpoint which is a compulsory argument. It returns a promise that points to the response from the request. We want to make this request once our React component has mounted hence we would be making use of a Hook called useEffect for functional-based components <em>or componentDidMount for class-based components</em>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetch(<span class="hljs-string">"https://api.github.com/users/jideabdqudus"</span>)
      .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (response.ok) {
          <span class="hljs-keyword">return</span> response.json();
        }
        <span class="hljs-keyword">throw</span> response;
      })
      .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
        setData(data);
      })
      .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching data: "</span>, error);
        setError(error);
      })
      .finally(<span class="hljs-function">() =&gt;</span> {
        setLoading(<span class="hljs-literal">false</span>);
      });
  }, []);

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="hljs-string">"Error!"</span>;
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">textAlign:</span> "<span class="hljs-attr">center</span>" }}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{data.avatar_url}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Avatar"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"100"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Name: {data.name}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Bio: {data.bio}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Username: {data.login}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Location: {data.location}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Public Repos: {data.public_repos}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>In the code above, we have created a very simple functional component that makes a fetch request once the component gets mounted and sends back the response to us in the <em>data</em> state.</p>
<p>Within the <strong>useEffect </strong>we declare the API endpoint inside of our fetch function, the <code>.then()</code> callback, was used to see if the response was okay (<code>response.ok</code>). We call back a response as JSON data if the response is ok.</p>
<p>If it’s not an okay response, we assume there was an error making the request. Using fetch, for us to handle the errors, we throw <code>response</code> as an error for it to handled by our <code>catch</code> callback.</p>
<p>Here in our example, we are putting our error data in state with <code>setError</code>. If there's an error we return the text "Error!".</p>
<p>The <code>.finally()</code> callback is a function that is called when our promise has resolved successfully or not. In it, we set <code>loading</code> to false, so that we no longer see our loading text.</p>
<p>Instead we see either our data on the page if the request was made successfully, or that there was an error in making the request if not.</p>
<h2 id="how-to-fetch-data-in-react-using-axios">How to Fetch Data in React Using Axios</h2>
<p>The second pattern is by making use of Axios. Axios is an easy to use promise-based HTTP client for the browser and node.js. With Axios, we get the ability to intercept and cancel request, it also has a built-in feature that provides client-side protection against cross-site request forgery.</p>
<p>Axios is a React/Javascript library, so for us to use it in our app we would need to install it first.</p>
<pre><code>npm <span class="hljs-keyword">install</span> axios <span class="hljs-keyword">or</span> yarn <span class="hljs-keyword">add</span> axios
</code></pre><p>After which we import it at the top of the component that it would be used in. Making HTTP request with Axios is quite easy, and it’s one of the most popular ways of fetching data in React. We would be converting the previous Fetch example to an axios request.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>);
  useEffect(<span class="hljs-function">() =&gt;</span> {
    axios(<span class="hljs-string">"https://api.github.com/users/jideabdqudus"</span>)
      .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
        setData(response.data);
      })
      .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching data: "</span>, error);
        setError(error);
      })
      .finally(<span class="hljs-function">() =&gt;</span> {
        setLoading(<span class="hljs-literal">false</span>);
      });
  }, []);

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="hljs-string">"Error!"</span>;
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">textAlign:</span> "<span class="hljs-attr">center</span>" }}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{data.avatar_url}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Avatar"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"100"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Name: {data.name}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Bio: {data.bio}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Username: {data.login}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Location: {data.location}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Public Repos: {data.public_repos}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>What Axios enables us to do is to use the exact same promise syntax as fetch — but instead of using our first then callback to manually determine whether the response is okay and throw an error, Axios takes care of that for us.</p>
<h2 id="fetch-data-in-react-using-async-await-syntax">Fetch Data in React Using async / await syntax</h2>
<p>In ES7, it became possible to resolve promises using the <code>async / await</code> syntax. Async/await is a relatively new way to write asynchronous code in Javascript.</p>
<p>The benefit of this is that it enables us to remove our <code>.then()</code>, <code>.catch()</code>, and <code>.finally()</code> callbacks, promises andsimply get back our asynchronously resolved data as if we were writing synchronous code without promises altogether.</p>
<p>Why<strong> `</strong>async/await` ? Well, simply put, async/await allows us to write asynchronous code in a synchronous manner. The one thing you need to know about async functions is that; <strong>they always returns a promise</strong>.</p>
<p>We have to be aware of the fact that when we use <code>useEffect</code> the effect function (the first argument) cannot be made an <code>async</code> function.</p>
<p>To create an async function all we need to do is add the <code>async</code> keyword before the function definition, we would be converting our previous example to an async/await syntax:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>);
  useEffect(<span class="hljs-function">() =&gt;</span> {
    getData();
  }, []);

  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getData</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">await</span> axios(<span class="hljs-string">"https://api.github.com/users/jideabdqudus"</span>)
      .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
        setData(response.data);
      })
      .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching data: "</span>, error);
        setError(error);
      })
      .finally(<span class="hljs-function">() =&gt;</span> {
        setLoading(<span class="hljs-literal">false</span>);
      });
  }

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="hljs-string">"Error!"</span>;
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">textAlign:</span> "<span class="hljs-attr">center</span>" }}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{data.avatar_url}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Avatar"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"100"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Name: {data.name}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Bio: {data.bio}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Username: {data.login}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Location: {data.location}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Public Repos: {data.public_repos}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>In summary, <code>async/await</code> is a cleaner syntax to write asynchronous Javascript code. It enhances readability and flow of your code.</p>
<p>Things to keep in mind while using <code>async/await</code>:</p>
<ul>
<li><p>Async functions return a promise.</p>
</li>
<li><p>Await can only be used inside an async block.</p>
</li>
<li><p>Await waits until the function(“promise”) resolves or rejects.</p>
</li>
</ul>
<h2 id="how-to-fetch-data-in-react-using-a-custom-react-hook-usefetch">How to Fetch Data in React Using a Custom React Hook (useFetch)</h2>
<p>Over time, you may realize that it gets a bit tedious and time-consuming to keep writing the <em>useEffect</em> hook with all of its boilerplate within every component in which you want to fetch data.</p>
<p>To cut down on our reused code, we can use a custom hook as a special abstraction, which we can write ourselves from a third party library (like we are here, using the library <code>react-fetch-hook</code>).</p>
<p>useFetch is an isomorphic fetch hook. That means it works with SSR (server side rendering).</p>
<p>A custom hook that makes our HTTP request allows us to make our components much more concise. All we have to do is call our hook at the top of our component.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> useFetch <span class="hljs-keyword">from</span> <span class="hljs-string">"react-fetch-hook"</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { isLoading, error, data } = useFetch(<span class="hljs-string">"https://api.github.com/users/jideabdqudus"</span>);
  <span class="hljs-keyword">if</span> (isLoading) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="hljs-string">"Error!"</span>;

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">textAlign:</span> "<span class="hljs-attr">center</span>" }}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{data.avatar_url}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Avatar"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"100"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Name: {data.name}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Bio: {data.bio}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Username: {data.login}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Location: {data.location}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Public Repos: {data.public_repos}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>The 4 different patterns shown above are great ways of consuming APIs but fetch is mainly used when building relatively small applications and Axios/useFetch when building large applications for scalability reasons.</p>
<p>I hope you enjoyed reading this guide, I’ll be happy to answer any comment or questions you leave down below!</p>
<p>Check out more articles on my website: <a target="_blank" href="http://www.abdulqudus.com/blog">www.abdulqudus.com/blog</a></p>
]]></content:encoded></item><item><title><![CDATA[Lag Mobile App UI/UX Overview.]]></title><description><![CDATA[The Brief
The UI/UX of this app is concentrated on the experiences of users of the lag mobile app available on the google play store.
The App is a mobile application that helps to solve the problems experienced with navigating constantly through the ...]]></description><link>https://blog.abdulqudus.com/lag-mobile-app-460b479c6959</link><guid isPermaLink="true">https://blog.abdulqudus.com/lag-mobile-app-460b479c6959</guid><dc:creator><![CDATA[Jide Abdul-Qudus]]></dc:creator><pubDate>Fri, 10 Jan 2020 13:48:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537231581/l4UEx0ETM.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="the-brief"><strong>The Brief</strong></h2>
<p>The UI/UX of this app is concentrated on the experiences of users of the lag mobile app available on the google play store.</p>
<p>The App is a mobile application that helps to solve the problems experienced with navigating constantly through the school's website. It offers university students an opportunity to get first-hand information and access to there database/portal.</p>
<h2 id="project-brief">Project Brief</h2>
<p>An interactive mobile application prototype that can solve the problem of searching, navigating, downloading and filtering information in a convenient way and analyze the UI/UX progress through iterations all along the design process through proper <a target="_blank" href="https://www.interaction-design.org/literature/topics/design-thinking">design thinking</a> strategies.</p>
<h2 id="the-design-process">The Design Process</h2>
<p>As this work serves as a personal project and away from my normal core software programming, I thought to create a good UX strategy based on knowledge sought around.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537199325/8jdtFthzi.png" alt /></p>
<h2 id="interviewsreviews">Interviews/Reviews</h2>
<p>To start this process I took reviews from students, coworkers, and end-users of the application to understand important areas that needed to be worked on.</p>
<p>Based on the survey and interview research, the results indicated that:</p>
<ul>
<li><p>Users want options for updating data</p>
</li>
<li><p>Users want to have time to use</p>
</li>
<li><p>Users want flexibility in making payments</p>
</li>
<li><p>Users want real-time information feed.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537201603/y2m7sowzD.png" alt="Google play store review" /><em>Google play store review</em></p>
<h2 id="affinity-mapping">Affinity Mapping</h2>
<p>Subsequently, I started identifying the user’s preferences and pain-points. Once I did that, I wrote them down and grouped them in an affinity map which helped me pinpoint recurrent themes and issues. I selected the most recurrent themes or problems from the reviews to be the focal points of the mobile application.</p>
<h2 id="user-flow">User flow</h2>
<p>Before wireframing and creating a high-fidelity prototype, I decided to create a simple user flow in Figma. With this, I was able to better understand how the user would interact with the app to perform the tasks needed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537204693/CVHsU5hSZ.png" alt /></p>
<h2 id="low-fidelity-wireframes">Low-Fidelity Wireframes</h2>
<p>Right after finishing the User Flow, I was ready to start prototyping my low fidelity wireframes of the app on paper.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537207387/8_CMbtbZQ.png" alt /></p>
<h2 id="visual-designprototype">Visual Design/Prototype</h2>
<p>For this part of the process, I was able to transform the paper frameworks into high-fidelity prototypes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537210758/yJJoMMI9Y.jpeg" alt /></p>
<h2 id="high-fidelity-prototype">High-fidelity prototype</h2>
<p>User guide into the High-fidelity prototype, with a thorough look at the functions/pathways.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537213185/mqDF12lTH.jpeg" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537217834/-LXdQpg1g.jpeg" alt /></p>
<h2 id="conclusion">Conclusion.</h2>
<p>Working on this project has been a great experience and I have learned about the user-centered design process in great detail. Understanding the UX process through a user-centered lens allows for designing apps/websites with the user in mind by understanding the motivations and desires of each user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537221808/YjkmNgGRX.png" alt="Present google play store app VS My new design" /><em>Present google play store app VS My new design</em></p>
<h2 id="readers-feedback">Readers feedback</h2>
<p>After reading several UX case studies, seeking to find the perfect methodology, I realized that nobody’s project reaches perfection and I’m pretty sure that mine is not the exception.</p>
<p>For this reason, I’d really really love to have feedback from you guys whether it is on my methodology, my writing or any other thing you think I should improve.</p>
<p>Thanks a lot in advance for the feedback and for your reading!</p>
<p>I’ll leave you with extra images from the project :)</p>
<p><strong><em>Please clap, comment and share.</em></strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537223998/Fx2VuRgcZ.jpeg" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537226297/B2kizL-WF.jpeg" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631537228865/phnIStaIC.jpeg" alt /></p>
<p>Read my articles and more about me:
➡ <a target="_blank" href="https://blog.abdulqudus.com">https://blog.abdulqudus.com</a></p>
<p>Visit my web portfolio</p>
<p><a target="_blank" href="https://abdulqudus.com">abdulqudus.com</a></p>
]]></content:encoded></item></channel></rss>