<?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[The Rust Guy]]></title><description><![CDATA[Production Rust, no fluff. Architecture patterns, SaaS lessons, and building-in-public stories from a Nigerian systems engineer.]]></description><link>https://therustguy.com</link><image><url>https://cdn.hashnode.com/uploads/logos/5eafb1cbf89d4c762e706520/41f0cdda-d239-4675-b603-e88dd9e519cd.png</url><title>The Rust Guy</title><link>https://therustguy.com</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 30 Apr 2026 12:15:49 GMT</lastBuildDate><atom:link href="https://therustguy.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building Production-Ready Multi-Tenant SaaS in Rust with Actix-web]]></title><description><![CDATA[I've been building SmartFarmAI, an AI-powered poultry farm management platform, and one of the hardest architectural decisions I had to make early on was: how do I safely isolate data between farms?
W]]></description><link>https://therustguy.com/building-production-ready-multi-tenant-saas-in-rust-with-actix-web</link><guid isPermaLink="true">https://therustguy.com/building-production-ready-multi-tenant-saas-in-rust-with-actix-web</guid><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Sun, 15 Mar 2026 02:17:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/5eafb1cbf89d4c762e706520/a05f09f4-2f7e-4802-bc92-3c066d86c13b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I've been building <a href="https://smartfarmai.ng/">SmartFarmAI</a>, an AI-powered poultry farm management platform, and one of the hardest architectural decisions I had to make early on was: <strong>how do I safely isolate data between farms?</strong></p>
<p>When a farmer in Lagos logs in and checks their egg production numbers, they should never under any circumstance see data from a 60,000-bird enterprise operation in Tanzania. One bug, one missed <code>WHERE</code> clause, and you're leaking customer data. In agriculture, that's not just a privacy issue it's a business-ending trust violation.</p>
<p>This article walks through exactly how I solved this using <strong>Rust, Actix-web, and PostgreSQL Row-Level Security (RLS)</strong> the patterns, the gotchas I hit in production, and the code that keeps it all safe.</p>
<p>If you're building any kind of multi-tenant SaaS in Rust, this should save you weeks of trial and error.</p>
<p><em><strong>The pattern in a nutshell:</strong></em> <em>Actix middleware extracts the tenant from each request, starts a DB transaction, calls</em> <code>SET LOCAL app.current_tenant_id</code><em>, and lets Postgres RLS policies automatically scope every query no manual</em> <code>WHERE org_id = $1</code> <em>needed.</em></p>
<p><em>This article assumes you're comfortable with Rust basics, Actix-web routing, and have at least heard of PostgreSQL Row-Level Security. If you've never touched RLS before, you'll still be able to follow along I introduce the concepts as we go.</em></p>
<h2>Multi-Tenancy: Pick Your Strategy</h2>
<p>Before writing any code, you have to decide how to isolate tenant data. There are three common approaches:</p>
<img src="https://cdn.hashnode.com/uploads/covers/5eafb1cbf89d4c762e706520/80eb15ca-c043-46c2-aafb-189dd76ad45c.png" alt=" Database-per-Tenant: Architecture diagram illustrating the database-per-tenant multi-tenancy pattern and its operational challenges. A central PostgreSQL cluster connects to many separate databases, DB Tenant 1 through DB Tenant 6 and beyond to 100+, each represented as individual database icons spreading across the top of the diagram. Red arrows on the left depict a management and migration nightmare, showing how update scripts must be rolled out individually to every tenant database with clock icons indicating time delays. Green arrows on the right show the benefit of maximum isolation, with each tenant receiving completely separate data access. The bottom notes that this approach requires Docker/K8s at scale, complex Prometheus/Grafana monitoring, and coordinated Redis migration tooling for rollouts." style="display:block;margin:0 auto" />

<p><strong>Database-per-tenant</strong>: Every customer gets their own PostgreSQL database. Maximum isolation, but a nightmare to manage at scale. Migrations become a coordinated rollout across hundreds of databases.</p>
<img src="https://cdn.hashnode.com/uploads/covers/5eafb1cbf89d4c762e706520/36cb5c98-2f6a-4c70-99b3-7e66f2092113.png" alt="Schema-per-Tenant: Architecture diagram showing the schema-per-tenant multi-tenancy pattern as a middle ground between shared database and database-per-tenant approaches. A single PostgreSQL instance contains multiple colored schema segments. Schema Tenant 1, Schema Tenant 2, through Schema 100+ represented as pie-slice sections within one database. Red arrows on the left illustrate schema migration pain at scale, as each schema requires individual migration rollout. The top right shows a tangled knot of lines representing connection pooling complexity as the number of schemas grows. Green arrows on the right show isolated data access per tenant. The bottom notes Docker/K8s scaling is better than database-per-tenant, but still requires complex monitoring and coordinated rollout tooling." style="display:block;margin:0 auto" />

<p><strong>Schema-per-tenant</strong>: One database, but each customer gets their own schema. Better than separate databases, but schema migrations are still painful and connection pooling gets complicated fast.</p>
<img src="https://cdn.hashnode.com/uploads/covers/5eafb1cbf89d4c762e706520/652e95d6-4ecd-438f-a7a6-a89e90ecd6a9.png" alt="Shared Database with RLS: &quot;Architecture diagram showing SmartFarmAI's shared database multi-tenancy approach using PostgreSQL Row-Level Security. A single PostgreSQL instance contains shared tables (Users, Data_Streams) where each row includes a tenant_id column. Green arrows show how RLS policies filter data so Tenant A (farmer A) and Tenant B (farmer B) each only access their own rows through simple connection pooling with one shared pool. The left side highlights benefits: simple schema migration with one script for all tenants. The bottom shows supporting infrastructure including Docker/K8s for scalability, Prometheus/Grafana for observability, and Redis for async tasks. The diagram emphasizes simplicity at scale with robust security." style="display:block;margin:0 auto" />

<p><strong>Shared database with Row-Level Security</strong>: One database, one schema, one set of tables but PostgreSQL itself enforces which rows each tenant can see. This is what I chose for SmartFarmAI.</p>
<p>Why RLS? Because it pushes security enforcement down to the database layer. My application code doesn't need to remember to add <code>WHERE org_id = $1</code> to every query. PostgreSQL does it automatically. If I forget a filter in my Rust code? Doesn't matter the database won't return rows that don't belong to the current tenant.</p>
<p>For an early-stage SaaS serving poultry farmers, this gives me the isolation guarantees I need without the operational overhead of managing hundreds of databases.</p>
<h2>The Data Model: org_id Everywhere</h2>
<p>SmartFarmAI's domain hierarchy looks like this:</p>
<pre><code class="language-plaintext">Organization (tenant)
  └── Farm(s)
       └── Batch(es) / Pen House(s)
            └── Egg Records, Mortality Logs, Vaccination Schedules...
</code></pre>
<p>The key decision: <strong>every table carries</strong> <code>org_id</code>, even child tables. You might think "batches already belong to a farm, and farms belong to an org why duplicate <code>org_id</code> on the batch table?" Two reasons:</p>
<ol>
<li><p><strong>RLS policies need a direct column reference.</strong> PostgreSQL can't follow foreign key chains in a policy expression. The policy needs to see <code>org_id</code> on the row it's evaluating.</p>
</li>
<li><p><strong>Composite foreign keys enforce correctness.</strong> A batch doesn't just reference a <code>farm_id</code> it references <code>(org_id, farm_id)</code>. This makes it structurally impossible to accidentally associate a batch with a farm from a different organization.</p>
</li>
</ol>
<p>Here's what the schema looks like:</p>
<pre><code class="language-sql">-- Organizations (tenants)
CREATE TABLE organizations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Farms belong to an organization
CREATE TABLE farms (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    org_id UUID NOT NULL REFERENCES organizations(id),
    name TEXT NOT NULL,
    location TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    -- Composite unique for child FK references
    UNIQUE (org_id, id)
);

-- Batches belong to a farm, scoped by org
CREATE TABLE batches (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    org_id UUID NOT NULL,
    farm_id UUID NOT NULL,
    batch_name TEXT NOT NULL,
    bird_count INTEGER NOT NULL DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    -- Composite FK: can't assign a batch to a farm in a different org
    CONSTRAINT batch_farm_fk
        FOREIGN KEY (org_id, farm_id)
        REFERENCES farms (org_id, id)
        ON DELETE CASCADE,

    UNIQUE (org_id, farm_id, id)
);

-- Egg production records
CREATE TABLE egg_production_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    org_id UUID NOT NULL,
    farm_id UUID NOT NULL,
    batch_id UUID NOT NULL,
    record_date DATE NOT NULL DEFAULT CURRENT_DATE,
    eggs_collected INTEGER NOT NULL CHECK (eggs_collected &gt;= 0),
    notes TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT egg_log_batch_fk
        FOREIGN KEY (org_id, farm_id, batch_id)
        REFERENCES batches (org_id, farm_id, id)
        ON DELETE CASCADE,

    -- One record per batch per day
    CONSTRAINT unique_egg_record UNIQUE (batch_id, record_date)
);
</code></pre>
<p>Notice the pattern: every child table has a composite foreign key that threads <code>org_id</code> all the way down. This is intentional. It's one of those things that feels redundant until it saves you from a data leak.</p>
<h2>Enabling Row-Level Security</h2>
<p>With the schema in place, enabling RLS is straightforward:</p>
<pre><code class="language-sql">-- Enable RLS on all tenant-scoped tables
ALTER TABLE farms ENABLE ROW LEVEL SECURITY;
ALTER TABLE batches ENABLE ROW LEVEL SECURITY;
ALTER TABLE egg_production_logs ENABLE ROW LEVEL SECURITY;

-- Create isolation policies
CREATE POLICY tenant_isolation ON farms
    USING (org_id = current_setting('app.current_tenant_id')::uuid);

CREATE POLICY tenant_isolation ON batches
    USING (org_id = current_setting('app.current_tenant_id')::uuid);

CREATE POLICY tenant_isolation ON egg_production_logs
    USING (org_id = current_setting('app.current_tenant_id')::uuid);

-- WITH CHECK ensures inserts/updates also respect the tenant boundary
CREATE POLICY tenant_write_isolation ON farms
    FOR INSERT
    WITH CHECK (org_id = current_setting('app.current_tenant_id')::uuid);

CREATE POLICY tenant_write_isolation ON batches
    FOR INSERT
    WITH CHECK (org_id = current_setting('app.current_tenant_id')::uuid);

CREATE POLICY tenant_write_isolation ON egg_production_logs
    FOR INSERT
    WITH CHECK (org_id = current_setting('app.current_tenant_id')::uuid);
</code></pre>
<p>The magic here is <code>current_setting('app.current_tenant_id')</code>. This is a PostgreSQL session variable not a table, not a function, just a key-value pair that lives for the duration of a transaction or session. Before any query runs, we set this variable to the current user's organization ID. PostgreSQL's RLS engine then uses it to filter every <code>SELECT</code>, <code>INSERT</code>, <code>UPDATE</code>, and <code>DELETE</code>.</p>
<p><strong>Important</strong>: RLS policies are enforced for regular users but <strong>not for the table owner or superusers</strong>. Make sure your application connects as a non-superuser role.</p>
<h2>The Middleware: Setting Tenant Context in Actix-web</h2>
<p>This is where Rust and Actix-web come in. Every authenticated request needs to:</p>
<ol>
<li><p>Extract the tenant ID (from JWT claims)</p>
</li>
<li><p>Set the PostgreSQL session variable before any query runs</p>
</li>
<li><p>Ensure the variable is cleared when the request ends</p>
</li>
</ol>
<p>Here's how I built it:</p>
<h3>The TenantId Extractor</h3>
<p>First, a newtype for tenant IDs. This prevents accidentally passing a user ID where an org ID is expected Rust's type system catches it at compile time.</p>
<pre><code class="language-rust">use uuid::Uuid;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct TenantId(Uuid);

impl TenantId {
    pub fn new(id: Uuid) -&gt; Self {
        Self(id)
    }

    pub fn as_uuid(&amp;self) -&gt; &amp;Uuid {
        &amp;self.0
    }
}

impl std::fmt::Display for TenantId {
    fn fmt(&amp;self, f: &amp;mut std::fmt::Formatter&lt;'_&gt;) -&gt; std::fmt::Result {
        write!(f, "{}", self.0)
    }
}
</code></pre>
<h3>Extracting Tenant from JWT</h3>
<p>In Actix-web, you can implement <code>FromRequest</code> to automatically extract the tenant ID from the JWT on every request:</p>
<pre><code class="language-rust">use actix_web::{FromRequest, HttpRequest, dev::Payload, Error, HttpMessage};
use std::future::{Ready, ready};

impl FromRequest for TenantId {
    type Error = Error;
    type Future = Ready&lt;Result&lt;Self, Self::Error&gt;&gt;;

    fn from_request(req: &amp;HttpRequest, _payload: &amp;mut Payload) -&gt; Self::Future {
        // The auth middleware has already validated the JWT
        // and inserted claims into request extensions
        match req.extensions().get::&lt;AuthClaims&gt;() {
            Some(claims) =&gt; ready(Ok(TenantId::new(claims.org_id))),
            None =&gt; ready(Err(actix_web::error::ErrorUnauthorized(
                "Missing tenant context"
            ))),
        }
    }
}
</code></pre>
<h3>The RLS Middleware</h3>
<p>Now the critical piece the middleware that sets <code>app.current_tenant_id</code> before your handler runs:</p>
<pre><code class="language-rust">use actix_web::{dev::ServiceRequest, Error, HttpMessage};
use sqlx::PgPool;

pub async fn set_rls_context(
    pool: &amp;PgPool,
    org_id: &amp;TenantId,
) -&gt; Result&lt;sqlx::Transaction&lt;'_, sqlx::Postgres&gt;, Error&gt; {
    let mut tx = pool.begin().await.map_err(|e| {
        actix_web::error::ErrorInternalServerError(format!("DB error: {}", e))
    })?;

    // SET LOCAL scopes the variable to this transaction only
    sqlx::query("SELECT set_config('app.current_tenant_id', $1, true)")
        .bind(org_id.to_string())
        .execute(&amp;mut *tx)
        .await
        .map_err(|e| {
            actix_web::error::ErrorInternalServerError(format!("RLS context error: {}", e))
        })?;

    Ok(tx)
}
</code></pre>
<p>The critical detail here is the third argument to <code>set_config</code>: <code>true</code> <strong>means transaction-local</strong>. When the transaction commits or rolls back, the variable is automatically cleared. This is essential for connection pool safety more on that below.</p>
<h3>Using It in Handlers</h3>
<p>With the extractor and the RLS context function, your route handlers look clean:</p>
<pre><code class="language-rust">use actix_web::{web, HttpResponse, Result};
use sqlx::PgPool;

pub async fn get_farms(
    pool: web::Data&lt;PgPool&gt;,
    tenant: TenantId,
) -&gt; Result&lt;HttpResponse&gt; {
    let mut tx = set_rls_context(&amp;pool, &amp;tenant).await?;

    // No WHERE clause needed — RLS handles filtering
    let farms = sqlx::query_as!(
        Farm,
        "SELECT id, org_id, name, location, created_at FROM farms"
    )
    .fetch_all(&amp;mut *tx)
    .await
    .map_err(actix_web::error::ErrorInternalServerError)?;

    tx.commit().await
        .map_err(actix_web::error::ErrorInternalServerError)?;

    Ok(HttpResponse::Ok().json(farms))
}
</code></pre>
<p>Notice: <strong>no</strong> <code>WHERE org_id = $1</code>. The query selects all farms, but RLS ensures the farmer in Lagos only sees their own farms. The 60,000-bird operation in Tanzania is invisible to them at the database level.</p>
<h2>The Gotcha That Almost Burned Me: Connection Pools and Session Variables</h2>
<p>Here's the mistake that will bite you if you're not careful.</p>
<p>PostgreSQL session variables persist for the lifetime of a connection. When you use a connection pool (like sqlx's <code>PgPool</code>), connections are reused across requests. If you set <code>app.current_tenant_id</code> with session scope (<code>false</code> as the third argument to <code>set_config</code>), here's what happens:</p>
<pre><code class="language-plaintext">1. Request from Org-A arrives
2. Connection #5 is checked out from the pool
3. SET app.current_tenant_id = 'org-a-uuid'  (session-scoped)
4. Query runs, returns Org-A's data ✅
5. Connection #5 is returned to the pool

6. Request from Org-B arrives
7. Connection #5 is checked out again
8. But app.current_tenant_id is STILL 'org-a-uuid' !!
9. Query runs... returns Org-A's data to Org-B's user 🚨
</code></pre>
<p><strong>This is a data leak.</strong> And it's subtle it depends on which connection the pool hands out, so it won't happen consistently in development. It'll show up in production under load.</p>
<p>The fix: <strong>always use transaction-local scope.</strong></p>
<pre><code class="language-rust">// ✅ SAFE: Transaction-local — cleared automatically when tx ends
sqlx::query("SELECT set_config('app.current_tenant_id', $1, true)")
    .bind(org_id.to_string())
    .execute(&amp;mut *tx)
    .await?;

// ❌ DANGEROUS: Session-local — persists after connection returns to pool
sqlx::query("SELECT set_config('app.current_tenant_id', $1, false)")
    .bind(org_id.to_string())
    .execute(&amp;pool)
    .await?;
</code></pre>
<p>By wrapping every tenant-scoped operation in a transaction and using <code>set_config(..., true)</code>, the variable is automatically cleaned up when the transaction ends. No stale tenant context, no data leaks.</p>
<h2>When NOT to Use RLS: Background Workers and the Outbox Pattern</h2>
<p>SmartFarmAI uses an outbox pattern for event-driven processing. When a farmer logs egg production, the API handler inserts the record and publishes a domain event to an <code>outbox_events</code> table all in the same transaction. A background worker then picks up events and processes them (updating batch totals, triggering AI predictions, etc.).</p>
<p>Here's the thing: <strong>the outbox table should NOT have RLS enabled.</strong></p>
<p>Why? The background worker needs to poll for events across all organizations:</p>
<pre><code class="language-sql">SELECT * FROM outbox_events
WHERE processed_at IS NULL
ORDER BY created_at ASC
LIMIT 10
FOR UPDATE SKIP LOCKED;
</code></pre>
<p>If RLS were enabled on this table, the worker would need a tenant context to read events but it doesn't belong to any tenant. It's infrastructure.</p>
<p>My rule of thumb:</p>
<table>
<thead>
<tr>
<th>Table Type</th>
<th>RLS?</th>
<th>Why</th>
</tr>
</thead>
<tbody><tr>
<td>Business data (farms, batches, eggs)</td>
<td>Yes</td>
<td>Tenant-scoped, must be isolated</td>
</tr>
<tr>
<td>Work queues (outbox_events, email_jobs)</td>
<td>No</td>
<td>Infrastructure, cross-tenant by design</td>
</tr>
<tr>
<td>Audit logs</td>
<td>Depends</td>
<td>RLS if tenant-facing, no RLS if admin-only</td>
</tr>
</tbody></table>
<p>But here's the nuance: when the worker processes an event and needs to update business data, it <strong>does</strong> need to set the RLS context for that specific event's organization:</p>
<pre><code class="language-rust">pub async fn process_event(
    &amp;self,
    pool: &amp;PgPool,
    event: &amp;OutboxEvent,
) -&gt; Result&lt;(), Box&lt;dyn std::error::Error&gt;&gt; {
    let mut tx = pool.begin().await?;

    // Set RLS context for this event's organization
    sqlx::query("SELECT set_config('app.current_tenant_id', $1, true)")
        .bind(event.org_id.to_string())
        .execute(&amp;mut *tx)
        .await?;

    // Now we can safely update tenant-scoped tables
    match event.topic.as_str() {
        "EggProductionRecorded" =&gt; {
            self.update_batch_totals(&amp;mut tx, event).await?;
        }
        "MortalityRecorded" =&gt; {
            self.update_mortality_stats(&amp;mut tx, event).await?;
        }
        _ =&gt; {}
    }

    // Mark event as processed
    sqlx::query!(
        "UPDATE outbox_events SET processed_at = NOW() WHERE id = $1",
        event.id
    )
    .execute(&amp;mut *tx)
    .await?;

    tx.commit().await?;
    Ok(())
}
</code></pre>
<p>This is the pattern that took me the longest to get right. The worker reads from an unprotected queue, then enters a tenant context per-event to do the actual work. Each event is processed in its own transaction with its own RLS scope.</p>
<p>I actually hit a bug in production where my outbox table initially had RLS enabled. The worker was fetching zero events even though the table had hundreds queued up. No errors just silent filtering. It took me an embarrassing amount of debugging before I realised the worker had no tenant context set, so RLS was filtering out everything.</p>
<h2>Testing Multi-Tenant Isolation</h2>
<p>Testing RLS requires more thought than testing regular business logic. You need to verify that tenants genuinely can't see each other's data:</p>
<pre><code class="language-rust">#[tokio::test]
async fn test_tenant_isolation() {
    let pool = setup_test_db().await;

    // Create two organizations
    let org_a = create_test_org(&amp;pool, "Farm Corp A").await;
    let org_b = create_test_org(&amp;pool, "Farm Corp B").await;

    // Create farms under each org (using superuser/direct insert)
    create_test_farm(&amp;pool, &amp;org_a, "Org A Farm").await;
    create_test_farm(&amp;pool, &amp;org_b, "Org B Farm").await;

    // Query as Org A — should only see their farm
    let mut tx = pool.begin().await.unwrap();
    sqlx::query("SELECT set_config('app.current_tenant_id', $1, true)")
        .bind(org_a.to_string())
        .execute(&amp;mut *tx)
        .await
        .unwrap();

    let farms: Vec&lt;Farm&gt; = sqlx::query_as!(Farm, "SELECT * FROM farms")
        .fetch_all(&amp;mut *tx)
        .await
        .unwrap();

    assert_eq!(farms.len(), 1);
    assert_eq!(farms[0].name, "Org A Farm");

    tx.commit().await.unwrap();

    // Query as Org B — should only see their farm
    let mut tx = pool.begin().await.unwrap();
    sqlx::query("SELECT set_config('app.current_tenant_id', $1, true)")
        .bind(org_b.to_string())
        .execute(&amp;mut *tx)
        .await
        .unwrap();

    let farms: Vec&lt;Farm&gt; = sqlx::query_as!(Farm, "SELECT * FROM farms")
        .fetch_all(&amp;mut *tx)
        .await
        .unwrap();

    assert_eq!(farms.len(), 1);
    assert_eq!(farms[0].name, "Org B Farm");

    tx.commit().await.unwrap();
}

#[tokio::test]
async fn test_cross_tenant_insert_blocked() {
    let pool = setup_test_db().await;

    let org_a = create_test_org(&amp;pool, "Org A").await;
    let org_b = create_test_org(&amp;pool, "Org B").await;

    // Set context as Org A, but try to insert with Org B's ID
    let mut tx = pool.begin().await.unwrap();
    sqlx::query("SELECT set_config('app.current_tenant_id', $1, true)")
        .bind(org_a.to_string())
        .execute(&amp;mut *tx)
        .await
        .unwrap();

    // This should be rejected by the WITH CHECK policy
    let result = sqlx::query!(
        "INSERT INTO farms (org_id, name) VALUES (\(1, \)2)",
        org_b.as_uuid(),  // Wrong org!
        "Sneaky Farm"
    )
    .execute(&amp;mut *tx)
    .await;

    assert!(result.is_err()); // RLS blocks it
}
</code></pre>
<p>These tests are non-negotiable. Run them in CI. They're the safety net that catches regressions before your farmers do.</p>
<h2>Production Lessons from SmartFarmAI</h2>
<p>After running this architecture in production with farms across Nigeria and Tanzania, here's what I've learned:</p>
<p><strong>1. RLS has near-zero performance overhead.</strong> PostgreSQL evaluates the policy as part of query planning. For simple equality checks like <code>org_id = current_setting(...)::uuid</code>, the optimiser handles it efficiently. I haven't needed to do anything special for performance.</p>
<p><strong>2. Always index</strong> <code>org_id</code><strong>.</strong> Even though RLS handles filtering, the database still needs to efficiently find matching rows. Composite indexes on <code>(org_id, ...)</code> are essential:</p>
<pre><code class="language-sql">CREATE INDEX idx_farms_org ON farms(org_id);
CREATE INDEX idx_batches_org_farm ON batches(org_id, farm_id);
CREATE INDEX idx_egg_logs_batch_date ON egg_production_logs(batch_id, record_date DESC);
</code></pre>
<p><strong>3. Migrations need care.</strong> When you run migrations, you're typically using a superuser or the table owner which bypasses RLS. This is fine and expected, but be aware of it. Don't write migration scripts that assume RLS is filtering data.</p>
<p><strong>4. Debug with</strong> <code>current_setting()</code><strong>.</strong> When something seems off, check what the database thinks the current tenant is:</p>
<pre><code class="language-sql">SELECT current_setting('app.current_tenant_id', true);
-- Returns NULL if not set, the tenant UUID if set
</code></pre>
<p>The second argument (<code>true</code>) tells PostgreSQL to return <code>NULL</code> instead of throwing an error if the variable isn't set. Extremely useful for debugging.</p>
<p><strong>5. The outbox worker issue is real.</strong> As I mentioned earlier if you enable RLS on infrastructure tables, your background workers will silently return zero results. No errors, no warnings. Set up monitoring for your outbox queue depth so you catch this fast.</p>
<h2>Wrapping Up</h2>
<p>Multi-tenant data isolation isn't the kind of thing you want to get "mostly right." It needs to be airtight. PostgreSQL's Row-Level Security, combined with Rust's type system and Actix-web's middleware patterns, gives you defense in depth:</p>
<ul>
<li><p><strong>Database layer</strong>: RLS policies enforce isolation regardless of application bugs.</p>
</li>
<li><p><strong>Application layer</strong>: Transaction-scoped <code>SET LOCAL</code> prevents connection pool contamination.</p>
</li>
</ul>
<p>SmartFarmAI currently manages farms ranging from 550 birds to 60,000 birds. Every single one of them shares the same database, the same tables, the same application code. And none of them can see each other's data.</p>
<p>If you're building multi-tenant SaaS in Rust, start with RLS. Push security as far down the stack as it will go. And let Rust's type system catch everything else.</p>
<hr />
<p><em>I'm Chinedu Okere I write about building production systems in Rust. If you're working on multi-tenant architecture or SaaS in Rust, I'd love to hear about your approach. Find me on</em> <a href="https://x.com/chinedu_10"><em>Twitter/X</em></a> <em>or check out</em> <a href="https://smartfarmai.ng/"><em>SmartFarmAI</em></a><em>.</em></p>
]]></content:encoded></item><item><title><![CDATA[Different ways to truncate text with CSS]]></title><description><![CDATA[CSS is fantastic; we all know that. It has many unique features that enable us to achieve incredible responsiveness on the web. Have you ever wondered how the ellipses (...) you see on some popular websites (as shown in the image below) are created?
...]]></description><link>https://therustguy.com/different-ways-to-truncate-text-with-css</link><guid isPermaLink="true">https://therustguy.com/different-ways-to-truncate-text-with-css</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[CSS]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Wed, 25 Oct 2023 00:39:34 GMT</pubDate><content:encoded><![CDATA[<p>CSS is fantastic; we all know that. It has many unique features that enable us to achieve <a target="_blank" href="https://blog.logrocket.com/new-css-style-queries/">incredible responsiveness on the web</a>. Have you ever wondered how the ellipses <code>(...)</code> you see on some popular websites (as shown in the image below) are created?</p>
<p>Well, in this article, we will explore how to achieve multi-line truncations in CSS using the language of <a target="_blank" href="https://logrocket.com/for/javascript">web JavaScript</a>. Let’s go!</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2023/01/truncate-text-css-example.png" alt="Truncated Text in CSS" /></p>
<h2 id="heading-what-is-truncation"><strong>What is truncation?</strong></h2>
<p>Truncating text in CSS means adding an ellipsis at the end of a sentence to indicate that there is more text to be read. Unfortunately, there isn’t any truncation property to truncate text on the fly when it comes to using CSS. So, how do you truncate text with CSS?</p>
<p>Fortunately, there is a mix of some <a target="_blank" href="https://blog.logrocket.com/deep-dive-css-individual-transform-properties/">CSS properties</a> that do the job. It’s worth noting that these properties only work when used together on an element or the words you have chosen to truncate.</p>
<h3 id="heading-css-properties"><strong>CSS properties</strong></h3>
<p>The following properties will help us truncate text in CSS:</p>
<ul>
<li><code>White-Space: nowrap;</code>: This property forces the words into a straight line and not wrap to the next line</li>
</ul>
<ul>
<li><code>Overflow: hidden;</code>: This property causes the words to be contained within their parent container</li>
</ul>
<ul>
<li><code>Text-overflow: ellipsis;</code>: This property adds an ellipsis at the end of the words</li>
</ul>
<p>We can create a single-line truncation when we use these three CSS properties together on any text. This method is considered the traditional way to truncate a sentence with CSS.</p>
<h2 id="heading-how-to-create-a-multi-line-truncation"><strong>How to create a multi-line truncation</strong></h2>
<p>Using CSS properties works fine for a single line of text and a multi-line text that spans more than two lines. However, this can also be achieved using <a target="_blank" href="https://blog.logrocket.com/16-useful-typescript-javascript-shorthands-know/">JavaScript</a>.</p>
<p>Now, we will look at the two techniques for multi-line truncation using CSS or JavaScript. That way, you can determine which technique works for you.</p>
<h3 id="heading-multi-line-text-truncation-with-css"><strong>Multi-line text truncation with CSS</strong></h3>
<p>So, let’s look at the CSS technique for a multi-line truncation. The first thing to do is to set the height of the box or the element itself. Next, we count the number of lines we want to ignore before truncating and then multiply the by the <code>line-height</code> to get the <code>max-height</code>.</p>
<p>Here’s how it’s done: <code>Max-height: calc(line-height * the number of the line we want to ignore);</code>.</p>
<p>We will set <code>Overflow</code> to <code>hidden</code>. We will also set <code>max-height</code> to our preferred height, the same as <code>line-height</code>.</p>
<p>Then, we have the <code>-webkit-box-orient</code> which we set to <code>vertical</code>, <code>-webkit-line-clamp</code>, and <code>text-overflow</code> which we set to <code>ellipsis</code>. We will also set the <code>display</code> to <code>box</code>:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.paragraph</span> {
  <span class="hljs-attribute">Overflow</span>:hidden;
  <span class="hljs-attribute">max-height</span>: <span class="hljs-number">6rem</span>;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">2.5rem</span>;
  <span class="hljs-attribute">-webkit-box-orient</span>: vertical;
  <span class="hljs-attribute">-webkit-line-clamp</span>: <span class="hljs-number">5</span>;
  <span class="hljs-attribute">text-overflow</span>: ellipsis;
  <span class="hljs-attribute">display</span>: block;
}
</code></pre>
<h3 id="heading-using-javascript-to-truncate"><strong>Using JavaScript to truncate</strong></h3>
<p>Next, let’s look at how we can achieve this using JavaScript. First, let’s create a function called <code>truncate</code> and pass in the words to be truncated as parameters. We will also give a <code>max-length Parameter</code>:</p>
<pre><code class="lang-javascript">Const truncate (words, maxlength)=&gt;{}
</code></pre>
<p>Now, we are going to use the <a target="_blank" href="https://blog.logrocket.com/using-javascript-at-method/#:~:text=Learn%20more%20%E2%86%92-,The%20slice()%20method,-Developers%20can%20also"><code>slice</code></a> method to truncate our text, and we will also return our truncated text from within our <code>truncate</code> function.</p>
<blockquote>
<p><em>Note: We will give the</em> <code>slice</code> method an initial value of zero <code>(0)</code> because we will have to truncate from the beginning of words to the specified area where we wish to stop:</p>
</blockquote>
<pre><code class="lang-javascript">Const truncate (words, maxlength)=&gt;{
<span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${words.slice(<span class="hljs-number">0</span>, maxlength)}</span> …`</span>
}
</code></pre>
<p>Next, for the last and final step, let’s wrap it up by passing the <code>words</code> and the <code>maxlength</code> as arguments:</p>
<pre><code class="lang-javascript">Const words = <span class="hljs-string">"You are learning text truncation with javascript which is done with these three steps"</span> 

Const truncate (words, maxlength)=&gt;{
<span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${words.slice(<span class="hljs-number">0</span>, maxlength)}</span> …`</span>
}


truncate(words, <span class="hljs-number">20</span>)
</code></pre>
<p>In this case, the <code>maxLength</code> handles a particular edge case for a situation where the string we want to truncate isn’t long enough to be truncated.</p>
<p>Here, we want to return the original string without truncating it. However, in a situation where this condition is satisfied, we want to truncate and add the ellipsis at the end of the string.</p>
<h2 id="heading-adding-an-element-after-the-ellipsis"><strong>Adding an element after the ellipsis</strong></h2>
<p>In some situations, I have found myself wanting to add an element such as an <a target="_blank" href="https://blog.logrocket.com/7-popular-icon-libraries-you-can-use-for-free/">icon</a> after the ellipsis. But, when the line becomes too long, the element is truncated with the ellipsis. The challenge here is getting the element to stay after the ellipsis.</p>
<p>So, how do we add the element after the ellipsis? Let’s say we have the below HTML:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"parent-box box"</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"child-box"</span>&gt;</span> 
        You are learning text truncation with javascript which is done with these three steps 
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</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">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"parent-box box"</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"child-box no-max-width"</span>&gt;</span> 
        You are learning text truncation with javascript which is done with these three steps 
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>In other to achieve this, we set the <a target="_blank" href="https://blog.logrocket.com/css-before-after-custom-animations-transitions/"><code>::after</code> pseudo-element</a> to the parent element <code>.box</code>. Then, we set the <code>nest</code> div with class <code>.child-box</code> and give it a display of <code>inline-block</code>. This allows the pseudo-element of the <code>.parent-box</code> to come after the width of the <code>.child-box</code>.</p>
<p>If the defined <code>max-width</code> is exceeded, then the <code>overflow</code> set to <code>hidden</code> comes into play. This enables us to have the <code>ellipsis</code> and the element of the <code>.parent-box</code> if there is a <code>text-overflow</code>.</p>
<blockquote>
<p><em>Note: The trick here is to not declare the pseudo-element to an element that we declared</em> <code>overflow</code> and <code>width</code> on. This should be done to the parent element, which will, at some point, trim out the content once the max-width is reached:</p>
</blockquote>
<pre><code class="lang-css"><span class="hljs-selector-class">.parent-box</span> <span class="hljs-selector-class">.child-box</span> { 
    <span class="hljs-attribute">text-overflow</span>: ellipsis; 
    <span class="hljs-attribute">display</span>: inline-block; 
    <span class="hljs-attribute">max-width</span>: <span class="hljs-number">70%</span>; 
    <span class="hljs-attribute">width</span>: auto; 
    <span class="hljs-attribute">white-space</span>: nowrap; 
    <span class="hljs-attribute">overflow</span>: hidden; 
} 

<span class="hljs-selector-class">.parent-box</span> <span class="hljs-selector-class">.child-box</span><span class="hljs-selector-class">.no-max-width</span> { 
<span class="hljs-attribute">max-width</span>: none; 
} 

<span class="hljs-selector-class">.parent-box</span> <span class="hljs-selector-class">.child-box</span><span class="hljs-selector-pseudo">::before</span> { 
<span class="hljs-attribute">display</span>: none; 
} 

<span class="hljs-selector-class">.parent-box</span> <span class="hljs-selector-class">.box</span><span class="hljs-selector-pseudo">::after</span> { 
    <span class="hljs-attribute">content</span>: <span class="hljs-string">'X'</span>; 
    <span class="hljs-attribute">display</span>: inline-block; 
}
</code></pre>
<p>To learn more about pseudo-elements, check out our <a target="_blank" href="https://blog.logrocket.com/css-pseudo-elements-guide/">guide to CSS pseudo-elements</a>.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this article, we reviewed how to truncate text in CSS using several CSS and JavaScript techniques. We also looked at how we can add an element after the ellipsis, which is quite tricky to achieve in many cases.</p>
<p>I hope you enjoyed this article, and feel free to suggest other patterns I may have missed. Thank you for taking the time to read this one, even if it was short, and keep coding!</p>
]]></content:encoded></item><item><title><![CDATA[Create a React chat assistant with Dialogflow CX]]></title><description><![CDATA[Have you ever wondered how a chatbot assistant works when you’ve visited a website that uses one?
Well, in this article I’m going to be showing you how to build a chatbot assistant using Dialogflow. And the best part? We are going to be doing this wi...]]></description><link>https://therustguy.com/create-a-react-chat-assistant-with-dialogflow-cx</link><guid isPermaLink="true">https://therustguy.com/create-a-react-chat-assistant-with-dialogflow-cx</guid><category><![CDATA[React]]></category><category><![CDATA[dialogflow]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[chatbot]]></category><category><![CDATA[ReactHooks]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Sun, 30 Oct 2022 23:31:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1672270063051/799fce4b-1346-4e7a-9557-4051592b0eeb.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you ever wondered how a chatbot assistant works when you’ve visited a website that uses one?</p>
<p>Well, in this article I’m going to be showing you how to build a chatbot assistant using Dialogflow. And the best part? We are going to be doing this with React. We’ll go over what Dialogflow is, explain its various components, and integrate it with a React app.</p>
<p>By the end of this article, you’ll have a functioning Dialogflow chatbot assistant, built with React, to add to your portfolio. Yay!!!</p>
<p>You can clone this project from my <a target="_blank" href="https://github.com/chinedu360/blogbotapp.git">GitHub</a>, please leave a star if you like it.</p>
<p><img src="https://s.w.org/images/core/emoji/14.0.0/svg/1f60a.svg" alt="😊" /></p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>To set up our Dialogflow chatbot, we will need the following:</p>
<ul>
<li><p>A Gmail account (this will enable us to create a Dialogflow CX agent)</p>
</li>
<li><p>Access to Google Cloud</p>
</li>
</ul>
<p>But first, let’s find out what Dialogflow CX is…</p>
<h2 id="heading-what-is-dialogflow-cx"><strong>What is Dialogflow CX?</strong></h2>
<p><a target="_blank" href="https://blog.logrocket.com/building-chatbots-dialogflow-node-js-and-react/">Dialogflow CX is a conversational AI Platform</a>, CAIP for short, used for building conversational UIs. It can be used to implement several types of virtual agents, such as voice bots, chatbots, and phone gateways, and the best part is that it supports over 50 different languages.</p>
<p>Now that we know what Dialogflow CX is, let’s set up our environment.</p>
<h2 id="heading-setting-up-our-environment"><strong>Setting up our environment</strong></h2>
<p>The first step is opening up a <a target="_blank" href="https://console.cloud.google.com/projectselector2/home/dashboard">Google Cloud Project</a>.</p>
<p>You’ll be asked to sign in, and if you have a Gmail account, log in with your credentials. After that, you’ll be redirected to a dashboard.</p>
<p>Next, click on <strong>CREATE PROJECT</strong>.</p>
<p>After that, we have to enter the project name. In our case, we’ll use <code>blog-post-bot</code>.</p>
<p>The second thing to choose is the parent organization, then click <strong>CREATE</strong>:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/google-cloud-registration.png" alt="Google Cloud Registration Page" /></p>
<p>After that, you’ll see a dashboard similar to the below image:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/google-cloud-dashboard.png" alt="Google Cloud Dashboard" /></p>
<p>Now let’s enable the Dialogflow API.</p>
<p>To make use of Dialogflow, we have to <a target="_blank" href="https://dialogflow.cloud.google.com/cx/projects">Enable Dialogflow API</a> for our project. We can do that on the dashboard that pops up, similar to the below image:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/enable-dialogflow-api.png" alt="Enable DialogFlow API Option" /></p>
<p>Select the project we created initially, and you’ll be presented with the below screen. Click on <strong>Enable API</strong>:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/enable-api.png" alt="Enable API Button" /></p>
<p>You’ll then be prompted with another screen asking to create an agent. Complete the form for the initial basic agent settings:</p>
<ul>
<li><p>Set a display name</p>
</li>
<li><p>Leave location as the default: <code>us-central1 (Iowa, USA)</code></p>
</li>
<li><p>Set your preferred time zone. I set mine to <code>(GMT+1:00) Africa/Casablanca</code></p>
</li>
<li><p>Leave the language as the default or feel free to set your own</p>
</li>
<li><p>Click <strong>Create</strong></p>
</li>
</ul>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/create-agent.png" alt="Create Agent" /></p>
<p>After our agent is created, we are presented with a dashboard called the “Default Start Flow.” A mini pop-up at the bottom of the dashboard tells us that our agent is successfully created:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/setting-flows.png" alt="Setting The Flows" /></p>
<h2 id="heading-what-are-flows-in-dialogflow-cx"><strong>What are flows in Dialogflow CX?</strong></h2>
<p>Flows are a new concept in Dialogflow CX. They enable us to create complex dialogs that involve a lot of topics.</p>
<p>The bot we are building will give us different articles, such as blog post articles categories, article suggestions, and most popular articles.</p>
<p>With this, we will have three conversation topics that we’ll break into three different flows:</p>
<ul>
<li><p>Categories</p>
</li>
<li><p>Suggested articles</p>
</li>
<li><p>Best articles</p>
</li>
</ul>
<p>Next, we’ll set up our flows.</p>
<h2 id="heading-creating-our-flows"><strong>Creating our flows</strong></h2>
<p>In the above image, you can see the <strong>+</strong> icon on the left sidebar. Click on <strong>Create flow</strong> and enter the name “Categories.” Hit the <code>Enter</code> key.</p>
<p>We have successfully created our first flow! Now, go ahead and do the same for “Suggested articles” and “Best articles.”</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/create-second-third-flows-1.png" alt="Create Second And Third Flows" /></p>
<h2 id="heading-the-dialogflow-simulator"><strong>The Dialogflow Simulator</strong></h2>
<p>On the Dialogflow CX dashboard, we have a simulator. This allows us to simulate our bot and test our conversations.</p>
<p>At the top right of our dashboard, click on <strong>Test Agent</strong>.</p>
<p>To quickly test our bot we can say <code>Hi</code>. Our virtual agent will respond with a default welcome message, just like the image below:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/test-agent.png" alt="Test Agent" /></p>
<p>Let’s change our welcome text to something more personalized — something more friendly, welcoming, and fun.</p>
<p>On the left of your dashboard, click on <strong>Default Start Flow</strong>, then click on the <strong>Start Tree</strong> node to open the page.</p>
<p><strong><em>N.B.*</em></strong>, on the<em> **</em>Pages<strong><em> </em>section in the left sidebar, it automatically selects<em> </em></strong>Start<em>*</em></p>
<p>In <strong>Start</strong>, under <strong>Routes</strong>, click <strong>Default Welcome Intent</strong>. To the right, another panel will open, and in this panel look for the <strong>Fulfillment</strong> section and delete all the <strong>Agent says</strong> entries. Add our custom text below:</p>
<p><code>You are most welcome, I am Chinedu, a blog bot. I can do many things. You can read tech articles from many categories, get the best articles, and I can suggest great articles in case you don't have any in mind, I'm sure you'd love it! Let's get reading…</code></p>
<p>Next, we make some quick reply buttons similar to what we see on regular bots. We call them suggestion chips.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/quick-reply-buttons.png" alt="Quick Reply Buttons" /></p>
<p>Under the <strong>Fulfillment</strong>, there is a link called <strong>Add dialogue options.</strong> Click on it, then click on <strong>Custom payload</strong> and paste in the below code snippet before hitting <strong>Save</strong>:</p>
<pre><code class="lang-plaintext">{
    "richContent": [
      [
        {
          "type": "chips",
          "options": [
            {
              "text": "Categories"
            },
            {
              "text": "Best articles"
            },
            {
              "text": "Suggested articles"
            }
          ]
        }
      ]
    ]
  }
</code></pre>
<p>Now let’s go ahead and test our welcome intent in the simulator:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/test-bot-simulator.png" alt="Test Bot Simulator" /></p>
<p>When we send <code>Hi</code>, we get our custom message. You may have noticed that we can’t view our chip. For us to be able to achieve that, we need integration. We’ll be using React for this, and we’ll set up our React app to integrate with our Dialogflow bot.</p>
<p>But before we do that, we need to enable a web integration as such:</p>
<ul>
<li><p>In the left sidebar, click on <strong>Manage</strong></p>
</li>
<li><p>Scroll down to <strong>Integrations</strong></p>
</li>
<li><p>Select <strong>Dialogflow Messenger</strong> from the dashboard</p>
</li>
<li><p>Click on <strong>Connect</strong></p>
</li>
<li><p>A pop-up will appear, click <strong>Enable</strong></p>
</li>
</ul>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/enable-web-integration.png" alt="Enable Web Integrations" /></p>
<p>After this, another pop-up will be shown that contains the JavaScript code we need for the integration:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/javascript-code-integration.png" alt="JavaScript Code Needed For Integration" /></p>
<p>To do a quick demo, we can click on the <strong>Try it now</strong> button.</p>
<h2 id="heading-setting-up-our-react-app"><strong>Setting up our React app</strong></h2>
<p>In your terminal, create a new React project by running the below code:</p>
<pre><code class="lang-plaintext">npx create-react-app blogbotapp
</code></pre>
<p>Next, <code>cd</code> into our application, open it with your favorite code editor and type run <code>npm start</code>.</p>
<p>Next, we add our code snippet to the body of our HTML file in the public folder within our React application:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/code-snippet-html-file.png" alt="Paste Code Snippet Into HTML File" /></p>
<p>All set! With this, we have successfully set up our React app, and we can see that everything works well like in our simulator on the Dialogflow CX dashboard.</p>
<p>Let’s get back to configuring our bot and setting up our entities.</p>
<h3 id="heading-what-are-the-three-entity-types"><strong>What are the three entity types?</strong></h3>
<p>Entities are used for identifying and extracting useful data from user input.</p>
<p>We will be creating our entities shortly, but Dialogflow provides ones that can be used to match dates, emails, colors, currency, phone numbers, addresses, etc.</p>
<p>There are three types of entities in Dialogflow:</p>
<ul>
<li><p>System entities</p>
</li>
<li><p>Session entities</p>
</li>
<li><p>Developer entities</p>
</li>
</ul>
<p>Let’s go ahead and create our custom entities for our category, best articles, and suggested articles options.</p>
<h3 id="heading-entity-for-category"><strong>Entity for “Category”</strong></h3>
<p>First, click on <strong>Manage</strong> and then <strong>Entity types.</strong> If the dashboard opens up, click the button that says <strong>Create new</strong>.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/create-new-entity.png" alt="Create New Entity" /></p>
<p>A dashboard will show up where you can enter the display name. In the table that shows the entity, enter the following entities and their synonyms:</p>
<ul>
<li><p>React.js (with synonyms: react, React, React.js, reactjs, Reactjs, React.JS)</p>
</li>
<li><p>Node.js (with synonyms: Node,node.js, Node.js, Node.JS, NODE.JS, nodejs, Nodejs, NODEJS)</p>
</li>
<li><p>Data Structures and Algorithms (with synonyms: algorithms, Algorithms, algorithm, Algorithm, data, Data, data structures, Data structures, Data structures &amp; Algorithms, DSA, structures, dsa, data structures &amp; Algorithms, Data structures and Algorithms, data structures &amp; algorithms)</p>
</li>
</ul>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/entities-synonyms.png" alt="Entities With Synonyms" /></p>
<p>After that, click on the <strong>Advanced</strong> <strong>settings</strong> dropdown, and check the <strong>Fuzzy matching</strong> and <strong>Redact in Log</strong> checkbox.</p>
<p>Fuzzy matching helps in the case where if we spell a name wrong, it can match it to the right entity.</p>
<p>Redact in log helps to correct the name in the log in a case where we spell them wrong.</p>
<p>After that, click <strong>Save</strong> and do the same for the other two entities.</p>
<p>After saving our first entity, return to the dashboard and we can see our first entity, @Categories. To create a new entity, click <strong>+</strong> <strong>Create</strong>.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/new-entity.png" alt="New Entity" /></p>
<h3 id="heading-entity-for-best-articles"><strong>Entity for “Best articles”</strong></h3>
<ul>
<li><p>JavaScript: How to implement a queue (with synonyms: Javascript queue, Javascript: How to implement a queue, queue, Queue, queues, Queues, QUEUES, QUEUE)</p>
</li>
<li><p>70+ JavaScript libraries (with synonyms: 70+ JavaScript library frameworks tools and plugins, plugins, PLUGINS, PLUGIN, Plugins, Plugin, tools, TOOLS, TOOL, Tools, Tool, tool, frameworks, FRAMEWORKS, FRAMEWORK, Frameworks, Framework, frameworks, framework. Library, libraries, javascript library)</p>
</li>
<li><p>Big O Notation (with synonyms: Big O, big O, Big O Notation, Notation, big o notation)</p>
</li>
</ul>
<h3 id="heading-entity-for-suggested-articles"><strong>Entity for “Suggested articles”</strong></h3>
<ul>
<li><p>Cache (with synonyms: Cache, Redis, CACHE, REDIS, cache, redis)</p>
</li>
<li><p>Nest.js vs. Loopback (with synonyms: Nestjs vs Loopback, NESTJS, nestjs, loopback, loopback4)</p>
</li>
</ul>
<p>Next, we set up our intents.</p>
<h2 id="heading-what-are-intents"><strong>What are intents?</strong></h2>
<p>In Dialogflow CX, intents contain the logic that detects what the user wants. They only contain training phrases and are therefore reusable.</p>
<p><strong><em>N.B.*</em></strong>, According to the documentation, training phrases in intents make use of entities. This helps to get variable inputs, therefore it’s good practice to create entity types before creating intents*</p>
<p>Training phrases are example phrases of what the user might type or say. If the user input is similar to one of the defined phrases, Dialogflow matches the intent.</p>
<p>Also, we don’t need to match everything because Dialogflow has an inbuilt machine learning functionality that expands our list with other similar phrases.</p>
<p>Intents use three different prefixes:</p>
<ul>
<li><p>Redirect (for intents that use NLU to fetch a page)</p>
</li>
<li><p>Confirm/decline (for intents that are yes or no training phrases)</p>
</li>
<li><p>Supp (in a case where the intent is an additional question that can come back anytime in the flow)</p>
</li>
</ul>
<h2 id="heading-how-do-we-create-intents"><strong>How do we create intents?</strong></h2>
<p>To create intents, click on <strong>Manage</strong> and then <strong>Intents</strong>. At the top of the dashboard, click on the <strong>+ Create</strong> button.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/how-create-intents.png" alt="How To Create Intents" /></p>
<p>I’ll go ahead and create the intents for the @Catergories entity, then I will give phrases for the other entities to enable you to do that on your own.</p>
<p>You can add your imagination for more training phrases. It’s advisable to have more than 10 training phrases for each intent to cover the different ways the user might trigger it.</p>
<p>In the input box that says <strong>Display name</strong>, input <code>redirect.categories.overview</code>.</p>
<p>Do the same for the description:</p>
<p><code>Categories.description: The types of articles we have.</code></p>
<p>After that, we scroll down and create the training phrases:</p>
<ul>
<li><p><code>Can I see a list of all the available categories of articles?</code></p>
</li>
<li><p><code>What articles can I read?</code></p>
</li>
<li><p><code>I would like to see the categories of articles available</code></p>
</li>
<li><p><code>Which categories of tech articles do you have</code></p>
</li>
<li><p><code>Which categories are currently available</code></p>
</li>
<li><p><code>Which category</code></p>
</li>
<li><p><code>Which articles</code></p>
</li>
<li><p><code>What articles can I read?</code></p>
</li>
</ul>
<p>After all, this is done, click on <strong>Save</strong>.</p>
<p>Now, go ahead and create new intents.</p>
<h2 id="heading-pages-and-state-handlers"><strong>Pages and state handlers</strong></h2>
<p>Dialogflow CX conversations can be described as <a target="_blank" href="https://en.wikipedia.org/wiki/Finite-state_machine">finite-state automation</a>.</p>
<p>Let me explain with an example…</p>
<p>Take an automated teller machine (ATM). The ATM has the following states: waiting for credit/debit cards, inputting your pin/passcode, selecting your bank, selecting the withdrawal amount, giving money, and when a certain input is provided by the user, moving between different states.</p>
<p>Slotting in your card will change the state of the ATM Machine from waiting for credit/debit cards to inputting your pin/passcode.</p>
<p>In Dialogflow CX virtual agent, we use pages to model these states.</p>
<p>There are three types of routes that control the conversation state by handling the transition between pages:</p>
<ul>
<li><p>Condition routes: changing the page occurs based on a certain condition stored in the session</p>
</li>
<li><p>Intent routes: changing the page occurs based on what the user says/wants</p>
</li>
<li><p>Event handlers: changing the page occurs when a certain event should be handled, (for example, handling no match, handling no input)</p>
</li>
</ul>
<p>The response sent back to the user is known as the conversation utterances. And they are defined by fulfillment which can be of two types:</p>
<ul>
<li><p>Dynamic fulfillment: when a fulfillment webhook is called to get a dynamic response</p>
</li>
<li><p>Static fulfillment: when a static fulfillment response is provided</p>
</li>
</ul>
<p>We won’t be going into creating dynamic fulfillment. For our blog bots, we will focus on static fulfillment responses.</p>
<p>We’ll create the pages in the default start flow:</p>
<ul>
<li><p>First click <strong>Build</strong></p>
</li>
<li><p>Click on <strong>Default Start Flow</strong></p>
</li>
<li><p>Click the <strong>Start</strong> under <strong>PAGES</strong> in the left sidebar section</p>
</li>
<li><p>Next, click the <strong>+</strong> icon next to <strong>Routes</strong></p>
</li>
<li><p>Click on the <strong>Intents</strong> input dropdown</p>
</li>
<li><p>Add <code>redirect.categories.overview</code></p>
</li>
<li><p>Scroll down to <strong>Transition</strong> and select the <strong>Categories</strong> flow that we created initially</p>
</li>
<li><p>Finally, hit <strong>Save</strong></p>
</li>
<li><p>We repeat the same process for <code>redirect.bestArticles.overview</code>, <code>redirect.reactjs</code>, <code>redirect.nodejs</code>, <code>redirect.datastructures-and-algorithims</code>, <code>redirect.suggestedArticles.overview</code>, and <code>redirect.end</code></p>
</li>
</ul>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/static-fulfillment-responses-one.png" alt="Static Fulfillment Responses Photo One" /></p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/static-fulfillment-responses-two.png" alt="Static Fulfillment Responses Photo Two" /></p>
<p>You might have noticed <strong>End Session</strong> and <strong>Flow</strong>. <strong>End Flow</strong> closes the flow and jumps back to the last active flow, while <strong>End Session</strong> closes the full chat session.</p>
<p>Next, we create pages for flows, starting with Category. The below chat transcript is for the “Category” flow:</p>
<pre><code class="lang-plaintext">Message from user: "Hello"

Bot response: "You are most welcome, I am Chinedu, a certified comrade and a blog bot. I can do many things. You can read tech articles from many categories, get the best articles, and I can suggest great articles in case you don't have any in mind, I'm sure you'd love it! Let's get reading…"

Message from user: "Can I see a list of all the available categories of articles?"

Bot response: "We have the following categories you could read from: React.js, Node.js, Data Structures and Algorithms.Which categories would you love to read from?"

Message from user: "React.js"

Bot response: "Awesome! Everyone loves React.js"
</code></pre>
<p>Let’s connect our pages:</p>
<ul>
<li><p>First click on <strong>Build</strong></p>
</li>
<li><p>Click on <strong>Categories</strong></p>
</li>
<li><p>Click the <strong>Start</strong> under <strong>PAGES</strong></p>
</li>
<li><p>Next, click the <strong>+</strong> icon next <strong>Routes</strong></p>
</li>
<li><p>Click on the <strong>Intents</strong> input dropdown</p>
</li>
<li><p>Add <code>redirect.categories.overview</code></p>
</li>
<li><p>Scroll down to <strong>Transition</strong>, select the <strong>Page</strong> and choose <strong>+ New page</strong>.</p>
</li>
<li><p>Use the page name<strong>:</strong> <code>Category Overview</code></p>
</li>
<li><p>Finally, hit <strong>Save</strong></p>
</li>
<li><p>We repeat the same process for the <code>redirect.bestArticles.overview</code>, <code>redirect.reactjs</code>, <code>redirect.nodejs</code>, <code>redirect.datastructures-and-algorithims</code>, and <code>redirect.suggestedArticles.overview</code></p>
</li>
</ul>
<p>We’ll continue adding static fulfilments:</p>
<ul>
<li><p>In <strong>Categories</strong>, click on <strong>Category Overview</strong></p>
</li>
<li><p>Click on <strong>Edit fulfillment</strong> under the <strong>Entry fulfillment</strong> section</p>
</li>
<li><p>Paste the static fulfillment message: <code>We have the following categories you could read from: React.js, Node.js, Data Structures and Algorithms.</code></p>
</li>
<li><p>Click <strong>Save</strong></p>
</li>
</ul>
<p>We do the same thing for the “Best articles” overview and “Suggested articles” overview<strong>:</strong></p>
<ul>
<li><p><code>Do you want to read some of our best articles?</code></p>
</li>
<li><p><code>You don't have anything in mind to read? I could suggest articles for you to read.</code></p>
</li>
</ul>
<p>Let’s look at the parameters and what they are used for.</p>
<p>Parameters are used to capture values that we expect to be supplied by the user in a session.</p>
<p>Each parameter has an entity and name.</p>
<p>Let’s create parameters for the “Category Overview” page:</p>
<ul>
<li><p>Click the <strong>Category Overview</strong> page</p>
</li>
<li><p>Click the <strong>+</strong> in the <strong>Parameter</strong> block. Add the category parameter</p>
</li>
<li><p>Enter a display name: <code>category</code></p>
</li>
<li><p>Select an entity type: <code>@Category</code></p>
</li>
<li><p>Check the box for <strong>Required</strong></p>
</li>
<li><p>Check the box for <strong>Redact</strong> <strong>in</strong> <strong>Log</strong></p>
</li>
</ul>
<p>If the virtual agent hasn’t collected the category parameter, we could send the user a response:</p>
<p><code>Please, what category of article do you have in mind?</code></p>
<p>Next, let’s add a dialogue option that’ll provide rich suggestions.</p>
<p>Click <strong>Add dialogue option</strong> and add the below JSON code:</p>
<pre><code class="lang-plaintext">{
  "richContent": [
    [
      {
        "options": [
          {
            "text": "React.js"
          },
          {
            "text": "Node.js"
          },
          {
            "text": "Data Structures and Algorithms"
          }
        ],
        "type": "chips"
      }
    ]
  ]
}
</code></pre>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/10/add-dialogue-option.png" alt="Add Dialogue Option" /></p>
<p>We can handle different fallback fulfillment prompts. We do this with parameter event handlers. There are various inbuilt event handlers to choose from, such as no-match default and no-input default, which we are going to be using.</p>
<ul>
<li><p>On the same page, scroll down to the <strong>Event handlers</strong> section</p>
</li>
<li><p>Click on <strong>Add event handler</strong></p>
</li>
<li><p>Select the event: <code>No-match default</code></p>
</li>
<li><p>Then paste in the following static fulfillment text: <code>I could not get that, can you specify the category you need? You can choose React.js, Node.js, and Data Structures and Algorithms. What category of articles would you like to read?</code></p>
</li>
<li><p>Click <strong>Save</strong></p>
</li>
<li><p>Click on <strong>Add event handler</strong></p>
</li>
<li><p>Select the event: <code>No-input default</code></p>
</li>
<li><p>Then paste in the static message: <code>I am sorry, I could not get the category you need. You can choose React.js, Node.js, and Data Structures and Algorithms. What category of articles would you like to read?</code></p>
</li>
<li><p>Click <strong>Save</strong></p>
</li>
</ul>
<p><strong>Page condition routes</strong></p>
<p>Parameters tend to be very powerful when combined with a page conditional route. When a condition evaluates to <code>true</code>, the respective page route is called.</p>
<p>For our blog bot, we collect a sequence of parameters, hence we will create a form to check if our condition is met.</p>
<p>Creating the conditional routes on the “Category Overview” page.</p>
<p>Here, we are creating a conditional route that will transition to the next page once the artist is known.</p>
<p>After we have selected the category we want, our bot does something really simple. It sends us a nice message “React.js, nice choice.”</p>
<p>In the “Best articles” flow, we click <strong>bestArticle</strong>, hit the <strong>+</strong> beside the route, and paste the following into the custom payload:</p>
<pre><code class="lang-plaintext">{
  "richContent": [
    [
      {
        "options": [
          {
            "link": "https://blog.logrocket.com/add-redis-cache-nestjs-app/",
            "text": "Redis in Nestjs"
          },
          {
            "link": "https://blog.logrocket.com/build-strongly-typed-polymorphic-components-react-typescript/",
            "text": "React.js polymorphic component"
          }
        ],
        "type": "chips"
      }
    ]
  ]
}
</code></pre>
<p>Change the intent to the “Best articles” page that we created initially and set the condition to <code>At least match one rule</code>.</p>
<p>After that, we want to create another route where we end the session.</p>
<p>We do the same thing for the suggested article. Creating a new intent called “Suggested articles” while pasting the below payload and creating the end session route:</p>
<pre><code class="lang-plaintext">{
  "richContent": [
    [
      {
        "options": [
          {
            "link": "https://www.ddevguys.com/bigo-notation-summarized",
            "text": "Big O Notation Summarized"
          },
          {
            "link": "https://www.ddevguys.com/javascript-how-to-implement-the-linked-list-data-structure-part3",
            "text": "Linked-list"
          },          {
            "link": "https://www.ddevguys.com/javascript-how-to-implement-a-queue",
            "text": "Implement a queue."
          }
        ],
        "type": "chips"
      }
    ]
  ]
}
</code></pre>
<p>With this, we have been able to build a very simple bot that sends us a cool message after we have chosen a category, sends us our best articles, and also suggests articles to us.</p>
<p>Phew…</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>We went over the process of building a chatbot using Dialogflow CX and React. This app and chatbot could be improved in a lot of ways depending on your project requirement and the goal you want to achieve.</p>
<p>This was just a basic overview of what could and can be done with Dialogflow CX and how powerful it is.</p>
<p>If you got to this point, you are indeed a legend, because this was a long one. And I really appreciate you for taking the time to read this.</p>
<p>Do leave feedback if you enjoyed it! Reach out on Twitter if you want to dive really deep into Dialogflow CX, I’d love to hear from you all.</p>
<p>Until then, keep coding. Much love.</p>
]]></content:encoded></item><item><title><![CDATA[How to add Redis cache to a NestJS app]]></title><description><![CDATA[Performance, performance, performance! That’s the whole point of caching.Caching specifically helps speed up an application’s performance, thereby significantly improving its efficiency.
This article will look at how to add caching functionality to a...]]></description><link>https://therustguy.com/how-to-add-redis-cache-to-a-nestjs-app</link><guid isPermaLink="true">https://therustguy.com/how-to-add-redis-cache-to-a-nestjs-app</guid><category><![CDATA[Next.js]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Redis]]></category><category><![CDATA[caching]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Wed, 03 Aug 2022 23:10:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1672268290052/c7c12350-6756-42d2-a85f-f3d6d821243b.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Performance, performance, performance! That’s the whole point of caching.Caching specifically helps speed up an application’s performance, thereby significantly improving its efficiency.</p>
<p>This article will look at how to add caching functionality to a NestJS app with Redis. We’ll talk about what caching is, about Redis, and go over the implementation process.</p>
<p>So grab a cup of coffee (or whatever it is you all drink these days). This is going to be an interesting one!</p>
<h2 id="heading-what-is-caching"><strong>What is caching?</strong></h2>
<p>In computing, a cache is a frequently queried, temporary store of duplicate data. The data is kept in an easily accessed location to reduce latency.</p>
<p>Let me form an analogy to help explain this concept better…</p>
<p>Let’s say you did get that cup of coffee after all! Imagine that each time you drink a bit of it, you have to head back to your coffee machine. You fill up your cup, take a sip, and leave it there to head back to your workstation and continue reading this article.</p>
<p>Because you have to keep going back and forth to your coffee machine and cup, it takes you several hours to finish your coffee (and this article). This is what happens without caching.</p>
<p>Let’s imagine a different scenario. Let’s say when you head over to your coffee machine for your first sip of coffee, instead of taking a sip and heading back to your workspace, you fill up your cup and head back to your workstation with it in hand.</p>
<p>As you continue reading this article, you always have your coffee at your desk. You can quickly take a sip (lower latency) so you can concentrate on this article and finish it much faster. <a target="_blank" href="https://blog.logrocket.com/caching-strategies-to-speed-up-your-api/">This is what happens when caching is implemented</a>.</p>
<p>If we are to bring this analogy to the real world, the coffee machine is the web server and the coffee itself is the data that’s frequently queried.</p>
<h2 id="heading-what-is-redis"><strong>What is Redis?</strong></h2>
<p>According to <a target="_blank" href="https://redis.io/docs/about/#:~:text=Redis%20is%20an%20open%20source,%2C%20geospatial%20indexes%2C%20and%20streams.">the official Redis website</a>, “Redis is an open source, in-memory data structure store used as a database, cache, message broker, and streaming engine.”</p>
<p><a target="_blank" href="https://blog.logrocket.com/guide-to-fully-understanding-redis/">It’s important to note that Redis doesn’t handle caching alone</a>. It provides data structures like hashes, sets, strings, lists, bitmaps, and sorted sets with range queries, streams, HyperLogLogs, and geospatial indexes.</p>
<h2 id="heading-implementing-redis-cache-in-a-nestjs-app"><strong>Implementing Redis cache in a NestJS App</strong></h2>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<p>To follow along with this article, you’ll need the following:</p>
<ul>
<li><p>Node.js installed on your computer</p>
</li>
<li><p>Basic knowledge of JavaScript and Node.js</p>
</li>
<li><p>NestJS Command Line Interface (CLI) installed on your computer</p>
</li>
<li><p>Basic understanding of how Nest works</p>
</li>
</ul>
<p>If you don’t have NestJS installed, <a target="_blank" href="https://docs.nestjs.com/">this will help you get up to speed</a>.</p>
<p>After you’ve installed the NestJS CLI on your machine, let’s go ahead and set up the Redis cache for our application.</p>
<h2 id="heading-setting-up-redis-cache-for-our-nestjs-app"><strong>Setting up Redis cache for our NestJS app</strong></h2>
<p>First, let’s create a new project. We’ll call it <code>redis-setup</code>. Open the terminal after installing NestJS and run the below line of code:</p>
<pre><code class="lang-plaintext">nest new redis-setup
</code></pre>
<p>After that, we want to select our preferred package manager.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/07/preferred-package-manager.png" alt="Package Manager Screenshot" /></p>
<p>In my case, I chose <code>npm</code> but please pick whichever works for you! After that, the installation will continue.</p>
<p>Once the installation is done, we’ll see something similar to the below screenshot. We have to <code>cd</code> into our app by running <code>cd redis-setup</code>.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/07/cd-redis-setup.png" alt="Cd Into Redis Setup Screenshot" /></p>
<p>Once inside the project directory, we’ll run <code>code</code> in the terminal. This will automatically open the project in VS Code, provided that it’s installed.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/07/vs-code.png" alt="VS Code" /></p>
<p>Below is what our <code>redis-setup</code> project looks like.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/07/redis-setup-project.png" alt="Redis Setup Project Screenshot" /></p>
<p>Before we continue our setup, there are four main packages we need to install in our application.</p>
<h3 id="heading-installing-packages"><strong>Installing packages</strong></h3>
<p>The first package we need to install is <code>node-cache-manager</code>. The Node cache module manager allows for easy wrapping of functions in cache, tiered caches, and a consistent interface. Install this by running <code>npm install cache-manager</code> in the terminal.</p>
<p>Next, we need to install <code>@types/cache-manager</code>, the TypeScript implementation of <code>node-cache-manager</code>. Install this by running <code>npm i @types/cache-manager</code> in the terminal.</p>
<p>Third, we’ll install <code>cache-manager-redis-store</code>. This package provides a very easy wrapper for passing configuration to the <code>node_redis</code> package. Install this by running <code>npm install cache-manager-redis-store --save</code> in the terminal</p>
<p>Finally, we need to install <code>@types/cache-manager-redis-store</code>. This is the TypeScript implementation of the <code>cache-manager-redis-store</code> package. Install this by running <code>npm i --save-dev @types/cache-manager-redis-store</code> in the terminal.</p>
<p>After we are done with the installation, we can proceed to configure <code>redis-cache</code> for our app.</p>
<h3 id="heading-configuring-redis-cache"><strong>Configuring</strong> <code>redis-cache</code></h3>
<p>The first step to configuring <code>redis-cache</code> is importing the <code>CacheModule</code> and calling its method <code>register()</code>. This method will take our Redis configurations.</p>
<pre><code class="lang-plaintext">//import CacheModule from @nestjs/common'

import { Module, CacheModule } from '@nestjs/common';
</code></pre>
<p>In our <code>register()</code>, which takes an object, we will create a property called <code>store</code> and assign <code>redisStore</code> to it. The <code>redisStore</code> will represent the <code>cache-manager-redis-store</code> library that we installed.</p>
<pre><code class="lang-plaintext">//import CacheModule from '@neskjs/common/cache';
import { Module, CacheModule } from '@nestjs/common';

//import redisStore from 'cache-manager-redis-store';
import * as redisStore from 'cache-manager-redis-store';

import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [CacheModule.register({ store: redisStore })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
</code></pre>
<p>Next, we’ll set up another property in the <code>register()</code> method object. We’ll add another property called <code>host</code> and set its value to the default <a target="_blank" href="http://localhost"><code>localhost</code></a>. We’ll set the <code>port</code> to the default value of <code>6379</code>.</p>
<pre><code class="lang-plaintext">//import CacheModule from '@neskjs/common/cache';
import { Module, CacheModule } from '@nestjs/common';

//import redisStore from 'cache-manager-redis-store';
import * as redisStore from 'cache-manager-redis-store';

import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [CacheModule.register({ 
    store: redisStore, 
    host: 'localhost', //default host
    port: 6379 //default port
  })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
</code></pre>
<p>With the above, we’ve set up a simple, basic configuration between Redis and our NestJS application!</p>
<p>The second step is to inject the functionality into our controller. This is so our controllers can communicate with the Redis store. We need to inject <code>CacheManager</code>.</p>
<p>In our project directory, head over to <code>app.controller.ts</code>. In this file, we’ll import <code>Get</code>, <code>Inject</code>, and <code>CACHE_MANAGER</code> from <code>@nestjs/common</code>.</p>
<pre><code class="lang-plaintext">//importing Get, Inject, Inject, and CACHE_MANAGER from nestjs/common
import { Controller, Get, Inject, CACHE_MODULE } from '@nestjs/common';
</code></pre>
<p>After that, we’ll pass in <code>Inject</code> and the <code>CACHE_MANAGER</code> token. Next, we’ll import <code>Cache</code> from <code>cache-manager</code> and pass it to our <code>cacheManager</code>.</p>
<pre><code class="lang-plaintext">//importing Get, Inject, Inject, and CACHE_MANAGER from nestjs/common
import { Controller, Get, Inject, CACHE_MANAGER } from '@nestjs/common';
//import the cache manager
import Cache from 'cache-manager';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache{}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}
</code></pre>
<p><strong>N.B.</strong>, The <code>Cache</code> class is imported from the <code>cache-manager</code> library, while the <code>CACHE_MANAGER</code> token is imported from <code>@nestjs/common</code>.</p>
<p>The <code>CACHE_MANAGER</code> injects the <code>redis-cache-store</code>, while <code>Cache</code> provides the default method for <code>Cache</code> communication and also works with any other store.</p>
<p>Let’s understand the <code>get</code> and <code>set</code> methods of the Redis store.</p>
<h3 id="heading-get-and-set-methods"><code>get</code> and <code>set</code> methods</h3>
<p>The <code>Cache</code> instance has the <code>get</code> method, which we have from the <code>cache-manager</code> package. This method enables us to get items from the cache. <code>null</code> is returned if the cache is empty.</p>
<pre><code class="lang-plaintext">let val = await this.cacheManager.get('key');
</code></pre>
<p>We use the <code>get</code> method for adding an item to the cache. The default caching time is five seconds, but we can manually set the time to live (TTL) to anytime we need. It will depend on the app’s specs.</p>
<pre><code class="lang-plaintext">await this.cacheManager.set('key', 'value', {ttl: 2000});
</code></pre>
<p>In our <code>get</code> method, we’ll pass the URL for checking our Redis store.</p>
<pre><code class="lang-plaintext">@Get('get-number-cache')
</code></pre>
<p>Next, in our <code>app.controller.ts</code>, we’ll create a method that gets a number. We’ll check if our number is available in the Redis store using the string <code>number</code>.</p>
<pre><code class="lang-plaintext">const val = await this.cacheManager.get('number')
    if(val) {
      return { 
        data: val,
        FromRedis: 'this is loaded from redis cache'
      }
    }
</code></pre>
<p>If this is the case, we will return the data to our endpoint. But, if the data does not exist in <code>redis-store</code>, we store it using the key <code>number</code> and set the TTL to any desired value. In our case, we’ll use <code>1000</code>.</p>
<p>Finally, we’ll return the stored data from our dummy database <code>randomNumDbs</code>. In this case, we are generating the number randomly. We could use a string, but in a real-world production application, this is where we’d get the data from the database for every first request.</p>
<pre><code class="lang-plaintext">if(!val){
      await this.cacheManager.set('number', this.randomNumDbs , { ttl: 1000 })
      return {
        data: this.randomNumDbs,
        FromRandomNumDbs: 'this is loaded from randomNumDbs'
    }
</code></pre>
<p>Below is the complete code:</p>
<pre><code class="lang-plaintext">@Controller()
export class AppController {
  //This would be our dummy database since we won't be connecting to a database in the article
  randomNumDbs = Math.floor(Math.random() * 10)
  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  @Get('get-number-cache')
  async getNumber(): Promise&lt;any&gt; {
    const val = await this.cacheManager.get('number')
    if(val) {
      return { 
        data: val,
        FromRedis: 'this is loaded from redis cache'
      }
    }

    if(!val){
      await this.cacheManager.set('number', this.randomNumDbs , { ttl: 1000 })
      return {
        data: this.randomNumDbs,
        FromRandomNumDbs: 'this is loaded from randomNumDbs'
    }
  }
}
</code></pre>
<p>Now it’s time to run our application and test what we have done thus far. To do this in the terminal, run <code>npm start</code> and visit the URL <a target="_blank" href="http://localhost:3000/get-number-cache">http://localhost:3000/get-number-cache</a> in the browser.</p>
<p>On our first load, our request will be taken from our dummy, random number database.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/07/random-number-database-request.png" alt="Random Number Database Request" /></p>
<p>The second request (and others) will load from the Redis store until the cached data expires.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/07/loaded-redis-cache.png" alt="Loaded Redis Cache" /></p>
<p>Redis cache also has two other methods: <code>del</code> and <code>reset</code>.</p>
<h3 id="heading-del-and-reset-methods"><code>del</code> and <code>reset</code> methods</h3>
<p>If it’s not already self-explanatory, the <code>del</code> method helps us remove an item from the cache.</p>
<pre><code class="lang-plaintext">await this.cacheManager.del('number');
</code></pre>
<p>The <code>reset</code> method, on the other hand, clears the entire Redis store cache</p>
<pre><code class="lang-plaintext">await this.cacheManager.reset();
</code></pre>
<h2 id="heading-setting-up-automatic-caching-using-interceptor"><strong>Setting up automatic caching using Interceptor</strong></h2>
<p>Auto cache enables cache for every <code>Get</code> action method inside of the controller using the <code>CacheInterceptor</code>.</p>
<p>In our <code>app.module.ts</code> file, we will import <code>CacheInterceptor</code>. Configure the expiration globally for our auto cache, using the <code>TTL</code> property. To enable <code>CacheInterceptor</code>, we need to import it into the array <code>providers</code>.</p>
<pre><code class="lang-plaintext">//import CacheModule from '@neskjs/common/cache';
import { Module, CacheModule, CacheInterceptor } from '@nestjs/common';

//import redisStore from 'cache-manager-redis-store';
import * as redisStore from 'cache-manager-redis-store';

import { AppController } from './app.controller';
import { AppService } from './app.service';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register({ 
    store: redisStore, 
    host: 'localhost', //default host
    port: 6379, //default port
    ttl: 2000, //ttl
  })],
  controllers: [AppController],
  providers: [
    {
      provide:APP_INTERCEPTOR,
      useClass: CacheInterceptor
    },
    AppService],
})
export class AppModule {}
</code></pre>
<p>Next, in <code>app.controller.ts</code>, we import the <code>UseInterceptor</code> and <code>CacheInterceptor</code> from <code>@nestjs/common</code>.</p>
<pre><code class="lang-plaintext">import { Controller, Get, Inject, CACHE_MANAGER, UseInterceptors, CacheInterceptor } from '@nestjs/common';
</code></pre>
<p>We use the <code>UseInterceptors</code> decorator directly under our <code>@controller()</code> and pass <code>CacheInterceptor</code> to it. This will enable auto caching for all our <code>Get</code> endpoints inside the controller.</p>
<pre><code class="lang-plaintext">//importing Get, Inject, Inject, and CACHE_MANAGER from nestjs/common
import {Controller, Get, Inject, CACHE_MANAGER, UseInterceptors, CacheInterceptor} from '@nestjs/common';
//import the cache manager
import {Cache} from 'cache-manager';
import { AppService } from './app.service';
//import Profile.ts
import {User} from './shared/model/User';

@UseInterceptors(CacheInterceptor)
@Controller()
export class AppController {
  fakeModel:User = {
    id: 1,
    name: 'John Doe',
    email: 'okee@gmail.com',
    phone: '123456789',
    address: '123 Main St',
    createdAt: new Date(),
  }

  @Get('auto-caching')
  getAutoCaching() {
    return this.fakeModel;
  }
}
</code></pre>
<p>For auto caching, the <code>key</code> is the <code>route</code> value. This is what is going to be stored in our cache, shown in the screenshot below.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/07/key-route-value.png" alt="Key Route Value" /></p>
<p>We can confirm this in our CLI by inputting the <code>keys *</code> command.</p>
<p>In cases where we want to store data for a specific route, we won’t use the globally defined <code>time</code> and <code>key</code>. We can customize our method to have a different time.</p>
<p>In <code>app.controller.ts</code>, we use a decorator called <code>@CacheTTL()</code>. For the unique key, we use another decorator <code>@CacheKey()</code>, imported from <code>@nestjs/common</code>.</p>
<pre><code class="lang-plaintext">//importing Get, Inject, Inject, and CACHE_MANAGER from nestjs/common
import {Controller, Get, Inject, CACHE_MANAGER, UseInterceptors, CacheInterceptor, CacheKey, CacheTTL} from '@nestjs/common';
</code></pre>
<p>Specify a string that will save the data into the Redis store and a private time for our controller.</p>
<pre><code class="lang-plaintext">@Get('auto-caching')
  @CacheKey('auto-caching-fake-model')
  @CacheTTL(10)
  getAutoCaching() {
    return this.fakeModel;
  }
</code></pre>
<p>The complete code for the <code>app.controller.ts</code> file auto caching code is below.</p>
<pre><code class="lang-plaintext">//importing Get, Inject, Inject, and CACHE_MANAGER from nestjs/common
import {Controller, Get, Inject, CACHE_MANAGER, UseInterceptors, CacheInterceptor, CacheKey, CacheTTL} from '@nestjs/common';
//import the cache manager
import {Cache} from 'cache-manager';
import { AppService } from './app.service';
//import Profile.ts
import {User} from './shared/model/User';

@UseInterceptors(CacheInterceptor)
@Controller()
export class AppController {
  fakeModel:User = {
    id: 1,
    name: 'John Doeeee',
    email: 'okee@gmail.com',
    phone: '123456789',
    address: '123 Main St',
    createdAt: new Date(),
  }

  @Get('auto-caching')
  @CacheKey('auto-caching-fake-model')
  @CacheTTL(10)
  getAutoCaching() {
    return this.fakeModel;
  }
}
</code></pre>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>That’s it! In this article, we went over how to add a Redis cache to a NestJS application.</p>
<p>Redis enables lower application latency and very high data access. This has allowed software engineers to build highly performant, reliable solutions.</p>
<p>In my opinion, the advantages of Redis outweigh the disadvantages (if there are any). I hope I have shared some in-depth information on how NestJS and the Redis store work!</p>
<p>If you loved this article, please comment in the comment section! Thanks for staying with me until the end of this one. Bye!!!</p>
]]></content:encoded></item><item><title><![CDATA[NestJS vs. LoopBack 4: Which is best?]]></title><description><![CDATA[NestJS or LoopBack: Which is best? Is there a best?
Choosing between Node frameworks is super confusing, especially when there are so many great options. Picking the right one requires an understanding of not only the project you’re working on, but o...]]></description><link>https://therustguy.com/nestjs-vs-loopback-4-which-is-best</link><guid isPermaLink="true">https://therustguy.com/nestjs-vs-loopback-4-which-is-best</guid><category><![CDATA[Node.js]]></category><category><![CDATA[nestjs]]></category><category><![CDATA[Loopback]]></category><category><![CDATA[loopback4]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Fri, 01 Jul 2022 21:58:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1672269201912/7b107b02-bdbd-4723-ae91-f49688ca0fc4.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>NestJS or LoopBack: Which is best? Is there a best?</p>
<p>Choosing between Node frameworks is super confusing, especially when there are so many great options. Picking the right one requires an understanding of not only the project you’re working on, but of both frameworks and when to use them.</p>
<p>I previously wasn’t a fan of using frameworks to build backend Node apps. You could say we had a love-hate relationship, but a couple of years back I tried using NestJS and was amazed! After that, I thought Nest was the best out there…</p>
<p>…until I started experimenting with LoopBack 4. Now I’m torn!</p>
<p>In this article, we’ll compare NestJS with LoopBack across various attributes and features. We’ll also cover which of the two is best in different scenarios. Though I can’t definitively point out which is better, I can analyze which is best depending on a few important factors. We’ll go over these in the article below!</p>
<h2 id="heading-what-is-nestjs"><strong>What is NestJS?</strong></h2>
<p><a target="_blank" href="https://blog.logrocket.com/node-back-end-next-level-nestjs/">NestJS is a Node.js framework</a> used to build efficient, scalable, and enterprise-level server-side applications. It uses progressive JavaScript and has full support for TypeScript.</p>
<p>Nest uses the default Express.js but can be configured using alternatives such as Fastify.</p>
<p>Nest aims to solve the problems of software architecture. It’s worth noting that the architecture is heavily inspired by Angular, a front-end platform and framework for creating single-page applications. Thanks to its software architecture, Nest enables teams and developers to create easily maintainable, testable, scalable, and loosely coupled server-side applications.</p>
<h2 id="heading-what-is-loopback-4"><strong>What is LoopBack 4?</strong></h2>
<p>LoopBack is an innovative, <a target="_blank" href="https://strongloop.com/strongblog/loopback-2019-api-award-api-middleware/">award-winning</a> Node.js framework. It enables software engineers to quickly create APIs and microservices with backend systems, such as databases and REST or SOAP services.</p>
<p>LoopBack is highly extensible, has out-of-the-box support for TypeScript, and is built on top of Express.</p>
<p><a target="_blank" href="https://blog.logrocket.com/creating-a-dynamic-application-with-loopback/">LoopBack makes it super simple to build modern API applications</a> with little to no coding. It’s open source, is strongly supported by IBM and StrongLoop, and is driven by OpenAPI. Loopback also follows the <a target="_blank" href="https://www.openapis.org/">OpenAPI standard</a>, which is becoming widely accepted in the industry.</p>
<p>I don’t know about you, but just defining these two frameworks doesn’t quite convince me of which is best. Let’s try to compare them!</p>
<h2 id="heading-comparing-nestjs-with-loopback-4"><strong>Comparing NestJS with LoopBack 4</strong></h2>
<p>NestJS is a full-stack Node framework, while LoopBack is a microframework. The former is powerful and very easy to use, while the latter is considered when Database, REST API, AAA, and Swagger are needed. Both of these frameworks are open source.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/nestjs-loopback-comparison-1.png" alt="NestJS Vs LoopBack Comparison Matrix" /></p>
<h3 id="heading-popularity-and-growth"><strong>Popularity and growth</strong></h3>
<p>Both frameworks have acquired popularity amongst developers and in various tech communities.</p>
<p>At the time of writing this article, LoopBack has 4.2k GitHub stars and 947 forks, while NestJS has 47k stars and about 5.3k forks. You can see in the graph below that both frameworks have growing interest over time on Google.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/google-interest.png" alt="Trends On Google Over Time" /></p>
<p><strong><em>LoopBack 4 and NestJS interest over 12 months.</em></strong></p>
<p>As previously mentioned, LoopBack is a microframework (backend), while NestJS is a framework (full-stack). This could be one reason why NestJS has more GitHub stars than LoopBack.</p>
<p>Another reason behind the disparity between GitHub stars and for the general popularity of NestJS could be because NestJS software is highly opinionated. It’s also strongly backed and easily adopted by the Angular community.</p>
<p>Looking at the comparison infographic and seeing which framework has a higher GitHub star count still doesn’t cut it for me. Let’s continue with other factors.</p>
<h3 id="heading-overall-performance"><strong>Overall performance</strong></h3>
<p>Performance is the bread and butter of a good framework. It’s no surprise that NestJS is very popular amongst developers or that LoopBack has won awards for being one of the most innovative frameworks.</p>
<p>The <a target="_blank" href="https://github.com/loopbackio/loopback-next/pull/1583">LoopBack benchmark</a> measures how fast we can create new records and fetch data. This test was carried out on a mid-2015 MacBook Pro with a 22.5 GHz Intel Core i7 processor, 16GB of memory, and 1600 MHz DDR3.</p>
<p>The average results for fetching data were 4,569 requests per second, while it took 348 requests per second to create a new record.</p>
<p>When we look at latency, the average time to fetch data in milliseconds was 1.68, while it took 28.27 milliseconds to create a new one.</p>
<p>While LoopBack tried to use a real-world working scenario to test and measure requests per second, NestJS used a “Hello World” application to test, which, according to the NestJS <a target="_blank" href="https://github.com/nestjs/nest/runs/482105333">code checks benchmark</a>, shows that a NestJS and Fastify application handles about 30,001 requests per second.</p>
<h3 id="heading-scalability"><strong>Scalability</strong></h3>
<p>The scalability of a web app is its ability to handle an increasing number of concurrent users.</p>
<p>NestJS is scalable for large apps because of its application architecture. It allows software developers to build easily maintainable, highly testable, and loosely coupled applications.</p>
<p>Further, the use of HTTP server frameworks like Express (the default) or Fastify greatly improves its scalability for large apps. The fact that it’s built with TypeScript is also a big plus.</p>
<p>LoopBack is also very scalable for building complex Node.js apps. It solves a huge problem with loosely coupled apps: different parts have to work seamlessly together, without knowing much about each other, to introduce patterns that help solve these problems.</p>
<p>LoopBack gives control to software engineers. It enables problem-solving, allowing developers to bring in more capabilities without breaking the app’s core foundation.</p>
<p>We can also compose a set of actions into a meaningful flow/sequence with LoopBack, such as setting up an efficient pipeline for processing HTTP requests and responses.</p>
<p>LoopBack is built on the Express framework and uses TypeScript, making it highly scalable for building apps with extensibility, composability, and great flexibility.</p>
<h2 id="heading-features-of-nestjs-and-loopback-4"><strong>Features of NestJS and LoopBack 4</strong></h2>
<p>Now, we’ll compare some of the features of both NestJS and LoopBack 4.</p>
<h3 id="heading-features-of-nestjs"><strong>Features of NestJS</strong></h3>
<p>Unsurprisingly, the popularity of NestJS is due to its amazing features that have taken the tech community by storm.</p>
<p>Here are some of them, to name a few:</p>
<ul>
<li><p>Boosts productivity and increases development time due to its amazing and powerful Command Line Interface (CLI)</p>
</li>
<li><p>Has great, constantly maintained documentation</p>
</li>
<li><p>Is open source (MIT license)</p>
</li>
<li><p>Is written in TypeScript, a superset of JavaScript</p>
</li>
<li><p>There’s a dedicated section in the documentation for microservice-type applications built with NestJS</p>
</li>
<li><p>Makes unit testing easy</p>
</li>
<li><p>Has an actively maintained and developed codebase</p>
</li>
</ul>
<h3 id="heading-features-of-loopback-4"><strong>Features of LoopBack 4</strong></h3>
<p>Although LoopBack’s popularity is nowhere compared to NestJS, LoopBack has some amazing, innovative features that we can’t turn a blind eye to. Here are some of them:</p>
<ul>
<li><p>Is open source</p>
</li>
<li><p>Has support for TypeScript and embraces OpenAPI Specification, GraphQL, etc.</p>
</li>
<li><p>Enables development teams to quickly create dynamic end-to-end REST APIs thanks to its powerful Command Line Interface (CLI)</p>
</li>
<li><p>Enables the use of AngularJS, Android, and iOS SDKs to quickly create client-side applications.</p>
</li>
<li><p>Has easy authorization and authentication setup, API Explorer Model, role-based access controls, oAuth registration, and user models with out-of-the-box browser support</p>
</li>
<li><p>Easily connects to backend data stores like MongoDB, Postgres, MySQL, and Oracle</p>
</li>
</ul>
<p>Even after looking at their features, we can’t overlook performance, scalability, ease of getting started, and ease of testing web applications built on these frameworks. All of these factors are integral decisions for software engineers to make to get the most out of these technologies and really achieve developmental goals.</p>
<p>Now, let’s evaluate creating a project in each of these frameworks.</p>
<h2 id="heading-creating-a-project"><strong>Creating a project</strong></h2>
<p>Let’s look at how to create a simple project in both frameworks.</p>
<h3 id="heading-creating-a-hello-world-application-in-nestjs"><strong>Creating a “Hello World” application in NestJS</strong></h3>
<p><strong>N.B.,</strong> According to the NestJS documentation it is advised that Node.js v10.13.0 and later, except v13, is installed in your operating system.</p>
<p>First, we need to install the NestJS Command Line Interface.</p>
<pre><code class="lang-plaintext">npm i -g @NestJS/cli
</code></pre>
<p>Then, in the terminal of our operating system, we use the below commands to create a new project:</p>
<pre><code class="lang-plaintext">nest hello-world-app
</code></pre>
<p>A directory for <code>hello-world-app</code> will be created. The necessary boilerplates, as well as Node modules, will be installed, and the <code>src/</code> directory will be populated.</p>
<p>Below is an image of the files that populate the <code>src/</code> directory:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/src-directory-files.png" alt="SRC Directory Files" /></p>
<p>After the installation process, we can run the <code>npm run start:dev</code> command to start the app.</p>
<p>Once the app is running, if we open our browser and visit <a target="_blank" href="http://localhost:3000/">http://localhost:3000/</a>, we will see “Hello World!” in the browser!</p>
<h3 id="heading-creating-a-hello-world-application-in-loopback-4"><strong>Creating a “Hello World” application in LoopBack 4</strong></h3>
<p>Note: In order for this app to work, we need Node.js v10 or later to be installed.</p>
<p>First, we have to install the LoopBack CLI toolkit globally:</p>
<pre><code class="lang-plaintext">npm i -g @loopback/cli
</code></pre>
<p>Then, when we create a new project, the CLI installs all the dependencies and configures a TypeScript Compiler. The CLI will create a scaffold of the project, and to do so we will run the CLI and answer the prompts:</p>
<pre><code class="lang-plaintext">lb4 app
</code></pre>
<p>Answer the prompts as shown in the photo below:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/answer-prompts.png" alt="Answer Prompts" /></p>
<p>The scaffold creation is now in progress.</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/scaffold-creation.png" alt="Scaffold Creation" /></p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/scaffold-creation-two.png" alt="Scaffold Creation Two" /></p>
<p>After scaffolding, the project comes with a route of its own: <code>/ping</code>. To try it out, we <code>cd</code> into our project and run it:</p>
<pre><code class="lang-plaintext">cd hello-world-app
npm start
</code></pre>
<p>In our browser, we can visit <a target="_blank" href="http://127.0.0.1:3000/ping">http://[::1]:3000/ping</a> to see the results:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/3000-ping-results.png" alt="3000 Ping Results" /></p>
<p>We can also see that our server runs on <a target="_blank" href="http://%5B::1%5D:3000/">http://[::1]:3000</a>:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/3000-results.png" alt="3000 Results" /></p>
<p>We can see our Open API spec at <a target="_blank" href="http://127.0.0.1:3000/openapi.json">http://127.0.0.1:3000/openapi.json</a>:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/open-api-spec.png" alt="Open API Spec Results" /></p>
<p>And finally, our API Explorer on <a target="_blank" href="http://127.0.0.1:3000/explorer/">http://127.0.0.1:3000/explorer/</a>:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/api-explorer-results.png" alt="API Explorer Results" /></p>
<p>Now that we have created the scaffold for our app, let’s go ahead and add a simple controller for “Hello World.”</p>
<p>First, we need to stop the application with <code>Control + C</code> if it’s still running.</p>
<p>Then, we need to run the below command for our controller:</p>
<pre><code class="lang-plaintext">lb4 controller
</code></pre>
<p>Next, we’ll answer the prompt below:</p>
<p><img src="https://blog.logrocket.com/wp-content/uploads/2022/06/hello-world-prompts.png" alt="Hello World Prompts" /></p>
<p>In order to create the “Hello World” route, we’ll paste the below code in <code>src/controllers/hello.controller.ts:</code></p>
<pre><code class="lang-plaintext">import {get} from '@loopback/rest';

export class HelloController {
  @get('/hello')
  hello(): string {
    return 'Hello world!!!';
  }
}
</code></pre>
<p>Finally, we can start the app using <code>npm start</code>.</p>
<p>When we visit <a target="_blank" href="http://127.0.0.1:3000/hello">http://127.0.0.1:3000/hello</a>, we see “Hello World”.</p>
<h2 id="heading-testing-in-nestjs-and-loopback-4"><strong>Testing in NestJS and LoopBack 4</strong></h2>
<p>NestJS supports automated testing, which can be very important for software development.</p>
<p>Automation makes sure that tests are run at very critical development stages, such as feature integration, version release, and source code control check in.</p>
<p>The former includes features that enable developers and teams to automate and build tests.</p>
<p>NestJS is integrated with <a target="_blank" href="https://github.com/visionmedia/supertest">SuperTest</a> and <a target="_blank" href="https://github.com/facebook/jest">Jest</a>, provides its own default tooling, and automatically scaffolds default unit tests for components and end-to-end tests for apps.</p>
<p>NestJS also makes it easy to use any testing framework.</p>
<p>LoopBack comes with a thoroughly automated test suite that helps speed up development. It also helps both new and experienced developers understand different parts of the application codebase. When bugs are fixed and new features are implemented, LoopBack helps prevent regressions and ensures that applications built on LoopBack work as expected.</p>
<p>LoopBack has recommended the use of <a target="_blank" href="https://mochajs.org/">Mocha</a>. Mocha is a JavaScript test framework that runs on Node.js, as well as the browser, and makes asynchronous testing simple.</p>
<p>However, LoopBack’s automated test suite needs a test runner in order for it to execute the test and produce a summarized report. Hence, Mocha to the rescue.</p>
<p>In addition to a test runner, the automated test suites also require a library for creating test doubles. <a target="_blank" href="https://sinonjs.org/">Sinon.JS</a> is used for this.</p>
<p>An assertion library like <a target="_blank" href="https://shouldjs.github.io/">Should.js</a>, as well as a library for making HTTP calls and verifying their results like <a target="_blank" href="https://github.com/visionmedia/supertest">SuperTest</a>, are recommended.</p>
<p>The <a target="_blank" href="https://www.npmjs.com/package/@loopback/testlab">@loopback/testlab</a> module automatically integrates with these packages, making them easy to use with LoopBack and, in turn, making testing for LoopBack apps extremely quick and simple to set up.</p>
<h2 id="heading-is-nestjs-or-loopback-4-the-better-framework"><strong>Is NestJS or LoopBack 4 the better framework?</strong></h2>
<p>We’ve gotten to the point where we have to answer this very important question. Well…</p>
<p>At the beginning of this article, I asked a question that I felt you might have in mind. Is there really a best between these two?</p>
<p>Well, every framework has its pros and cons, as with everything in life.</p>
<p>I’ve found that picking one technology and sticking to it is king. But, of course, you have to make that decision based on the requirements of the project you are working on and the team behind it.</p>
<p>Ultimately, both technologies have done a great job of building a solid foundation to help software engineers build fast, scalable, highly efficient, and maintainable web applications.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Comparing these two technologies was no easy feat because they are both amazing and very innovative.</p>
<p>We went from defining these frameworks to comparing their popularity and growth. We looked at their features and how they scale, as well as how easy and fast it is to set up a “Hello World” application using both frameworks. Finally, we looked at testing and how easy it is to set it up in both frameworks.</p>
<p>This has been a long piece, and if you have stayed to this point I must say a big thank you! All in all, I hope you enjoyed this piece as much as I enjoyed writing it. Once again, thanks for sticking with me thus far! Happy coding, comrades!</p>
]]></content:encoded></item><item><title><![CDATA[Big(O) Notation summarized!]]></title><description><![CDATA[Big(O) is the way in which we compare algorithmic complexities of two programs in a standard manner
Big(O) is an algorithmic complexity metric, which defines the relationship between the number of input and the steps taken by the algorithm to process...]]></description><link>https://therustguy.com/bigo-notation-summarized</link><guid isPermaLink="true">https://therustguy.com/bigo-notation-summarized</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Python]]></category><category><![CDATA[Java]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Sat, 26 Jun 2021 17:54:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1624727612316/QZylW4E7v.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624724016690/RMGYBzeOG.png" alt="Instagram post - 9.png" />
<code>Big(O)</code> is the way in which we compare algorithmic complexities of two programs in a standard manner</p>
<p><code>Big(O)</code> is an algorithmic complexity metric, which defines the relationship between the number of input and the steps taken by the algorithm to process those inputs.</p>
<p>In summary <code>big(O)</code> measure, the amount of work a program has to do as the input scales.
<code>Big(O)</code> in other can be used to define both time and space complexities</p>
<p><strong>Table of Big(O) starting from best case scenarios to worst case scenarios.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624724308842/5FcaIFvQ0.png" alt="Instagram post - 10.png" /></p>
<p><strong>HOW TO CALCULATE TIME COMPLEXITY USING BIG(O)</strong></p>
<p><strong>CONSTANT COMPLEXITY O(1)</strong></p>
<p>In a constant complexity, the steps taken to complete the execution of a program is always the same regardless of the size of its input.</p>
<p>An execution would be getting an element at a certain position in an array(like getting the alphabet <strong>D</strong> at the index of 3 in the array).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624724433931/fwr-uom7i.png" alt="Instagram post - 12.png" /></p>
<p>The above takes just one step to complete. The above example, the <code>getAlphabetAt</code> method gets a particular element at a constant position in an array.</p>
<p>No matter how many Alphabet there are in the array the <code>getAlphabetAt</code> method always performs two steps. </p>
<ul>
<li><p>First, get the element at a certain position.</p>
</li>
<li><p>Second, <code>console.logs()</code> the result to the console.</p>
</li>
</ul>
<p>Hence, we can say. The complexity is constant as it doesn’t scale with the input.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624725192269/i8DlFPPM_.png" alt="Instagram post - 13.png" /></p>
<p><strong>LINEAR COMPLEXITIES O(N)</strong></p>
<p>In algorithms with linear complexity a single unit increase in the input causes a unit increase in the steps required to complete the program execution.</p>
<p>An example would be calculating power of every element in an array.</p>
<p>This would be linear because as the array grows it would do one unit more of more of that element.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624725293584/TJaGQuVfM.png" alt="Instagram post - 14.png" /></p>
<p>The above method <code>getCubicValues()</code> will take 3 steps to complete. </p>
<p>So, for each of them in the array passed as a params to <code>getCubicValues()</code> method, the method finds the cube of each of the item in the array and then logs it to the console.</p>
<p>Functions with linear complexity is represented by straight-line graphs increase in position directions.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624725510971/TYRcIspqh.png" alt="Instagram post - 15.png" /></p>
<p><strong>QUADRATIC COMPLEXITY</strong> </p>
<p>In an algorithm with quadratic complexity, the output steps increase quadratically with the increase in the inputs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624725609162/vAtAJ59Qs.png" alt="Instagram post - 16.png" /></p>
<p>In the above graphical example, the <code>getProductValue</code> method multiplies each element in that array with other elements.</p>
<p>There are two loops, where the outer loop it rates through each item, and for each of the item in the outer loop, and the inner loop also iterates over each item.</p>
<p>This makes the number of steps to be <code>N*N</code> where <code>N</code> is the number of elements in the array</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624725945180/eC3massH4.png" alt="Instagram post - 17.png" /></p>
<p><strong>BIG(O) NOTATION FOR SPACE COMPLEXITY</strong></p>
<p>In other to get the space complexity, we calculate the amount of space needed by the algorithms for the input element.</p>
<p><strong>BEST VS WORST CASE SCENERIOS IN COMPLEXITIES</strong></p>
<p><strong>There are two types of complexities</strong></p>
<ul>
<li><p>Best case scenarios </p>
</li>
<li><p>Worst case scenarios</p>
</li>
</ul>
<p><strong>BEST CASE SCENARIOS</strong></p>
<p>This is the complexity of an algorithm in an ideal situation. </p>
<p>An example would be, let’s say we want to search for an item <code>A</code> in an array of <code>N</code> items.</p>
<p>In the best-case scenarios, it would be that we found the item at the fist index in which we can say the complexity would be an <code>O(1)</code>.</p>
<p><strong>WORST CASE SCENARIOS</strong></p>
<p>In the worst case, lets assume we find the item at the <code>nth index</code> (last) in this case we can say the complexity would be an <code>O(N)</code> where <code>N</code> is the total number of items in the array.</p>
<p>In summary, and to round it all up, Algorithmic complexities are used as a tool to measure the performance of an algorithm in terms of time taken and space used.</p>
<p>Thank you for sticking with me through this. You Rock.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://media.giphy.com/media/BYoRqTmcgzHcL9TCy1/giphy.gif">https://media.giphy.com/media/BYoRqTmcgzHcL9TCy1/giphy.gif</a></div>
<p>If you enjoyed pls follow me on  <a target="_blank" href="https://twitter.com/chineduvictor7?s=09">Twitter</a>  and  <a target="_blank" href="https://www.instagram.com/chinedu._/?igshid=lyumzz45biao">Instagram</a> , if there are any improvements or code errors do let me know in the comment section below or send a dm.</p>
<p>Thanks once again and bye for now. Much Love❤❤❤.</p>
]]></content:encoded></item><item><title><![CDATA[JavaScript: How to implement a dictionary/map in 3mins.]]></title><description><![CDATA[Wait before you scream…. lol.
We do know that JavaScript isn’t a statically typed language. 
So how in the world can we implement dictionaries with it.
Well, stick with me champ! Because you are about to find out.

Up until ES6 when maps were created...]]></description><link>https://therustguy.com/javascript-how-to-implement-a-dictionarymap-in-3mins</link><guid isPermaLink="true">https://therustguy.com/javascript-how-to-implement-a-dictionarymap-in-3mins</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Angular]]></category><category><![CDATA[algorithms]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Mon, 18 Jan 2021 07:02:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1610953315806/ecJPKXSVx.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610935616837/SvcuyoF-M.png" alt="stacks post HEADING (7).png" />
Wait before you scream…. lol.</p>
<p>We do know that JavaScript isn’t a statically typed language. </p>
<p>So how in the world can we implement dictionaries with it.</p>
<p>Well, stick with me champ! Because you are about to find out.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610935903671/6Al6nhgOw.gif" alt="giphy (2).gif" /></p>
<p>Up until ES6 when maps were created. JavaScript had no native support for dictionaries.</p>
<p>But there was a flexible way of implementing a dictionary using the JavaScript object.</p>
<p>This may sound funny to people coming from other statically typed languages, but this is true and its because JavaScript gives us flexible ways to use objects because it’s a dynamically typed language.</p>
<p><strong>Introduction</strong></p>
<p><strong>What is a Dictionary?</strong></p>
<p>A dictionary can also be called a map in JavaScript, and maps/dictionaries are used to store unique elements of key-value pairs.</p>
<p>They are similar to the <code>set</code> data structure only that the set data structure stores a unique element of <code>value value</code> pairs.</p>
<p>Thanks to es6(ECMAScript 6) JavaScript now has an implementation of a map which could also be interchangeably called dictionaries.</p>
<p><strong>Let’s implement a map/dictionary shall we?</strong></p>
<p>If you are a constant reader of mine, you’d know that we as always implement the skeletal structure of our class so as to keep us on track and guide.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">dictionaryOrMap</span> </span>{
    <span class="hljs-keyword">constructor</span>(){
        <span class="hljs-built_in">this</span>.element = {}
    }

    <span class="hljs-comment">//methods go here</span>
    has(key)
    set(key, value)
    remove(key)
    get(key)
    clear()
    size()
    keys()
    values()
}
</code></pre>
<p>Taking a look at our class constructor property, we see that we are going to be storing our element in a JavaScript object. </p>
<p>This is unlike the <code>stacks</code> and <code>queues</code> where we used an <code>array</code>.</p>
<p>Let’s start implementing each methods of our dictionary class.</p>
<p><strong>has</strong></p>
<p>The <code>has</code> method <code>returns</code> <code>true</code> if the key exists and <code>false</code> if the key does not. </p>
<p>The <code>has</code> method is a utility method that will play a vital role in helping us implement the methods of our dictionary/map class.</p>
<p>To implement this function, we use the <code>for…in</code> loop to iterate all the properties of our objects. </p>
<p>To understand and dive deeper into how the <code>for..in</code> loop works checkout the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in">Mozilla Doc</a>.</p>
<pre><code class="lang-js">has(key){
    <span class="hljs-keyword">return</span> key <span class="hljs-keyword">in</span> <span class="hljs-built_in">this</span>.element
}
</code></pre>
<p>So, what the <code>has</code> method does for us is to verify if we truly have the key as a property in our object.</p>
<p><strong>set</strong></p>
<p>This method adds a new element to the dictionary. </p>
<p>The set method receives a <code>key-value</code> parameter. </p>
<p>Then we use our passed in <code>value</code> and set it to the <code>key</code> of our element object.</p>
<pre><code class="lang-js">set(key, value){
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.element[key] = value
}
</code></pre>
<p>As simple as that.</p>
<p><strong>delete</strong></p>
<p>This method uses the <code>key</code> to remove a value from the dictionary. </p>
<p>To implement this method, we first have to search for the <code>key</code>. </p>
<p>Then we use JavaScript’s <code>delete</code> property or method to remove the <code>key</code> attribute from our element object.</p>
<p>In a case where we delete, we want to return <code>true</code> but, in a case, where we don’t, we want to return <code>false</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">delete</span>(key){
    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.has(key)){
        <span class="hljs-keyword">delete</span> <span class="hljs-built_in">this</span>.element[key]
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
}
</code></pre>
<p><strong>get </strong></p>
<p>The <code>get</code> method helps us to <code>return</code> a specific value by the <code>key</code> we passed into our method.</p>
<pre><code class="lang-js">get(key){
    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.has(key)){
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.element[key]
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">undefined</span>
}
</code></pre>
<p><strong>values</strong></p>
<p>The <code>values</code> method returns all our <code>values</code> in the <code>element</code> object of our dictionary in an array.</p>
<p>There are two ways of implement this method we would see the both of them in this section.</p>
<p><strong>The first method</strong></p>
<p>First off, we want to loop through all the <code>elements</code> in our object, this tells us that we actually have <code>values</code> in our dictionary.</p>
<p>Then we would employ the <code>has</code> method once again to verify the <code>keys</code>. </p>
<p>If they do not exist then we <code>push</code> them into the <code>array</code> and <code>return</code> all the <code>values</code>.</p>
<blockquote>
<p>Note: we verify the keys because the object prototype contains additional properties of its own.</p>
</blockquote>
<pre><code class="lang-js">values(){
    <span class="hljs-keyword">let</span> values = []
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> k <span class="hljs-keyword">in</span> <span class="hljs-built_in">this</span>.element){
        <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.has(k)){
            values.push(<span class="hljs-built_in">this</span>.element[k])
        }
    }
    <span class="hljs-keyword">return</span> values
}
</code></pre>
<p><strong>The second method</strong></p>
<p>For the second method we use <code>Object.values</code> to get all the values of our dictionary.</p>
<pre><code class="lang-js">values(){
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.values(<span class="hljs-built_in">this</span>.element)
}
</code></pre>
<p>Which method do you prefer? Let me know in the comments 😉😉😉😉.</p>
<p><strong>key</strong></p>
<p>This method <code>returns</code> the <code>array</code> of all the <code>keys</code> in our dictionary.</p>
<p>In other to achieve this we use the <code>Object.keys</code>, and passing in our object’s element as a parameter.</p>
<pre><code class="lang-js">Key(){
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.keys(<span class="hljs-built_in">this</span>.element)
}
</code></pre>
<p><strong>size</strong></p>
<p>This gives us the number of elements that are contained in our dictionary, this is similar to the <code>length</code> property of an array.</p>
<pre><code class="lang-js">size(){
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.keys(<span class="hljs-built_in">this</span>.element).length
}
</code></pre>
<p><strong>clear</strong></p>
<p>This method removes all the elements from the dictionary just like its name sounds.</p>
<pre><code class="lang-js">clear(){
     <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.element = {}
}
</code></pre>
<p>With this, we have completely implemented or dictionary. </p>
<blockquote>
<p>Dictionary or maps should be used whenever we are trying to solve a problem that has to be unique(element) and needs to be in a key-value pair format.</p>
</blockquote>
<p><strong>Let’s Test out our Dictionary</strong></p>
<p>First, we instantiate our <code>class</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> map = <span class="hljs-keyword">new</span> dictionaryOrMaps()
</code></pre>
<p>Let’s test the <code>set</code> method</p>
<pre><code class="lang-js">map.set(<span class="hljs-string">"Vivian"</span>, <span class="hljs-string">"African"</span>)
map.set(<span class="hljs-string">"Shalom"</span>, <span class="hljs-string">"Hispanics"</span>)
map.set(<span class="hljs-string">"Gideon"</span>, <span class="hljs-string">"Caucasian"</span>)
</code></pre>
<p>Let’s test the <code>has</code> method</p>
<pre><code class="lang-js"><span class="hljs-comment">//The result should be true</span>
<span class="hljs-built_in">console</span>.log(map.has(<span class="hljs-string">"Vivian"</span>))
</code></pre>
<p>Let’s test our <code>size</code> method</p>
<pre><code class="lang-js"><span class="hljs-comment">//The result should be 3</span>
<span class="hljs-built_in">console</span>.log(map.size())
</code></pre>
<p>Let’s test our <code>keys</code> method</p>
<pre><code class="lang-js"><span class="hljs-comment">//Result =&gt; ["Vivian", "Shalom", "Gideon"]</span>
<span class="hljs-built_in">console</span>.log(map.keys())
</code></pre>
<p>Let’s test our <code>values</code> method</p>
<pre><code class="lang-js"><span class="hljs-comment">//Result =&gt; ["African", "Hispanics", "Caucasian"]</span>
<span class="hljs-built_in">console</span>.log(map values())
</code></pre>
<p>Let’s test the <code>get</code> method</p>
<pre><code class="lang-js"><span class="hljs-comment">//Result =&gt; ["African"]</span>
<span class="hljs-built_in">console</span>.log(map.get(<span class="hljs-string">"Vivian"</span>))
</code></pre>
<p>Let’s test the <code>remove</code> method</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(map.remove(<span class="hljs-string">"Vivian"</span>))
</code></pre>
<p>Finally, let's test to see if the <code>key</code> and its <code>value</code> were removed and if the <code>size</code> was reduced too.</p>
<pre><code class="lang-js"><span class="hljs-comment">//Results</span>
<span class="hljs-comment">//["shalom", "Gideon"]</span>
<span class="hljs-comment">//["Hispanics", "Caucasian"]</span>
<span class="hljs-comment">//2</span>

<span class="hljs-built_in">console</span>.log(map.keys())
<span class="hljs-built_in">console</span>.log(map.values())
<span class="hljs-built_in">console</span>.log(map.size())
</code></pre>
<p>Hey you, yes you champ! Thanks for hanging in with me till the very last moment. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610951687270/ECP_YdQZc.gif" alt="giphy (3).gif" /></p>
<p>If you enjoyed pls follow me on <a target="_blank" href="https://twitter.com/chineduvictor7?s=09">Twitter</a> and <a target="_blank" href="https://instagram.com/chinedu._?igshid=lyumzz45biao">Instagram</a>, if there are any improvements or code errors do let me know in the comment section below or a dm. </p>
<p>Thanks once again and bye for now. Much Love❤❤❤.</p>
]]></content:encoded></item><item><title><![CDATA[What is a TCP?]]></title><description><![CDATA[Introduction
I decided to write about something a little bit fun something that’s not data structures and algorithms, guys pls if you find value in this and love this sort of content do let me know.
Today we are going to talk about TCP this would be ...]]></description><link>https://therustguy.com/what-is-a-tcp</link><guid isPermaLink="true">https://therustguy.com/what-is-a-tcp</guid><category><![CDATA[backend]]></category><category><![CDATA[Python]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Java]]></category><category><![CDATA[Go Language]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Fri, 15 Jan 2021 02:33:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1610677874794/rQI0OccJ5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610677751641/y4kRPtojo.png" alt="stacks post HEADING (6).png" />
<strong>Introduction</strong></p>
<p>I decided to write about something a little bit fun something that’s not data structures and algorithms, guys pls if you find value in this and love this sort of content do let me know.</p>
<p>Today we are going to talk about TCP this would be an overview from a software engineering perspective. </p>
<p>Let’s go…</p>
<p><strong>What’s is TCP?</strong></p>
<p>TCP stands for (transmission control protocol).  </p>
<p>TCP and UDP are both layer 4(Transport Layer) protocols of the OSI Model. </p>
<p>TCP allows for transmission of information in both directions. This means that computer systems that communicate over TCP can send and receive data at the same time making use of the IP address and port</p>
<p>TCP is used in a lot of applications example: databases, secure chatting apps, etc. </p>
<p><strong>Let’s see some examples of TCP in real-life…
</strong>
HTTP (world wide web)
SSH (Secure Shell)
E-mail (SMTP TCP)
File Transfer Protocol (FTP)</p>
<p><strong>Why is TCP used</strong></p>
<p>TCP was created so that it would be a reliable, and straightforward way to pass data around without ending up with a scrambled or lost data, this way software engineers do not need to write code to handle this situation. Thereby allowing them to focus on application logic.</p>
<p><strong>Let’s look at some characteristics Advantages of TCP.</strong></p>
<p><strong>Acknowledgment/Confirmation</strong></p>
<p>Let’s use an example to explain this. Due to the unreliability of the internet, a lot of things can happen to data on transit from client to server. </p>
<p>We need some sort of confirmation that the data we have sent has gotten to its destination. </p>
<p>TCP is able to do this by attaching additional information to the data that’s being sent.
If our client doesn’t receive this confirmation it doesn’t accept the data.</p>
<p><strong>Retransmission</strong></p>
<p>In a situation where our client did not receive a confirmation from the server the TCP (transmission control protocol) does the job of informing the server that the data wasn’t received so that the data is resent.</p>
<p>This is called RETRANSMISSION where it keeps sending the data until it knows that we have received it.</p>
<p>This is often a tradeoff. Because of the guaranteed delivery capability of TCP, it tends to be slow.</p>
<p><strong>Connection</strong>
For a client to communicate with the server, a unique connection is needed. TCP uses the IP to establish a stateful connection.</p>
<p>This is why it is able to carry out retransmission and acknowledgment/confirmation. This is how the server knows that it has a client that it needs to send data to.</p>
<p><strong>Congestion control mechanism</strong></p>
<p>The TCP stops once there is a lot of traffic and waits for when there is less traffic then it resumes sending the data.</p>
<p>This is because on the internet there is a lot of packets/information/data going around, so our packets get delayed when the server is overwhelmed.</p>
<p>This happens when a lot of people are sending packets all over the internet.</p>
<p><strong>Packets Ordering</strong></p>
<p>Because the internet does not guarantee that the packets you send would be received in an orderly manner.</p>
<p>TCP has the capability of ordering our packets, by adding identifiers to our packets or data, so this is what it does to enable it to order our packets.</p>
<p>An example of this would be sending a long-detailed email to a friend, what TCP does, in this case, is to break this data into smaller pieces and then orders them. </p>
<p>This helps them to arrive on the server in an orderly manner and prevents unnecessary data loss.</p>
<p><strong>Let’s see some characteristics Disadvantages of TCP.
</strong></p>
<p><strong>Large Packet size</strong></p>
<p>TCP usually ends up with larger packet sizes, this is due to all the extra identifiers and informations it adds to the data that it sends. </p>
<p>These identifiers help it achieve retransmission, packet ordering, congestion control, etc.</p>
<p><strong>Larger Bandwidth</strong></p>
<p>With larger packet size comes more bandwidth.</p>
<p><strong>Slow</strong></p>
<p>The delay involved with TCP is due to things like packet ordering, congestion control, retransmission, acknowledgment/confirmation, etc. Basically the advantages of the TCP are the actually things that makes it slow.</p>
<p><strong>Stateful</strong></p>
<p>TCP is stateful, this is because the server and client carries info information about the connection.</p>
<p>So, if in any way the server or client is closed our connection is lost.</p>
<p><strong>Server memory</strong></p>
<p>The server stacks up the TCP connection and allocates memory for each of these connections. </p>
<p>The server has to keep listening so that it knows when it receives data from any part of the connection.</p>
<p>This is possible because of the statefulness and connection-based characteristics of the TCP.</p>
<p>So, in a situation when someone tries to establish a connection to the server using the TCP. </p>
<p>Due to the fact that the server does some kind of waiting, because of the connection, acknowledgment/confirmation, retransmission, guaranteed delivery, packet ordering and congestion control, a bad-client uses these features against the server to create a kind of DENIAL OF SERVICE attack (DOS).</p>
<p>So, this bad client keeps sending a connections request, without letting the server go through the normal process of acknowledgment, retransmission, etc.</p>
<p>This keeps the server waiting until there is a timeout, and the server crashes, this is a very simple explanation of how DOS is perpetuated.</p>
<p>The layer 4 or otherwise called the transport layer also has another transport protocol called UDP (User Datagram protocol). </p>
<p>In another article we would be touching in this. </p>
<p>Until then stayed tuned!!!</p>
<p>With this, we have come to the end of this article.</p>
<p>Guys as always thanks for being here with me. I really appreciate it. </p>
<p>And if you found any sort of value in this please leave a comment share it on Twitter it really does help get the word out so that other devs can find value in it.</p>
<p>Once again thank you for sparing the time to read this article. </p>
<p>If you’d love me to implement a TCP server using NodeJS. </p>
<p>Do let me know and I will do just that.</p>
<p>Much Love.❤❤❤</p>
]]></content:encoded></item><item><title><![CDATA[JavaScript: How to implement the linked list data structure (part3)]]></title><description><![CDATA[Introduction
Continuing the series of our data structures and algorithm. 
In this article I will be teaching you how to implement a popular data structure called the linked list.
Hey dude…this is going to be a long one grab that cup of coffee, tea or...]]></description><link>https://therustguy.com/javascript-how-to-implement-the-linked-list-data-structure-part3</link><guid isPermaLink="true">https://therustguy.com/javascript-how-to-implement-the-linked-list-data-structure-part3</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[React]]></category><category><![CDATA[Angular]]></category><category><![CDATA[Vue.js]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Sun, 10 Jan 2021 18:28:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1610303057141/CRn_3jDoI.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610239543347/hQojxrqDC.png" alt="stacks post HEADING (2).png" />
Introduction</p>
<p>Continuing the series of our data structures and algorithm. </p>
<p>In this article I will be teaching you how to implement a popular data structure called the linked list.</p>
<p><strong>Hey dude…this is going to be a long one grab that cup of coffee, tea or whatever it is you guys drink these days…maybe a bottle of beer. Looooooooooool.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610239775659/MVmII-ACv.gif" alt="Zw3oBUuOlDJ3W.gif" /></p>
<p>What is a linked list?</p>
<p>A linked list is a data structure that permits insertion and deletion of items from it and would grow accordingly.</p>
<p>Each element in the linked-list consist of a node that stores the element itself and a reference which is also called a link/pointer to the next element.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610240078145/8IN4vN7Pq.gif" alt="ofegPosyLt5FS.gif" /></p>
<p>Let's look at some examples of a linked list</p>
<p>Let's use a conga line as an example.</p>
<p>The above gif is an example of a conga line. </p>
<p>Each person on the conga line is to an element on the linked-list and their hands are to the reference (pointer/link) on the linked-list.</p>
<p>Each person's hands on the linked-list servers as a link to the next person, this is the same for our linked-list with each node's pointer serving as a link to the next nodes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610240479144/UItbkmB32.png" alt="stacks post HEADING (3).png" /></p>
<p>It is worth pointing out that there are 4 types of linked-list.</p>
<ol>
<li><p>Singly linked list</p>
</li>
<li><p>Doubly linked list</p>
</li>
<li><p>Circular linked list</p>
</li>
<li><p>Doubly circular linked list</p>
</li>
</ol>
<p>In this article, we would be implementing only the singly linked list and in a later article we would be implementing a doubly-linked list. </p>
<p>This is because if you can implement the singly linked list and the doubly linked list, you can easily implement the Circular linked list and the Doubly circular linked list with little explanation.</p>
<p>Before implementing the singly linked list. Let's quickly explain the different types of linked lists.</p>
<p>Singly-linked list</p>
<p>This is the most commonly used linked list. In a singly linked list, each node contains two parts.</p>
<p>One part is the element and the other is a reference (pointer/link) to the next node.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610240637743/pXdVuIp00.jpeg" alt="Screenshot (260)_1610212734335.jpg" /></p>
<p>Doubly linked list</p>
<p>In the doubly linked list, each node contains three parts.</p>
<p>One part in the doubly linked list contains a link to the next node and the other part has the link to the previous node.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610240692632/3Hxwq3erW.jpeg" alt="Screenshot (261)_1610212794819.jpg" /></p>
<p>Circular linked list</p>
<p>In a circular linked list, each node contains two parts just like the singly linked list.</p>
<p>The difference between a circular linked list and a singly linked list is that the last nodes element does not point to null, but instead points to head which is the first element on the list.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610240743969/CkGqhLHMc.jpeg" alt="Screenshot (264)_1610213068570.jpg" /></p>
<p>Doubly circular linked list</p>
<p>The doubly circular linked is similar to the double linked list because its nodes contain three parts.</p>
<p>One part pointing to the next node and the other pointing to the previous node.</p>
<p>It is also similar to the circular linked but with a slight difference being that the last node's elements points to the head while the head previous points to the tail.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610241247885/zj6rhhmvh.jpeg" alt="Screenshot (263)_1610213128884.jpg" /></p>
<p>For this tutorial, you can run your codes in your browser console or if you have node.js installed on your local machine, you can run your codes in vscode while using the integrated terminal provided by vscode.</p>
<p>Learn how to install node on windows, Mac, and Linux <a target="_blank" href="https://www.google.com/amp/s/www.freecodecamp.org/news/how-to-install-node-in-your-machines-macos-linux-windows/amp/">here</a>.</p>
<p>Now you understand the theory behind the types of the linked list.
Let's implement our linked list data structure.</p>
<p>Since we are using classes we would first create our Node class and our linked list skeleton.</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span> </span>{
     <span class="hljs-keyword">constructor</span>(element, next = <span class="hljs-literal">null</span>) {
       <span class="hljs-keyword">this</span>.element = element;
       <span class="hljs-keyword">this</span>.next = next;
  }
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinkedList</span> </span>{
   <span class="hljs-keyword">constructor</span>(){
     <span class="hljs-keyword">this</span>.head = <span class="hljs-literal">null</span>;
     <span class="hljs-keyword">this</span>.length = <span class="hljs-number">0</span>
   }
   <span class="hljs-comment">//methods go here</span>
   appendFirst(element){}
   appendLast(element){}
   removeAt(position, element){}
   insert(postion, element){}
   indexOf(element)
   remove(element)
   size()
   isEmpty()
   getHead()
   print()
}
</code></pre><p>Above we have our linked list class with a head property which is where we store the reference to our node. </p>
<p>And also a length property that stores the number of nodes in our linked list.
Let's start implementing our linked list methods.</p>
<p>appendFirst: this method adds a node to the beginning of our linked list.</p>
<p>The insert method takes an element. </p>
<p>Then in this method we instantiate our node and store it in a variable called head, passing in the element which our function received and this.head as the second value of our node class.</p>
<p>Then we set our head variable as the head(this.head) of our linked list.
Then we increment the size.</p>
<pre><code>appendFirst(element){
   let head = new Node(element, <span class="hljs-keyword">this</span>.head)
     <span class="hljs-keyword">this</span>.head = head
     <span class="hljs-keyword">this</span>.length++
}
</code></pre><p>We put the this.head in our instantiated class, because if there is already a node in the linked list head(this.head), then when adding another node to the list we push the present node to the next, but if the head(this.head) is empty then the node we are adding becomes the only node on the list.</p>
<p>for the sake of this article, I used vscode, and I created a file called index.js(you can name yours with any name of your choice).</p>
<p>Using the vscode integrated terminal would enable us to test and run our codes.</p>
<p>Image(include screenshot image of vscode)</p>
<p>Test</p>
<pre><code>    <span class="hljs-comment">//instantiating our inked list class</span>
    let <span class="hljs-keyword">list</span> = <span class="hljs-keyword">new</span> LinkedList()

    <span class="hljs-comment">//using the append first method of the linked list class</span>
    <span class="hljs-keyword">list</span>.appendFirst(<span class="hljs-number">10</span>)
    <span class="hljs-keyword">list</span>.appendFirst(<span class="hljs-number">15</span>)

    Run in terminal
    node index

    <span class="hljs-comment">// head: Node { element: 15, next: Node { element: 10, next: null } },</span>
    <span class="hljs-comment">// length: 2</span>
    <span class="hljs-comment">// }</span>
</code></pre><p>Before continuing the implementation of our linked list methods, let's implement the print method.</p>
<p>Print: this method enables us to log our linked list element more neatly and conveniently to the console.</p>
<p>In our print method, we set a variable of current to represent the head of our node.</p>
<pre><code>print() {
   let <span class="hljs-keyword">current</span> = this.head
   <span class="hljs-keyword">while</span> (<span class="hljs-keyword">current</span>) {
   console.log(<span class="hljs-keyword">current</span>.element)
   <span class="hljs-keyword">current</span> = <span class="hljs-keyword">current</span>.next
   }
}
</code></pre><p>Then we loop through all the nodes using the while loop and in the while loop, we log the current element because we just want the element property.</p>
<p>Then we loop through the nodes by setting the current variable to current.next.</p>
<p>By so doing we simply outputting each element in our linked list.</p>
<p>Test</p>
<pre><code>   <span class="hljs-comment">// add another element to the linked list</span>
   <span class="hljs-keyword">list</span>.appendFirst(<span class="hljs-number">15</span>)
   <span class="hljs-keyword">list</span>.appendFirst(<span class="hljs-number">20</span>)

   <span class="hljs-comment">//Run the print method</span>
   <span class="hljs-keyword">List</span>.<span class="hljs-keyword">print</span>()

   <span class="hljs-comment">//result logged to the console.</span>
   <span class="hljs-number">25</span> <span class="hljs-number">20</span> <span class="hljs-number">15</span> <span class="hljs-number">10</span>
</code></pre><p>appendLast: This adds a node to the end of the linked list,</p>
<p>Things to look out for</p>
<ol>
<li><p>When the list is empty and we want to add an element.</p>
</li>
<li><p>When the list is not empty and we want to add an element to it</p>
</li>
</ol>
<p>For this method, the first thing we do is to create our node instance and pass in our element value.</p>
<p>After that, we define a variable current for internal controls</p>
<pre><code>Let node = <span class="hljs-built_in">new</span> Node(element)
Let <span class="hljs-keyword">current</span>;
</code></pre><p>After this, we want to implement our first case, which is when the list is empty and we want to add an element to the list.</p>
<p>So, we point our head to our node if our head element is null. Since our head element is null this automatically means we are adding our first element to the list.</p>
<pre><code>If(<span class="hljs-keyword">this</span>.head === <span class="hljs-literal">null</span>){
   <span class="hljs-keyword">this</span>.head = node
}<span class="hljs-keyword">else</span>{}
</code></pre><p>Let's implement the second case when we are adding an element to the list if it's not empty.</p>
<p>So, first in our else block, we create a reference to our head.</p>
<p>Then we iterate through the list until the last element on the list is found.</p>
<pre><code>…}<span class="hljs-keyword">else</span>{
   <span class="hljs-keyword">Current</span> = this.head
   <span class="hljs-keyword">While</span>(<span class="hljs-keyword">current</span>.next){
   <span class="hljs-keyword">Current</span> = <span class="hljs-keyword">current</span>.next
}
</code></pre><p>When looping the list we know we have reached the last element only when the current.next is null.</p>
<p>So all we have left to do is linking the current element to the node we want to add to the list.</p>
<pre><code><span class="hljs-attr">Current.next</span> = node
</code></pre><p>Then finally we want to increment the length of the list so as to keep track of how many elements we have on the list.</p>
<pre><code>Length++
</code></pre><p>Below is the complete code for the appendLast method of our linked list.</p>
<pre><code>appendLast(element){
   let node = new Node(element)
   let current;
   <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.head === <span class="hljs-literal">null</span>) {
      <span class="hljs-keyword">this</span>.head = node;
   } <span class="hljs-keyword">else</span> {
   current = <span class="hljs-keyword">this</span>.head
      <span class="hljs-keyword">while</span> (current.next) {
   current = current.next
  }
   current.next = node
  }
   <span class="hljs-keyword">this</span>.length++
}
</code></pre><p>removeAt: this method removes an element from the list at a specified position.</p>
<p>Things to look out for</p>
<ol>
<li><p>Removing the first element</p>
</li>
<li><p>Removing any element that's not the first</p>
</li>
</ol>
<p>The first step is creating a method that would take the position of the element to be removed from the list.</p>
<pre><code><span class="hljs-selector-tag">removeAt</span>(positon){
}
</code></pre><p>Next using a conditional we want to check that the position we are passing in is valid.</p>
<p>If the position is valid, we would stem from 0 to the length of the list.</p>
<p>While a value that's is not valid would return a string saying "not a valid position on the linked list"</p>
<pre><code><span class="hljs-keyword">if</span>(position &gt; -<span class="hljs-number">1</span> &amp;&amp; position &lt; <span class="hljs-keyword">this</span>.length){
   } <span class="hljs-keyword">else</span> {
   Return <span class="hljs-string">"not a valid position on the linked list"</span>
}
</code></pre><p>Let's handle the first case which is removing the first element on the list.</p>
<p>Before doing that we make reference to the first element on the list using the current variable and also declaring other variables such as previous and index which would initially be 0.</p>
<p>All this would be very helpful for internal controls.</p>
<pre><code>Let <span class="hljs-keyword">current</span> = this.head
<span class="hljs-keyword">Index</span> = <span class="hljs-number">0</span>
Previous
</code></pre><p>Removing the first element on the list, we use a conditional, saying where the position is 0, we want to set the head to the second element on our list.</p>
<p>So to remove the head element we would point the head to the current.next.</p>
<pre><code>If(position === <span class="hljs-number">0</span>){
   <span class="hljs-keyword">this</span>.head = current.next
}<span class="hljs-keyword">else</span>{}
</code></pre><p>Let's handle the second case where we want to remove an element from the end or middle of the list.</p>
<p>In other to achieve this we have to loop the list until we get the position we are looking for.</p>
<p>Then we set our previous to current and our current to current.next.</p>
<pre><code><span class="hljs-keyword">While</span>(<span class="hljs-keyword">index</span>++ &lt; position){
   Previous = <span class="hljs-keyword">current</span>
   <span class="hljs-keyword">Current</span> = <span class="hljs-keyword">current</span>.next
}
</code></pre><p>Then outside our while block, we can remove the current element from the linked list.</p>
<p>All we do is to link the previous.next to the current.next.</p>
<pre><code><span class="hljs-attr">Previous.next</span> = current.next
</code></pre><p>Then we decrement our list.</p>
<pre><code>length<span class="hljs-comment">--</span>
</code></pre><p>Note: This method works well for removing both the last and middle elements.</p>
<p>Test</p>
<pre><code>   <span class="hljs-comment">//test if it is a valid position on the list</span>
   <span class="hljs-comment">//result =&gt; not a valid position on the list</span>
   console.<span class="hljs-built_in">log</span>(<span class="hljs-built_in">list</span>.removeAt(<span class="hljs-number">20</span>))

   <span class="hljs-comment">//test for removing the head from the list</span>
   Run
   <span class="hljs-comment">//result =&gt; 20 15 10 100</span>
   <span class="hljs-comment">// 25 at index 0 was removed</span>
   <span class="hljs-built_in">list</span>.removeAt(<span class="hljs-number">0</span>)

   Run
   <span class="hljs-comment">//test for removing the last element from the list</span>
   <span class="hljs-comment">//the last element on the list is the element with the index of 4 which is 100</span>
   <span class="hljs-comment">//result =&gt; 25 20 15 10</span>
   <span class="hljs-built_in">list</span>.removeAt(<span class="hljs-number">4</span>)

   Run
   <span class="hljs-comment">//test for removing the middle element from the list</span>
   <span class="hljs-comment">//we choose element at index 2 which is 15</span>
   <span class="hljs-comment">//result =&gt; 25 20 10 100</span>
   <span class="hljs-built_in">list</span>.removeAt(<span class="hljs-number">2</span>)
</code></pre><p>Below Is the complete code snippet for our removeAt method.</p>
<pre><code>removeAt(position){
   <span class="hljs-keyword">if</span> (position &gt; <span class="hljs-number">-1</span> &amp;&amp; position &lt; this.length) {
     let <span class="hljs-keyword">current</span> = this.head;
     let <span class="hljs-keyword">index</span> = <span class="hljs-number">0</span>;
     let previous;
    <span class="hljs-keyword">if</span> (position === <span class="hljs-number">0</span>) {
     this.head = <span class="hljs-keyword">current</span>.next
    } <span class="hljs-keyword">else</span> {
     <span class="hljs-keyword">while</span> (<span class="hljs-keyword">index</span>++ &lt; position) {
      previous = <span class="hljs-keyword">current</span>
      <span class="hljs-keyword">current</span> = <span class="hljs-keyword">current</span>.next
   }
     previous.next = <span class="hljs-keyword">current</span>.next
   }
   this.length<span class="hljs-comment">--</span>
   } <span class="hljs-keyword">else</span> {
     <span class="hljs-keyword">return</span> "the position is not valid"
   }
}
</code></pre><p>Insert: this method inserts a new element to a position on the list.</p>
<p>Things to look out for</p>
<ol>
<li><p>Inserting an element to the first position of the list</p>
</li>
<li><p>Inserting an element at the end or middle of the list</p>
</li>
</ol>
<p>The first step to take is creating a method that takes a position and an element to be inserted.</p>
<pre><code><span class="hljs-keyword">Insert</span>(<span class="hljs-keyword">position</span>, <span class="hljs-keyword">element</span>){
}
</code></pre><p>Next, we need to do what we did for the removeAt method, since our method is taking values for the position, we want to insert the element, we need to make sure these values are not out of bound.</p>
<p>We do this using a conditional and returning a string saying "no item was added"</p>
<pre><code><span class="hljs-keyword">If</span>(position &gt; = <span class="hljs-number">0</span> &amp;&amp; position &lt; = length){
   }<span class="hljs-keyword">else</span>{
     <span class="hljs-keyword">Return</span> "no items added"
}
</code></pre><p>Now, let's handle the first case where we are adding an element to the first position on the list.</p>
<p>But before going ahead with that let's instantiate our node class as well as create some variables for internal controls.</p>
<pre><code>Const node = <span class="hljs-built_in">new</span> Node(element)
Let <span class="hljs-keyword">current</span> = this.head
Let previous;
Let <span class="hljs-keyword">index</span> = <span class="hljs-number">0</span>
</code></pre><p>To add an element to the first position of the linked list, we set the node.next to the current.</p>
<p>And simply point the head to the node.</p>
<p>By so doing we have another element on the list.</p>
<pre><code><span class="hljs-keyword">If</span>(position === <span class="hljs-number">0</span>){
   node.<span class="hljs-keyword">current</span> = <span class="hljs-keyword">current</span>
   head = node
}<span class="hljs-keyword">else</span>{}
</code></pre><p>Handling the second case is inserting an element to the end, or the middle of our list.</p>
<p>The first thing we do Is loop the list until we get to the position where we want to insert an element.</p>
<p>We do this in our else block of code.</p>
<pre><code>…} <span class="hljs-keyword">else</span> {
   <span class="hljs-keyword">While</span>(<span class="hljs-keyword">index</span>++ &lt; position){
   previous = <span class="hljs-keyword">current</span>
   <span class="hljs-keyword">current</span> = <span class="hljs-keyword">current</span>.next
}
</code></pre><p>When we are out of the loop, the previous would be pointing to the element present before the position we want to insert a new element.</p>
<p>While the current variable would be pointing to the element present after the position where we would insert a new element, which is between the previous and current.</p>
<p>Then we need to link the new node and the current element.</p>
<pre><code><span class="hljs-attr">node.next</span> = current
</code></pre><p>After that we want to point the previous.next to node, by so doing we have successfully change the link between the previous and current.</p>
<pre><code><span class="hljs-attr">previous.next</span> = node
</code></pre><p>Then after that, we want to keep track of the length property of our linked list class.</p>
<p>Here we decrement the length and return a string saying "a value has been added to the list".</p>
<pre><code><span class="hljs-keyword">this</span>.length++
<span class="hljs-keyword">return</span> <span class="hljs-string">"a value has been added to the list"</span>
</code></pre><p>Test</p>
<pre><code>   <span class="hljs-comment">//let's insert an element to the first position on the list   //(index of 0)</span>
   <span class="hljs-comment">//current list is 25 20 15 10 100</span>
   <span class="hljs-comment">//after inserting we get 500 25 20 15 10 10</span>
   <span class="hljs-comment">//return "a value has been added to the list"</span>
   <span class="hljs-selector-tag">list</span><span class="hljs-selector-class">.insert</span>(<span class="hljs-number">0</span>, <span class="hljs-number">500</span>)


   <span class="hljs-comment">//let's insert to the middle of the list</span>
   <span class="hljs-comment">//current list is 25 20 15 10 100</span>
   <span class="hljs-comment">//after inserting we get 25 20 15 500 10 100</span>
   <span class="hljs-comment">//return "a value has been added to the list"</span>
   <span class="hljs-selector-tag">list</span><span class="hljs-selector-class">.insert</span>(<span class="hljs-number">3</span>, <span class="hljs-number">500</span>)


   <span class="hljs-comment">//let's insert to the end of the list</span>
   <span class="hljs-comment">//current list is 25 20 15 10 100</span>
   <span class="hljs-comment">//after inserting we get 25 20 15 10 100 500</span>
   <span class="hljs-comment">//return "a value has been added to the list"</span>
   <span class="hljs-selector-tag">List</span><span class="hljs-selector-class">.insert</span>(<span class="hljs-number">5</span>, <span class="hljs-number">500</span>)


   <span class="hljs-comment">//if we try to add to a position that's not on the list it won't be added we </span>
   <span class="hljs-comment">//just return the original list and a string saying "Not a valid position on the list".</span>
   <span class="hljs-selector-tag">console</span><span class="hljs-selector-class">.log</span>(list.insert(<span class="hljs-number">10</span>, <span class="hljs-number">500</span>))
</code></pre><p>Below is the complete code for our insert method.</p>
<pre><code><span class="hljs-keyword">insert</span>(<span class="hljs-keyword">position</span>, <span class="hljs-keyword">element</span>){
   <span class="hljs-keyword">if</span> (<span class="hljs-keyword">position</span> &gt;= <span class="hljs-number">0</span> &amp;&amp; <span class="hljs-keyword">position</span> &lt;= this.length) {
     let node = <span class="hljs-keyword">new</span> Node(<span class="hljs-keyword">element</span>)
     let <span class="hljs-keyword">current</span> = this.head
     let previous
     let <span class="hljs-keyword">index</span> = <span class="hljs-number">0</span>
   <span class="hljs-keyword">if</span> (<span class="hljs-keyword">position</span> === <span class="hljs-number">0</span>) {
     node.next = <span class="hljs-keyword">current</span>
     this.head = node
   } <span class="hljs-keyword">else</span> {
     <span class="hljs-keyword">while</span> (<span class="hljs-keyword">index</span>++ &lt; <span class="hljs-keyword">position</span>) {
       previous = <span class="hljs-keyword">current</span>
       <span class="hljs-keyword">current</span> = current.next
   }
      node.next = <span class="hljs-keyword">current</span>
      previous.next = node
   }
     this.length++
     <span class="hljs-keyword">return</span> <span class="hljs-string">"a value has been added to the list"</span>
   } <span class="hljs-keyword">else</span> {
     <span class="hljs-keyword">return</span> <span class="hljs-string">"not a valid position on the list"</span>
   }
 }
</code></pre><p>indexOf: this method returns the index of an element on the inked list. If there is no element it returns -1.</p>
<p>First, let's create the method and pass in the element as a value.</p>
<pre><code>indexOf(element) {
   <span class="hljs-keyword">Return</span> <span class="hljs-number">-1</span>
}
</code></pre><p>Next, in our method we set a variable current to head that would help us iterate the list, and a variable index to increment our count.</p>
<pre><code>Let <span class="hljs-keyword">current</span> = head
Let <span class="hljs-keyword">index</span> = <span class="hljs-number">0</span>
</code></pre><p>Then using a while loop we check if the element, we are looking for is the current one by looping through the list.</p>
<p>If the list is empty or we get to the end of the list we where current = current.next is null we would return -1</p>
<pre><code><span class="hljs-keyword">While</span>(<span class="hljs-keyword">current</span>){
   <span class="hljs-keyword">If</span>(element === <span class="hljs-keyword">current</span>.element){
   <span class="hljs-keyword">Return</span> <span class="hljs-keyword">index</span>
}
   <span class="hljs-keyword">Index</span>++
   <span class="hljs-keyword">Current</span> = <span class="hljs-keyword">current</span>.next
}
   <span class="hljs-keyword">Return</span> <span class="hljs-number">-1</span>
</code></pre><p>Note: Before testing the indexOf method make sure to clear all the instances where we passed in values for our appendFirst and appendLast methods.</p>
<p>This is just to prevent unnecessary confusion, after doing that you can go ahead and append values last to the empty linked list.</p>
<p>Test</p>
<pre><code>    <span class="hljs-comment">//first let's try to check for some values on the linked list</span>
    <span class="hljs-comment">//result is -1 this is because there are no values on the linked list (we //removed </span>
    <span class="hljs-comment">//themm all)</span>
    console.<span class="hljs-built_in">log</span>(<span class="hljs-built_in">list</span>.indexOf(<span class="hljs-number">20</span>))

    <span class="hljs-comment">//let's append some values using the appendLast method before checking for their  </span>
    <span class="hljs-comment">//index.</span>
    <span class="hljs-built_in">list</span>.appendLast(<span class="hljs-number">100</span>)
    <span class="hljs-built_in">list</span>.appendLast(<span class="hljs-number">200</span>)
    <span class="hljs-built_in">list</span>.appendLast(<span class="hljs-number">300</span>)
    <span class="hljs-built_in">list</span>.appendLast(<span class="hljs-number">400</span>)

    <span class="hljs-comment">//let's get the index of 100 and 200(you can go ahead and play around with getting </span>
    <span class="hljs-comment">//the index of 300 and 400)</span>
   <span class="hljs-comment">//results should be 0 and 1 which are the index of 100 and 200</span>
   console.<span class="hljs-built_in">log</span>(<span class="hljs-built_in">list</span>.indexOf(<span class="hljs-number">100</span>))
   console.<span class="hljs-built_in">log</span>(<span class="hljs-built_in">list</span>.indexOf(<span class="hljs-number">200</span>))

   <span class="hljs-comment">//let's check again for elements that are not on our list</span>
   <span class="hljs-comment">//results would be -1 because our list doesn't contain the element 500</span>
   console.<span class="hljs-built_in">log</span>(<span class="hljs-built_in">list</span>.indexOf(<span class="hljs-number">500</span>))
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610302523493/tJnaDGCAB.png" alt="stacks post HEADING (4).png" /></p>
<p>You could send me a DM with your solution on Twitter or Instagram.</p>
<p>With the index method implemented, we can implement the remove method of our linked list class.</p>
<p>Below is the complete code for our insert method.</p>
<pre><code>indexOf(element) {
   let <span class="hljs-keyword">current</span> = this.head,
   <span class="hljs-keyword">index</span> = <span class="hljs-number">0</span>
   <span class="hljs-keyword">while</span> (<span class="hljs-keyword">current</span>) {
     <span class="hljs-keyword">if</span> (element === <span class="hljs-keyword">current</span>.element) {
     <span class="hljs-keyword">return</span> <span class="hljs-keyword">index</span>;
  }
   <span class="hljs-keyword">index</span>++
   <span class="hljs-keyword">current</span> = <span class="hljs-keyword">current</span>.next
}
   <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>
}
</code></pre><p>Remove: this method removes an element from the list.</p>
<pre><code>Remove(element) {
   Let <span class="hljs-keyword">index</span> = this.<span class="hljs-keyword">index</span>(element)
   <span class="hljs-keyword">Return</span> this.removeAt(<span class="hljs-keyword">index</span>)
}
</code></pre><p>Taking a closer look you'd see that we are reusing the index and removeAt method. </p>
<p>To easily remove an element from the list.</p>
<p>So, if we pass an element value to our indexOf method and call the index in our removeAt method this removes the element from the list.</p>
<p>Test</p>
<pre><code><span class="hljs-comment">//lets try to remove and element that's not on the list</span>
<span class="hljs-comment">//result we just return the list</span>
<span class="hljs-selector-tag">list</span><span class="hljs-selector-class">.remove</span>(<span class="hljs-number">500</span>)


<span class="hljs-comment">//lets try to remove the element 200 of index 1</span>
<span class="hljs-comment">//results should be 100 300 400</span>
<span class="hljs-selector-tag">list</span><span class="hljs-selector-class">.remove</span>(<span class="hljs-number">200</span>)
</code></pre><p>isEmpty: this returns false if the size of the linked list is bigger than 0 and true if the linked list does not contain any element.</p>
<pre><code>isEmpty() {
   <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.length === <span class="hljs-number">0</span>
}
</code></pre><p>Size: this returns the number of elements that are contained in the linked list. </p>
<p>The length property is controlled internally since the linked list class is built from scratch.</p>
<pre><code>size() {
   <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.length;
}
</code></pre><p>getHead: this returns the heads property of the linked list class.</p>
<pre><code>getHead() {
   <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.head
}
</code></pre><p>There you have it we are done with implementing the linked list.</p>
<p>The linked list data structure is one of the most popular data structure and questions like <strong><em>reversing a linked list</em></strong> usually pop up in tech interviews, so it does help to completely understand the intricacies of how it works and how to implement it.</p>
<p>Guys pls it took quite a lot to make this article of over 3.5k words please share it with your friends on Twitter, Instagram, and Facebook. </p>
<p>This does help get the word out so that every other person can find value in it.</p>
<p>Once again thank you for sticking this long, with me on this one.</p>
<p>You can reach out to me on <a target="_blank" href="https://twitter.com/chineduvictor7?s=09">Twitter</a> or send a Dm on <a target="_blank" href="https://instagram.com/chinedu._?igshid=1k74afw43zteb">Instagram</a>. Much Love❤️❤️❤️❤️</p>
]]></content:encoded></item><item><title><![CDATA[70+ JavaScript library, frameworks, tools, and plugins]]></title><description><![CDATA[Hey and welcome to today's article 😊. 
I decided to put together some JavaScript library, frameworks, tools and plugins.
Some which I use in my projects. 
If you find them intriguing share it and save it for later.
Let's go…💃🕺💃🕺💃

LIBRARY AND F...]]></description><link>https://therustguy.com/70-javascript-library-frameworks-tools-and-plugins</link><guid isPermaLink="true">https://therustguy.com/70-javascript-library-frameworks-tools-and-plugins</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[Angular]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[React Native]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Tue, 05 Jan 2021 21:07:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1609879581103/_toIplANk.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="stacks-post-heading-1pnghttpscdnhashnodecomreshashnodeimageuploadv1609880051327-cwqexqf5png"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609880051327/-CWQEXQF5.png" alt="stacks post HEADING (1).png" /></h2>
<p>Hey and welcome to today's article 😊. </p>
<p>I decided to put together some JavaScript library, frameworks, tools and plugins.</p>
<p>Some which I use in my projects. </p>
<p>If you find them intriguing share it and save it for later.</p>
<p>Let's go…💃🕺💃🕺💃</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609880068955/HvfpzAePJ.gif" alt="giphy (1).gif" /></p>
<p><strong>LIBRARY AND FRAMEWORKS
</strong>
<strong>NodeJs</strong></p>
<p>Node.js is an open-source, cross-platform, back-end, JavaScript runtime environment that executes JavaScript code outside a web browser.</p>
<p><strong>ReactJs</strong></p>
<p>React is an open-source, front end, JavaScript library for building user interfaces or UI components. </p>
<p><strong>VueJs</strong></p>
<p>Vue.js is an open-source model–view–ViewModel front end JavaScript framework for building user interfaces and single-page applications.</p>
<p><strong>NextJs</strong></p>
<p>Next.js is an open-source React front-end development web framework that enables functionality such as server-side rendering and generating static websites for React-based web applications.</p>
<p><strong>Angular</strong></p>
<p>Angular is a TypeScript-based open-source web application framework</p>
<p><strong>Svelte</strong></p>
<p>Svelte is a free and open-source front end JavaScript framework</p>
<p><strong>Redux</strong></p>
<p>Redux is an open-source JavaScript library for managing application state.</p>
<p><strong>Meteor</strong></p>
<p>Meteor, or MeteorJS, is a free and open-source isomorphic JavaScript web framework written using Node.js.</p>
<p><strong>Backbone.js</strong></p>
<p>Backbone.js is a JavaScript library with a RESTful JSON interface and is based on the model–view–controller application design paradigm.</p>
<p><strong>Ember.js</strong></p>
<p>Ember.js is an open-source JavaScript web framework, utilizing a component-service pattern.</p>
<hr />
<p><strong>VISUALIZATION</strong></p>
<p><strong>Three.js</strong></p>
<p>Three.js is a cross-browser JavaScript library and application programming interface used to create and display animated 3D computer graphics in a web browser using WebGL.</p>
<p><strong>D3.js</strong></p>
<p>D3.js is a JavaScript library for producing dynamic, interactive data visualizations in web browsers. It makes use of Scalable Vector Graphics, HTML5, and Cascading Style Sheets standards.</p>
<p><strong>Victory.js</strong></p>
<p>A JavaScript 2D vector maths library for Node.js and the browser.</p>
<p><strong>Chart.js</strong></p>
<p>Simple, clean, and engaging HTML5 based JavaScript charts. Chart.js is an easy way to include animated, interactive graphs on your website for free.</p>
<p><strong>React-vis</strong></p>
<p>React-vis is a React visualization library.</p>
<p><strong>Trading Vuejs</strong></p>
<p>TradingVue.js is a hackable charting lib for traders. You can draw literally ANYTHING on top of candlestick charts.</p>
<p><strong>Flexmonster</strong></p>
<p>A pivot table component for web reporting, claims to be the most powerful JavaScript tool for visualizing your business data.</p>
<p><strong>ApexCharts</strong></p>
<p>ApexCharts is a modern charting library that helps developers to create beautiful and interactive visualizations for web pages.</p>
<p><strong>Echarts</strong></p>
<p>A Declarative Framework for Rapid Construction of Web-based Visualization.</p>
<p><strong>Google Charts</strong></p>
<p>Google Charts is an interactive Web service that creates graphical charts from user-supplied information.</p>
<p><strong>amCharts</strong></p>
<p>A go-to library for data visualization. When you don't have time to learn new technologies. When you need a simple yet powerful and flexible drop-in data visualization solution. Includes all basic and advanced chart types, as well as is extendable by additional plugins like Maps and TimeLine.</p>
<hr />
<p><strong>ANIMATION LIBRARY</strong></p>
<p><strong>Anime.js</strong></p>
<p>Anime.js is a lightweight JavaScript animation library with a simple, yet powerful API.</p>
<p><strong>Aos</strong></p>
<p><strong>Animate On Scroll library using CSS3.</strong></p>
<p><strong>Velocity</strong></p>
<p>Velocity is a cross-platform JavaScript library designed to simplify the client-side scripting of website animation.</p>
<p><strong>Mo.js</strong></p>
<p>Mo.js is a javascript motion graphics library that is fast, retina-ready, modular and open source.</p>
<p><strong>Popmotion</strong></p>
<p>The animator's JavaScript toolbox. Powerful Support for keyframes, spring, and inertia animations on numbers, colors, and complex strings.</p>
<p><strong>ScrollReveal</strong></p>
<p>JavaScript library to animate elements as they scroll into view.</p>
<p><strong>GreenSockJS</strong></p>
<p>GSAP is an industry-standard JavaScript animation library from GreenSock that lets you craft high-performance animations that work in every major browser.</p>
<p><strong>Skrollr</strong></p>
<p>skrollr is a parallax scrolling library used to transform, scale, skew, and rotate any element.</p>
<p><strong>AniJS</strong></p>
<p>AniJS, Declarative handling library for CSS animations. very beginner-friendly.</p>
<p><strong>Typed.js</strong></p>
<p>Typed.js is a library that types.</p>
<p><strong>Lottie</strong></p>
<p>Easily add high-quality animation to any native app. Lottie is an iOS, Android, and React Native library that renders After Effects animations in real-time, allowing apps to use animations as easily as they use static images.</p>
<hr />
<p><strong>VIDEO LIBRARY</strong></p>
<p><strong>Video.js</strong></p>
<p>Video JS is a free and open-source HTML5 video player built with JavaScript and CSS.</p>
<p><strong>Plyr</strong></p>
<p>Plyr is a simple, lightweight, accessible, and customizable HTML5, YouTube, and Vimeo media player that supports modern browsers.</p>
<p><strong>Jplayer</strong></p>
<p>jPlayer is a free and open-source JavaScript library developed as a jQuery plugin that facilitates the embedding of web-based media, notably HTML5 audio and video in addition to Adobe Flash-based media.</p>
<p><strong>Fit vid.js</strong></p>
<p>A lightweight, easy-to-use jQuery plugin for fluid width video embeds.</p>
<p><strong>indigo-player</strong></p>
<p>Highly extensible, modern, JavaScript video player. Handles MPEG-Dash / HLS / MPEG-4 and is built on top of the HTML5 video element.</p>
<p><strong>Flowplayer</strong></p>
<p>Flowplayer is an online video platform for broadcasters, publishers, and media houses. It gives you top ranking ad fill rates and the best-of-breed live streaming.</p>
<p><strong>Popcorn Js</strong></p>
<p>Popcorn.js is an open-source JavaScript library for HTML5 media developers, freely available under the MIT License.</p>
<p><strong>Xgplayer</strong></p>
<p>This is a web video player library. It has designed a separate, detachable UI component based on the principle that everything is componentized. More importantly, it is not only flexible in the UI layer, but also bold in its functionality: it gets rid of video loading, buffering, and format support for video dependence.</p>
<hr />
<p><strong>AUDIO</strong></p>
<p><strong>Howler.js</strong></p>
<p>Howler.js is a JavaScript library that works with Web Audio API by default and falls back to HTML5 Audio when not supported.</p>
<p><strong>Tone.js</strong></p>
<p>Tone.js packs in features for different virtual instruments, sequencers, effects, and more.</p>
<p><strong>Wavesurfer.js</strong></p>
<p>wavesurfer.js is an HTML 5 audio player and waveform visualizer, made with JavaScript and Web Audio.</p>
<p><strong>Pizzicato.js</strong></p>
<p>Pizzicato.js is another well-rounded library that provides a feature-packed set of tools to create everything from compositions made up of sample groups to precisely synthesized sounds.</p>
<p><strong>Sound Manager 2</strong></p>
<p>Sound Manager 2 is a JavaScript Sound API supporting MP3, MPEG4 and HTML5 audio. Makes it easy to play audio using JavaScript.</p>
<p><strong>Amplitudejs</strong></p>
<p>AmplitudeJS lets you build a fully customizable web audio player Stop being limited by the web browser's audio player design.</p>
<p><strong>Vexflow</strong></p>
<p>Vexflow is a JavaScript library for rendering standard music notation and guitar tablature.</p>
<p><strong>Sound js</strong></p>
<p>SoundJS abstracts HTML5 sound implementation, making adding consistent cross-browser sound to your games or rich experiences much easier.</p>
<p><strong>Ejecta</strong></p>
<p>Ejecta is like a Browser without the Browser. It's specially crafted for Games and Animations. It has no DIVs, no Tables, no Forms - only Canvas and Audio elements. This focus makes it fast.</p>
<hr />
<p><strong>GAMES</strong></p>
<p><strong>MelonJS</strong></p>
<p>MelonJS is yet another 2D focused game engine. By including the library into your code, you gain access to all kinds of features required for any game worth its money, such as physics support, collisions, sprites, and more.</p>
<p><strong>Pixi.js</strong></p>
<p>Superfast HTML 5 2D rendering engine that uses webGL with canvas fallback.</p>
<p><strong>Phaser</strong></p>
<p>Phaser is a 2D game framework used for making HTML5 games for desktop and mobile. It is free software and developed by Photon Storm. Phaser uses both a Canvas and WebGL renderer internally and can automatically swap between them based on browser support.s</p>
<p><strong>Babylon.js</strong></p>
<p>Babylon.js is a real time 3D engine using a JavaScript library for displaying 3D graphics in a web browser via HTML5. </p>
<p><strong>Matter.js</strong></p>
<p>Matter.js is a 2D physics engine for the web.</p>
<p><strong>Egret core</strong></p>
<p>Egret is a brand new open mobile game and application engine which allows you to quickly build mobile games and apps on Android,iOS and Windows.</p>
<p><strong>Melon.js</strong></p>
<p>MelonJS is a lightweight yet powerful HTML5 framework designed from the ground up to provide a true plugin-free 'write-once, run-everywhere' gaming platform. melonJS is an open-source project and supported by a community of enthusiasts. See our Gallery for a few examples of games powered by melonJS.</p>
<p><strong>Crafty</strong></p>
<p>Crafty is a JavaScript game library that can help you create games in a structured way.</p>
<hr />
<p><strong>FORMS</strong></p>
<p><strong>Quill</strong></p>
<p>Module for simple form and input field bindings. Automatically creates hidden input fields for a form and adds submit handling and submit by key. You may also specify your own custom input fields. It creates fields for text, html and delta.</p>
<p><strong>Cleave.js</strong></p>
<p>Cleave.js has a simple purpose: to help you format input text content automatically.</p>
<p><strong>jQuery Validation</strong></p>
<p>This jQuery plugin makes simple clientside form validation easy, whilst still offering plenty of customization options. It makes a good choice if you're building something new from scratch, but also when you're trying to integrate something into an existing application with lots of existing markup. </p>
<p><strong>Selectize.js</strong></p>
<p>Selectize is the hybrid of a textbox and  box. It's jQuery-based and it's useful for tagging, contact lists, country selectors, and so on.</p>
<p><strong>Parsley.js</strong></p>
<p>Parsley, the ultimate JavaScript form validation library
Validating forms for with this tool for frontend have never been so powerful and easy.</p>
<p><strong>Fine Uploader</strong></p>
<p>FineUploader is also simple to use. In the simplest case, you only need to include one JavaScript file. </p>
<p><strong>Pickadate.js</strong></p>
<p>The mobile-friendly, responsive, and lightweight jQuery date &amp; time input picker.</p>
<hr />
<p>Thanks for reading! </p>
<p>My hope is that after finishing this article you would have tools for creating awesome features with JavaScript in the browser. </p>
<p>Reach out on  <a target="_blank" href="https://twitter.com/chineduvictor7?s=09">Twitter</a>  with some of your personal favorite libraries/frameworks and tools to use. Love you❤️❤️❤️🤓🤓🤓</p>
]]></content:encoded></item><item><title><![CDATA[Javascript: How to implement a queue]]></title><description><![CDATA[Introduction
After, writing about  STACKS, the positive feedback, and all the support and nice DMs I got on Instagram and Twitter has made me turn this into a series, yeah you read that right. 
This is going to be a series of data-structures and algo...]]></description><link>https://therustguy.com/javascript-how-to-implement-a-queue</link><guid isPermaLink="true">https://therustguy.com/javascript-how-to-implement-a-queue</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[Angular]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Vue.js]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Sat, 26 Dec 2020 14:05:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1608980052841/PmoydesOk.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Introduction</p>
<p>After, writing about  <a target="_blank" href="https://www.ddevguys.com/javascript-how-you-can-implement-a-stack-in-3-mins">STACKS</a>, the positive feedback, and all the support and nice DMs I got on Instagram and Twitter has made me turn this into a series, yeah you read that right. </p>
<p>This is going to be a series of <strong>data-structures and algorithms</strong> using javascript. </p>
<p>I hope you reading this enjoys it. Let’s go…🤓🤓🤓</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1608980006438/MliVunOr6.png" alt="queues in javascript blog post HEADING.png" /></p>
<p>In today’s blog article, we would be talking about queues!</p>
<p>What is a queue
A queue is a data structure that follows the first in first out (FIFO)principle.</p>
<p>Example: people standing in a line (first come first serve) to get groceries from a grocery store, etc. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1608972789030/RJoprdoFH.gif" alt="giphy grocery queue.gif" /></p>
<p>Queues are very similar to stack, but instead of using the LIFO principles like stacks do they use the FIFO principle which we would implement as we go on.</p>
<p>In javascript, we have array methods that define the queue class which is a push() and shift() method. </p>
<p>Adding an item to the queue is commonly known as enqueuing and removing an item from the queue is known as dequeuing. </p>
<p>push() is used to enqueue while shift() is used to dequeue. </p>
<p>The shift() is a javascript array method that removes and returns the first element of an array. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1608978616499/BgNPx_kv0.png" alt="queues in javascript blog post.png" /></p>
<p>Let’s create a queue</p>
<p>Let’s write some codes, shall we? As usual, we start with the basics and declare a class using an array in the constructor property of our class.</p>
<pre><code><span class="hljs-comment">// Queue class</span>

Class Queue{
     <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
       <span class="hljs-built_in">this</span>.items=[];
     }
    <span class="hljs-comment">//Methods to be implemented go here</span>
      enqueue(item)
      dequeue()
      front()
      isEmpty()
      size()
      print()
}
</code></pre><p>Let’s implement each method for our queue class.</p>
<p>Enqueue: This adds a new item to the back of the queue, this is similar to standing in a line (queue) to get items from a grocery store.</p>
<pre><code><span class="hljs-selector-tag">enqueue</span>(item) {
<span class="hljs-comment">//enqueuing items onto the queue</span>
<span class="hljs-selector-tag">this</span><span class="hljs-selector-class">.items</span><span class="hljs-selector-class">.push</span>(item)
}
</code></pre><p>Dequeue: This removes and returns the first item on the queue, this is the first come first serve. </p>
<p>The first person to get to our imaginary grocery store is the first person to be attended to.</p>
<pre><code><span class="hljs-selector-tag">dequeue</span>(){
<span class="hljs-comment">//remove items from the queue</span>
<span class="hljs-selector-tag">this</span><span class="hljs-selector-class">.items</span><span class="hljs-selector-class">.shift</span>()
}
</code></pre><p>Front: This method returns the first item from the queue, but it does not modify the queue.</p>
<p>In our imaginary grocery store, let’s imagine that the grocery store attendant wants to know who is first on the queue. </p>
<p>Note that he has not attended to this person yet in our case has not modified the queue. </p>
<p>He just wants to know who is first on the queue.</p>
<pre><code><span class="hljs-selector-tag">front</span>() {
<span class="hljs-comment">//returns the first item on the queue</span>
<span class="hljs-selector-tag">this</span><span class="hljs-selector-class">.items</span><span class="hljs-selector-attr">[0]</span>
}
</code></pre><p>isEmpty: This <code>returns false</code> if the queue contains items or is greater than 0, and <code>returns true</code> if the queue is empty.</p>
<p>In our imaginary grocery store, let’s imagine that the grocery store attendant wants to know if there are more customers to attend to, if there are customers, that means the queue is not empty so as a result, we get false. </p>
<p>But if the grocery attendant has attended to everyone in the queue, then that means the queue is empty so as a result, we get <code>true</code></p>
<pre><code>isEmpty() {
<span class="hljs-keyword">this</span>.items.length == <span class="hljs-number">0</span>;
}
</code></pre><p>Size: This gives us the number of items in our queue. </p>
<p>Back to our imaginary grocery store where we have a queue of customers. </p>
<p>Let’s imagine that the grocery store attendant for some reasons best known to him wants to know how many people he is attending to at the moment (people on the queue) then he will have to count them right? Yeah.</p>
<pre><code>size() {
<span class="hljs-comment">//check the number of items on the queue</span>
<span class="hljs-keyword">this</span>.items.length;
}
</code></pre><p>Just like when we implemented  the  <a target="_blank" href="https://www.ddevguys.com/javascript-how-you-can-implement-a-stack-in-3-mins">STACKS</a>  class. We could go a step further to add a print method to help us print all the items in the queue whenever we want.</p>
<pre><code><span class="hljs-selector-tag">print</span>() {
<span class="hljs-comment">//log all the items in the queue</span>
<span class="hljs-selector-tag">console</span><span class="hljs-selector-class">.log</span>(items to String())
}
</code></pre><p>Let’s use the queue class
First, we have to instantiate the queue class we created</p>
<pre><code><span class="hljs-comment">//instantiating the queue</span>
let <span class="hljs-built_in">queue</span> = <span class="hljs-keyword">new</span> Queue()
</code></pre><p>Next, we can add items to our queue (since we are using the imaginary grocery store queue we would use real peoples names and enqueue them unto our queue. Let's use Vivian, Gideon, and Shalom)</p>
<pre><code><span class="hljs-comment">// pushing a new item (customers) to the queue</span>
<span class="hljs-selector-tag">queue</span><span class="hljs-selector-class">.enqueue</span>(<span class="hljs-string">"Vivian"</span>)
<span class="hljs-selector-tag">queue</span><span class="hljs-selector-class">.enqueue</span>(<span class="hljs-string">"Gideon"</span>)
<span class="hljs-selector-tag">queue</span><span class="hljs-selector-class">.enqueue</span>(<span class="hljs-string">"Shalom"</span>)
</code></pre><p>Next, we can go ahead to check if items are on the queue (checking if anyone is on our grocery store queue)</p>
<pre><code>//<span class="hljs-keyword">returns</span> <span class="hljs-keyword">false</span>
console.log(queue.isEmpty())
</code></pre><p>Next, we call the <code>front()</code> method, by doing so we would get <code>Vivian</code> because she happens to be the first person in the queue.</p>
<pre><code><span class="hljs-comment">//returns vivian</span>
<span class="hljs-selector-tag">queue</span><span class="hljs-selector-class">.front</span>()
</code></pre><p>Now, we want to check the size of our queue to see how many items (customers) are on it.</p>
<pre><code><span class="hljs-comment">//returns 3</span>
Console.<span class="hljs-built_in">log</span>(<span class="hljs-built_in">queue</span>.size())
</code></pre><p>Let’s print out all the items in our queue</p>
<pre><code><span class="hljs-comment">//returns [“Vivian”, “Gideon”, “Shalom”]</span>
<span class="hljs-selector-tag">queue</span><span class="hljs-selector-class">.print</span>()
</code></pre><p>Let’s remove items from the queue. </p>
<p>In our imaginary grocery store, we have to attend to our customers right? Yeah! If that be the case this has to happen in a first come first serve format (FIFO)). </p>
<p>Let’s do this</p>
<pre><code><span class="hljs-comment">//remove each item from the queue</span>
<span class="hljs-selector-tag">queue</span><span class="hljs-selector-class">.dequeue</span>()
<span class="hljs-selector-tag">queue</span><span class="hljs-selector-class">.dequeue</span>()
</code></pre><p>if we run </p>
<pre><code>queue.print()
</code></pre><p> we see that <code>Vivian</code> and <code>Gideon</code> has left the queue (our first two customers have been tended too) so we have only <code>shalom</code> to attend too. </p>
<p>Let’s not waste his time let’s attend to him, so once again we run the dequeue method of our queue class</p>
<pre><code><span class="hljs-selector-tag">queue</span><span class="hljs-selector-class">.dequeue</span> ()
</code></pre><p>To confirm our last action we can once again check if our queue is empty. This should <code>return true</code></p>
<pre><code>//<span class="hljs-keyword">returns</span> <span class="hljs-keyword">true</span>
queue.isEmpty()
</code></pre><p>With this, we can say we have successfully implemented a queue in javascript KUDOS 
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1608984527653/Mgj20l5Ne.gif" alt="giphykudos.gif" />
if you made it to this point <strong>but one more thing…</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1608985072423/VkX3e8q8h.png" alt="HERE IS HOW JS USES QUEUES post HEADING.png" /></p>
<p>Whenever a new tab is opened in a browser a task queue is created. </p>
<p>This is because of something we call the event loop and in the event loop only a single thread handles all the tasks for a single tab. </p>
<p>The browser handles several tasks such as handling user interaction (keyboard clicks, mouse clicks, etc), processing and executing async requests, executing javascript, and rendering HTML. </p>
<p>This is amazing that a very powerful and yet popular language like javascript uses queues to handle its internal control. You could learn more about it <a target="_blank" href="https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/">here</a></p>
<p>Once again as always thanks for being with me till the end. </p>
<p>Next, I would be writing about a very popular kind of queue implementation or maybe a linked list. </p>
<p>Well, I don’t know which to write about if you could make that choice for me I’d really appreciate you could consider sending a DM on Twitter or Instagram (join our 36k community members).</p>
<p>Cheers! Keep Grinding🧡 </p>
]]></content:encoded></item><item><title><![CDATA[Javascript: How You Can Implement a Stack in 3 Mins]]></title><description><![CDATA[Javascript: How You Can Implement a Stack in 3 Mins


Rocks stacked on each other
Introduction
So, a few days ago, I ran a survey on my stories on Instagram and the result of this survey is the reason I decided to write a blog post about the topic ST...]]></description><link>https://therustguy.com/javascript-how-you-can-implement-a-stack-in-3-mins</link><guid isPermaLink="true">https://therustguy.com/javascript-how-you-can-implement-a-stack-in-3-mins</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[data structures]]></category><category><![CDATA[algorithms]]></category><dc:creator><![CDATA[Okere chinedu Victor]]></dc:creator><pubDate>Fri, 25 Dec 2020 14:58:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1609093921255/31hqtbjEP.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><span class="s"></span></p>
<h1 id="javascript-how-you-can-implement-a-stack-in-3-mins">Javascript: How You Can Implement a Stack in 3 Mins</h1>
<img alt="Rocks stacked on each other" src="https://miro.medium.com/max/10944/1*eQURSxQ8LwEugssoZd21Ew.jpeg" />

<p>Rocks stacked on each other<span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv"></span></p>
<h1 id="introduction">Introduction</h1>
<p>So, a few days ago, I ran a survey on my stories on <a target="_blank" href="https://www.instagram.com/d_dev_guys/">Instagram</a> and the result of this survey is the reason I decided to write a blog post about the topic <strong>STACKS</strong> in using JavaScript.</p>
<p><img src="https://miro.medium.com/max/54/1*K8g4CAlbJbXzOhQU3wLtpg.png?q=20" alt="Instagram survey, where 76% voted yes to an article about stacks with javascript" /></p>
<img alt="Instagram survey, where 76% voted yes to an article about stacks with javascript" src="https://miro.medium.com/max/1072/1*K8g4CAlbJbXzOhQU3wLtpg.png" />

<p>Instagram poll<span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv"></span></p>
<h1 id="whats-the-stack-data-structure"><strong>What's the stack data structure?</strong></h1>
<p>A stack is a data structure that follows the <strong>LAST IN FIRST OUT (LIFO)</strong> principle. There are several real-world examples, e.g. plates, books stacked on each other, etc.</p>
<p><img src="https://miro.medium.com/max/40/1*_dIyKnW-30D4x81zPfX7sQ.jpeg?q=20" alt="Books stacked on each other" /></p>
<img alt="Books stacked on each other" src="https://miro.medium.com/max/5938/1*_dIyKnW-30D4x81zPfX7sQ.jpeg" />

<p>Books stacked on each other</p>
<p>The removal and addition of new items in a stack take place at the same end. This is because stacks follow the <strong>LIFO</strong> principle this means that the newly added items are the first to be removed.</p>
<p><span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv"></span></p>
<h1 id="lets-create-a-stack"><strong>Let’s create a stack</strong></h1>
<p>Enough of the explanations, let's write some codes🤓🤓🤓! We start with the basics and declare a class using an array in the constructor property of our class.</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span> </span>{
      <span class="hljs-keyword">constructor</span>() {
         <span class="hljs-keyword">this</span>.items = [];
      }&lt;/span&gt; &lt;span id=<span class="hljs-string">"e9e3"</span> <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">em</span> <span class="hljs-title">ke</span> <span class="hljs-title">hy</span> <span class="hljs-title">dp</span> <span class="hljs-title">kf</span> <span class="hljs-title">b</span> <span class="hljs-title">kg</span> <span class="hljs-title">kk</span> <span class="hljs-title">kl</span> <span class="hljs-title">km</span> <span class="hljs-title">kn</span> <span class="hljs-title">ko</span> <span class="hljs-title">ki</span> <span class="hljs-title">s</span> <span class="hljs-title">kj</span>"&gt;//<span class="hljs-title">methods</span> <span class="hljs-title">to</span> <span class="hljs-title">be</span> <span class="hljs-title">implemented</span> <span class="hljs-title">go</span> <span class="hljs-title">here</span></span>
      Push(item)
      Pop()
      Peek()
      isEmpty()
      Clear()
      Size() 
      Print()
}&lt;/span&gt;
</code></pre><h1 id="lets-implement-each-method-for-our-stack-class">Let’s implement each method for our stack Class.</h1>
<p><strong>Push</strong>: This adds items or an item to the top of the stack.</p>
<pre><code>Push(item) {
     <span class="hljs-comment">//pushing an item into the stack</span>
     <span class="hljs-keyword">this</span>.items.push(item)
}&lt;/span&gt;
</code></pre><p><strong>Pop</strong>: This removes the top item from the stack and returns the removed item.</p>
<pre><code>Pop() {
    <span class="hljs-comment">//removes an item from the stack</span>
    _return_ <span class="hljs-keyword">this</span>.items.pop()
}&lt;/span&gt;
</code></pre><p><strong>Peek</strong>: This returns the top element from the stack but doesn’t modify it (it doesn’t remove it).</p>
<pre><code>Peek() {
     <span class="hljs-comment">//returning the top item without modifying it</span>
     _return_ <span class="hljs-keyword">this</span>.items[<span class="hljs-keyword">this</span>.items.length - <span class="hljs-number">1</span>]
}&lt;/span&gt;
</code></pre><p><strong>isEmpty</strong>: This returns false if the stack contains items but returns true if it does not contain an item.</p>
<pre><code>isEmpty() {
        //<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span> <span class="hljs-keyword">if</span> the stack <span class="hljs-keyword">is</span> empty
        _return_ this.items.length == <span class="hljs-number">0</span>;
}&lt;/span&gt;
</code></pre><p><strong>Clear</strong>: This would remove all the items from the stack.</p>
<pre><code>Clear() {
      <span class="hljs-comment">//output all the content of the stacks</span>
      _return_ <span class="hljs-keyword">this</span>.items = [];
}&lt;/span&gt;
</code></pre><p><strong>Size</strong>: This returns all the number of items contained in the stack. (this is similar to the length property of the array data-structure)</p>
<pre><code>Size() {
     <span class="hljs-comment">//returns the number of items in the stack</span>
     _return_ <span class="hljs-keyword">this</span>.items.length;
}&lt;/span&gt;
</code></pre><p><strong>Print:</strong> This would output the content of the stack.</p>
<pre><code>Print() {
      <span class="hljs-comment">//output all the content of the stacks</span>
      console.log(<span class="hljs-keyword">this</span>.items.toString())
}&lt;/span&gt;
</code></pre><p><span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv"></span><img src="https://miro.medium.com/freeze/max/60/1*D2eQjN5bAS7f_rX_Xpa81A.gif?q=20" alt="Image for post" /></p>
<img alt="Image for post" src="https://miro.medium.com/max/996/1*D2eQjN5bAS7f_rX_Xpa81A.gif" />

<p><strong>YOOHOO</strong>…Champ! You made it this far! You are absolutely amazing</p>
<h1 id="lets-use-the-stack-class"><strong>Let’s use the stack class</strong></h1>
<p>The first thing we have to do is to instantiate the stack class we created.</p>
<pre><code><span class="hljs-comment">//instantiating the stack</span>
let <span class="hljs-built_in">stack</span> = <span class="hljs-keyword">new</span> Stack()&lt;/span&gt;
</code></pre><p>Next, we can add some items (we push 1 and 2, we can push any item to the stack)</p>
<pre><code>//pushing a <span class="hljs-built_in">new</span> item <span class="hljs-keyword">to</span> stack
stack.Push(<span class="hljs-number">1</span>)
stack.Push(<span class="hljs-number">2</span>)&lt;/span&gt;
</code></pre><p>Next, we can go ahead to test if the items were added to the stack. This should return <em>false.</em></p>
<pre><code>_//_returns _false_
console.log(stack.isEmpty());&lt;/span&gt;
</code></pre><p>Let’s go ahead and call the peek method, we would get <strong><em>2</em></strong> this is because it’s the last element added to the stack.</p>
<pre><code>//<span class="hljs-keyword">returns</span> _2_
Console.log(stack.Peek());&lt;/span&gt;
</code></pre><p>Let’s go ahead and add one item to the stack.</p>
<pre><code><span class="hljs-comment">//adds _3_ to the stack</span>
stack.Push(<span class="hljs-number">3</span>);&lt;/span&gt;
</code></pre><p>Let’s check the size to confirm how many items are in our stack.</p>
<pre><code>//<span class="hljs-keyword">out</span> puts _3_
console.log(stack.Size());&lt;/span&gt;
</code></pre><p>Let’s print all the items in our stack</p>
<pre><code><span class="hljs-string">//returns</span> [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>]
<span class="hljs-string">Stack.Print()&lt;/span&gt;</span>
</code></pre><p>Let’s go ahead and remove the item from the stack</p>
<pre><code>//removes <span class="hljs-keyword">each</span> item <span class="hljs-keyword">from</span> the stack
Stack.Pop()
Stack.Pop()
Stack.Pop()&lt;/span&gt;
</code></pre><p>Let’s check once again if it’s empty</p>
<pre><code>//<span class="hljs-keyword">returns</span> <span class="hljs-keyword">true</span>
Stack.isEmpty();&lt;/span&gt;
</code></pre><p><span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv hw"></span><span class="ht es fx hu hv"></span></p>
<p>There you have it!!!</p>
<p>In just a few simple steps we have implemented stacks using JavaScript.</p>
<p>As with everything it really goes into practicing these steps so you get to understand it deeply. In a later article, I would be writing about the application of stacks as well as solving some common computer science problems with it.</p>
<p>If you enjoyed this article why not follow me on <a target="_blank" href="https://twitter.com/chineduvictor7">Twitter</a>, also take a screenshot and send a DM on <a target="_blank" href="https://www.instagram.com/d_dev_guys/">Instagram</a>, I will give you a shoutout alongside other of our 36k community members.😉😉😉</p>
<p>Cheers! Happy Hacking.</p>
]]></content:encoded></item></channel></rss>