<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Hadiza Mohammed</title>
    <description>The latest articles on Forem by Hadiza Mohammed (@dee_codes).</description>
    <link>https://forem.com/dee_codes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1661410%2Fa8b0eb98-7c96-4df3-8fa9-3eb573fb0117.png</url>
      <title>Forem: Hadiza Mohammed</title>
      <link>https://forem.com/dee_codes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dee_codes"/>
    <language>en</language>
    <item>
      <title>How to Generate and Verify OTPs in Next.js</title>
      <dc:creator>Hadiza Mohammed</dc:creator>
      <pubDate>Thu, 24 Oct 2024 10:58:39 +0000</pubDate>
      <link>https://forem.com/dee_codes/how-to-generate-and-verify-otps-in-nextjs-30i5</link>
      <guid>https://forem.com/dee_codes/how-to-generate-and-verify-otps-in-nextjs-30i5</guid>
      <description>&lt;p&gt;When building modern web applications, One-Time Passwords (OTPs) are critical in two-factor authentication and user verification workflows. This guide will teach us how to generate, send, and verify OTPs using Next.js and a mock email service. By the end, you’ll understand how OTPs can enhance security and improve user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an OTP?
&lt;/h2&gt;

&lt;p&gt;An OTP (One-Time Password) is a temporary password used for a single login or transaction. It expires after a short time, providing additional security beyond regular passwords.&lt;/p&gt;

&lt;p&gt;Common use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Account Registration&lt;/li&gt;
&lt;li&gt;Password Resets&lt;/li&gt;
&lt;li&gt;Two-factor Authentication (2FA)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How OTP Generation Works
&lt;/h2&gt;

&lt;p&gt;The general workflow for OTP generation and verification is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate&lt;/strong&gt; a random OTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send&lt;/strong&gt; the OTP to the user via email (or SMS).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; the OTP when the user submits it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activate&lt;/strong&gt; or proceed with the next action only if OTP is correct.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;To demonstrate OTP generation and verification, we’ll build:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;backend API&lt;/strong&gt; route to generate OTPs.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Redis&lt;/strong&gt; store to temporarily save OTPs.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;API route&lt;/strong&gt; to verify OTPs.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;p&gt;1- Next.js project initialized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; npx create-next-app@latest otp-nextjs-demo
 cd otp-nextjs-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- Install necessary dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; npm install redis nodemailer crypto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: Set Up Redis
&lt;/h2&gt;

&lt;p&gt;We’ll use Redis to temporarily store the OTP. For this guide, we’ll use Upstash, a serverless Redis service.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a free Upstash Redis instance at &lt;a href="https://upstash.com" rel="noopener noreferrer"&gt;https://upstash.com&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Copy your Redis connection string and set it in your .env.local:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REDIS_URL=&amp;lt;your-upstash-redis-url&amp;gt;
EMAIL_USER=&amp;lt;your-email&amp;gt;
EMAIL_PASS=&amp;lt;your-email-password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create the OTP Generation API
&lt;/h2&gt;

&lt;p&gt;Next, let’s create an API route to generate and send OTPs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// /pages/api/generateOTP.ts
import { NextApiRequest, NextApiResponse } from 'next';
import Redis from 'ioredis';
import crypto from 'crypto';
import nodemailer from 'nodemailer';

// Initialize Redis
const redis = new Redis(process.env.REDIS_URL!);

// Configure Nodemailer for sending emails
const transporter = nodemailer.createTransport({
  service: 'gmail', // Use your preferred email service
  auth: {
    user: process.env.EMAIL_USER,
    pass: process.env.EMAIL_PASS,
  },
});

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { email } = req.body;

  if (!email) {
    return res.status(400).json({ message: 'Email is required' });
  }

  try {
    // Generate a 6-digit OTP
    const otp = crypto.randomInt(100000, 999999).toString();

    // Store OTP in Redis for 5 minutes
    await redis.setex(email, 300, otp);

    // Send OTP to user's email
    await transporter.sendMail({
      from: process.env.EMAIL_USER,
      to: email,
      subject: 'Your OTP Code',
      text: `Your OTP is ${otp}. It will expire in 5 minutes.`,
    });

    return res.status(200).json({ message: 'OTP sent to email' });
  } catch (error) {
    console.error('Error generating OTP:', error);
    return res.status(500).json({ message: 'Error generating OTP' });
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How This Code Works:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Redis Setup: We connect to Redis to store OTPs with a 5-minute expiration.&lt;/li&gt;
&lt;li&gt;OTP Generation: We use the crypto module to generate a random 6-digit OTP.&lt;/li&gt;
&lt;li&gt;Sending OTP via Email: Nodemailer is used to send the OTP to the user’s email.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 3: Verify OTP API
&lt;/h2&gt;

&lt;p&gt;Now, let’s create the OTP verification endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// /pages/api/verifyOTP.ts
import { NextApiRequest, NextApiResponse } from 'next';
import Redis from 'ioredis';

// Initialize Redis
const redis = new Redis(process.env.REDIS_URL!);

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { email, otp } = req.body;

  if (!email || !otp) {
    return res.status(400).json({ message: 'Email and OTP are required' });
  }

  try {
    // Retrieve OTP from Redis
    const storedOtp = await redis.get(email);

    if (!storedOtp) {
      return res.status(400).json({ message: 'OTP expired or not found' });
    }

    if (storedOtp !== otp) {
      return res.status(400).json({ message: 'Invalid OTP' });
    }

    // OTP is valid; proceed with registration or action
    await redis.del(email); // Remove OTP after successful verification

    return res.status(200).json({ message: 'OTP verified successfully' });
  } catch (error) {
    console.error('Error verifying OTP:', error);
    return res.status(500).json({ message: 'Error verifying OTP' });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How This Code Works:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;OTP Retrieval: We retrieve the OTP from Redis using the provided email.&lt;/li&gt;
&lt;li&gt;OTP Validation: If the OTP matches, we delete it from Redis and return a successful response. If not, we return an error message.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 4: Frontend Form to Request OTP
&lt;/h2&gt;

&lt;p&gt;Create a simple form to request an OTP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// /pages/index.tsx
'use client';

import { useState } from 'react';

export default function Home() {
  const [email, setEmail] = useState('');
  const [message, setMessage] = useState('');

  const handleSubmit = async (e: React.FormEvent) =&amp;gt; {
    e.preventDefault();

    const res = await fetch('/api/generateOTP', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email }),
    });

    const data = await res.json();
    setMessage(data.message);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Request OTP&amp;lt;/h1&amp;gt;
      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
        &amp;lt;input
          type="email"
          placeholder="Enter your email"
          value={email}
          onChange={(e) =&amp;gt; setEmail(e.target.value)}
          required
        /&amp;gt;
        &amp;lt;button type="submit"&amp;gt;Get OTP&amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;
      &amp;lt;p&amp;gt;{message}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Frontend Form to Verify OTP
&lt;/h2&gt;

&lt;p&gt;Create another form to verify the OTP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// /pages/verify.tsx
'use client';

import { useState } from 'react';

export default function Verify() {
  const [email, setEmail] = useState('');
  const [otp, setOtp] = useState('');
  const [message, setMessage] = useState('');

  const handleVerify = async (e: React.FormEvent) =&amp;gt; {
    e.preventDefault();

    const res = await fetch('/api/verifyOTP', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, otp }),
    });

    const data = await res.json();
    setMessage(data.message);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Verify OTP&amp;lt;/h1&amp;gt;
      &amp;lt;form onSubmit={handleVerify}&amp;gt;
        &amp;lt;input
          type="email"
          placeholder="Enter your email"
          value={email}
          onChange={(e) =&amp;gt; setEmail(e.target.value)}
          required
        /&amp;gt;
        &amp;lt;input
          type="text"
          placeholder="Enter OTP"
          value={otp}
          onChange={(e) =&amp;gt; setOtp(e.target.value)}
          required
        /&amp;gt;
        &amp;lt;button type="submit"&amp;gt;Verify OTP&amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;
      &amp;lt;p&amp;gt;{message}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In this guide, we built a complete OTP generation and verification flow in Next.js. We used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis to store OTPs temporarily.&lt;/li&gt;
&lt;li&gt;Nodemailer to send OTPs via email.&lt;/li&gt;
&lt;li&gt;API routes to generate and verify OTPs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This workflow ensures that your application can securely verify users during registration or password resets. You can expand this by integrating OTP with two-factor authentication (2FA) for even better security.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>typescript</category>
      <category>authentication</category>
      <category>redis</category>
    </item>
    <item>
      <title>Setting up Redis in a Next.js Application</title>
      <dc:creator>Hadiza Mohammed</dc:creator>
      <pubDate>Wed, 23 Oct 2024 11:14:14 +0000</pubDate>
      <link>https://forem.com/dee_codes/setting-up-redis-in-a-nextjs-application-1h1d</link>
      <guid>https://forem.com/dee_codes/setting-up-redis-in-a-nextjs-application-1h1d</guid>
      <description>&lt;p&gt;In modern web development, performance matters. Users expect pages to load instantly and real-time features to work seamlessly. This is where &lt;strong&gt;Redis&lt;/strong&gt; comes in an &lt;strong&gt;in-memory data store&lt;/strong&gt; known for &lt;strong&gt;blazing-fast performance&lt;/strong&gt; and scalability. Redis is perfect for use cases like &lt;strong&gt;caching, session management, rate limiting, and storing temporary data&lt;/strong&gt; such as &lt;strong&gt;OTP&lt;/strong&gt; codes or pending appointments.&lt;/p&gt;

&lt;p&gt;In this article, we’ll walk you through how to &lt;strong&gt;integrate Redis into a Next.js application&lt;/strong&gt;, covering both &lt;strong&gt;server-side logic&lt;/strong&gt; and &lt;strong&gt;practical use cases&lt;/strong&gt; like caching and session storage. We’ll be using &lt;strong&gt;Upstash Redis&lt;/strong&gt;, a serverless Redis service that works perfectly with &lt;strong&gt;Vercel&lt;/strong&gt; and other platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Redis in a Next.js App?
&lt;/h2&gt;

&lt;p&gt;Here are some key scenarios where Redis can boost the performance of your Next.js application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Session Management&lt;/strong&gt;: Store and retrieve user sessions, including access tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching&lt;/strong&gt;: Speed up page loading by caching frequently requested data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate Limiting&lt;/strong&gt;: Prevent abuse by limiting the number of API requests from a user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary Data&lt;/strong&gt;: Store OTPs, appointment statuses, or tokens with expiration times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Data&lt;/strong&gt;: Use Redis’s Pub/Sub feature to send real-time updates to users.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Set up a Next.js Application&lt;/strong&gt;&lt;br&gt;
If you don’t already have a Next.js project, let’s create one:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-next-app@latest redis-next-app&lt;br&gt;
cd redis-next-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Install the Redis Client for Upstash&lt;/strong&gt;&lt;br&gt;
We’ll use the Upstash Redis package, a serverless Redis solution designed for serverless platforms.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install @upstash/redis&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Get Redis Credentials from Upstash&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Upstash and create an account.&lt;/li&gt;
&lt;li&gt;Create a new Redis database.&lt;/li&gt;
&lt;li&gt;Copy the Redis URL and Access Token from the dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Store Redis Credentials in Environment Variables&lt;/strong&gt;&lt;br&gt;
Create a .env.local file in your project root and add the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;REDIS_URL=&amp;lt;your-redis-url&amp;gt;&lt;br&gt;
REDIS_TOKEN=&amp;lt;your-redis-token&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make sure to never hardcode credentials in your code—using environment variables keeps them secure.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up Redis in Your Next.js App
&lt;/h2&gt;

&lt;p&gt;Let’s create a Redis client that can be reused across the entire application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// lib/redis.ts
import { Redis } from '@upstash/redis';

// Initialize Redis using credentials from environment variables
const redis = new Redis({
  url: process.env.REDIS_URL!,
  token: process.env.REDIS_TOKEN!,
});

export default redis;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can import this Redis client in our API routes or server components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Use Case 1: Caching API Responses&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Imagine you’re fetching data from a slow external API. Let’s use Redis to cache the API response and speed things up for future requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/api/cache-example.ts
import { NextApiRequest, NextApiResponse } from 'next';
import redis from '@/lib/redis';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const cacheKey = 'myApiData';

  // Try to retrieve data from Redis cache
  const cachedData = await redis.get(cacheKey);
  if (cachedData) {
    console.log('Serving from cache');
    return res.status(200).json(JSON.parse(cachedData));
  }

  // If not in cache, fetch from an external API (simulate with static data)
  const data = { message: 'Hello from an external API' };

  // Store the result in Redis with a TTL (time-to-live) of 1 hour
  await redis.setex(cacheKey, 3600, JSON.stringify(data));

  res.status(200).json(data);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try hitting the endpoint:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:3000/api/cache-example&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;On the first request, data will be fetched from the API. On subsequent requests, Redis will serve the cached version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Use Case 2: Storing and Validating OTP Codes&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Let’s say we want to store OTP codes for user authentication. Redis is perfect because it supports data expiration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/api/sendOtp.ts
import redis from '@/lib/redis';
import { randomBytes } from 'crypto';

export default async function handler(req, res) {
  const { email } = req.body;

  // Generate a random OTP
  const otp = randomBytes(3).toString('hex'); // e.g., 'f1a2b3'

  // Store OTP in Redis with a 5-minute expiration
  await redis.setex(`otp:${email}`, 300, otp);

  // Simulate sending OTP via email (just log it for now)
  console.log(`Sending OTP ${otp} to ${email}`);

  res.status(200).json({ message: 'OTP sent' });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validate the OTP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/api/verifyOtp.ts
import redis from '@/lib/redis';

export default async function handler(req, res) {
  const { email, otp } = req.body;

  // Retrieve OTP from Redis
  const storedOtp = await redis.get(`otp:${email}`);

  if (storedOtp === otp) {
    return res.status(200).json({ message: 'OTP verified' });
  }

  res.status(400).json({ message: 'Invalid OTP' });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Use Case 3: Rate Limiting API Requests&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
To prevent abuse, let’s build a rate limiter that restricts each user to 10 API requests per minute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// middleware/rateLimiter.ts
import redis from '@/lib/redis';
import { NextRequest, NextResponse } from 'next/server';

export default async function middleware(req: NextRequest) {
  const ip = req.ip ?? 'unknown';

  const requests = await redis.incr(ip); // Increment request count
  if (requests === 1) {
    await redis.expire(ip, 60); // Set expiration to 1 minute
  }

  if (requests &amp;gt; 10) {
    return NextResponse.json({ message: 'Rate limit exceeded' }, { status: 429 });
  }

  return NextResponse.next(); // Proceed if within the limit
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this middleware to specific routes using the Next.js config.&lt;/p&gt;

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

&lt;p&gt;Integrating Redis with Next.js can drastically improve your app's performance by caching data, managing sessions, and storing temporary information. In this guide, we explored:&lt;/p&gt;

&lt;p&gt;How to set up Redis in a Next.js project.&lt;br&gt;
Using Redis for caching, OTP management and rate limiting.&lt;br&gt;
Happy coding! 🚀&lt;/p&gt;

</description>
      <category>redis</category>
      <category>nextjs</category>
      <category>tutorial</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How to Set Up MongoDB with Next.js</title>
      <dc:creator>Hadiza Mohammed</dc:creator>
      <pubDate>Fri, 04 Oct 2024 10:36:14 +0000</pubDate>
      <link>https://forem.com/dee_codes/how-to-set-up-mongodb-with-nextjs-2lkb</link>
      <guid>https://forem.com/dee_codes/how-to-set-up-mongodb-with-nextjs-2lkb</guid>
      <description>&lt;p&gt;In this tutorial, we’ll walk through the process of connecting MongoDB to a Next.js application. We’ll cover how to set up MongoDB using Mongoose, connect to MongoDB Atlas, and ensure efficient database connections in your Next.js API routes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic understanding of JavaScript and Next.js.&lt;/li&gt;
&lt;li&gt;Installed MongoDB locally or an active MongoDB Atlas account.&lt;/li&gt;
&lt;li&gt;Basic knowledge of Node.js and npm.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install MongoDB and Mongoose&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, you need to install mongoose, the popular Node.js library for MongoDB, in your Next.js project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install mongoose&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Mongoose provides an elegant solution for managing MongoDB connections and defining schemas for data models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Set Up MongoDB Atlas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you don’t have MongoDB installed locally, you can use &lt;a href="https://www.mongodb.com/products/platform/atlas-database" rel="noopener noreferrer"&gt;MongoDB Atlas&lt;/a&gt;, a cloud-hosted MongoDB service.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at MongoDB Atlas.&lt;/li&gt;
&lt;li&gt;Create a new project and cluster.&lt;/li&gt;
&lt;li&gt;Get the connection string by clicking "Connect" in the cluster dashboard. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Format:&lt;br&gt;
&lt;code&gt;mongodb+srv://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@cluster0.mongodb.net/&amp;lt;dbname&amp;gt;?retryWrites=true&amp;amp;w=majority&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;password&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;dbname&amp;gt;&lt;/code&gt; with your actual credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create a .env File&lt;/strong&gt;&lt;br&gt;
In the root of your Next.js project, create a file named .env.local. This file will hold your environment variables securely.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MONGODB_URI=mongodb+srv://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@cluster0.mongodb.net/&amp;lt;dbname&amp;gt;?retryWrites=true&amp;amp;w=majority&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make sure to replace the placeholders with your actual MongoDB connection string. This allows you to access the URI using process.env.MONGODB_URI in your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Create a Database Connection Utility&lt;/strong&gt;&lt;br&gt;
Create a utility file to manage the connection between your Next.js app and MongoDB. This file ensures that MongoDB connects efficiently, especially when handling multiple requests in a serverless environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;/lib/db.ts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose from 'mongoose';

const MONGODB_URI = process.env.MONGODB_URI;

if (!MONGODB_URI) {
  throw new Error('Please define the MONGODB_URI environment variable');
}

let cached = global.mongoose;

if (!cached) {
  cached = global.mongoose = { conn: null, promise: null };
}

async function dbConnect() {
  if (cached.conn) {
    return cached.conn;
  }

  if (!cached.promise) {
    const opts = {
      bufferCommands: false,
    };

    cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) =&amp;gt; {
      return mongoose;
    });
  }

  cached.conn = await cached.promise;
  return cached.conn;
}

export default dbConnect;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We define a &lt;code&gt;dbConnect&lt;/code&gt; function that ensures MongoDB connects once and reuses the connection for subsequent requests. This helps optimize performance in serverless environments like Vercel.&lt;/li&gt;
&lt;li&gt;If there’s already a connection (&lt;code&gt;cached.conn&lt;/code&gt;), it reuses it instead of reconnecting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Use the Connection in API Routes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we have the connection utility, let’s use it in an API route. Create a simple route that connects to MongoDB and returns all users.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/pages/api/users.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextApiRequest, NextApiResponse } from 'next';
import dbConnect from '@/lib/db';
import User from '@/lib/models/User';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  await dbConnect();

  const users = await User.find({});

  res.status(200).json({ success: true, data: users });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;p&gt;This API route connects to MongoDB and retrieves all users from the User model.&lt;br&gt;
The connection is established using dbConnect, ensuring MongoDB is connected before any database operations are performed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Define Mongoose Schema&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s define a simple schema for User using Mongoose. Create a User model under the lib/models directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/lib/models/User.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose, { Schema, Document } from 'mongoose';

export interface IUser extends Document {
  name: string;
  email: string;
  password: string;
}

const UserSchema: Schema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
});

const User = mongoose.models.User || mongoose.model&amp;lt;IUser&amp;gt;('User', UserSchema);

export default User;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;p&gt;This defines the structure of a User document in MongoDB.&lt;br&gt;
The schema ensures that each user has a name, email, and password, with validation to require all fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
In this guide, we demonstrated how to connect MongoDB to a Next.js application using Mongoose, how to set up MongoDB Atlas, and how to efficiently manage database connections in API routes.&lt;/p&gt;

&lt;p&gt;By following these steps, you can build scalable Next.js applications that work seamlessly with MongoDB. &lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>nextjs</category>
      <category>typescript</category>
      <category>database</category>
    </item>
    <item>
      <title>Mobile Development</title>
      <dc:creator>Hadiza Mohammed</dc:creator>
      <pubDate>Tue, 02 Jul 2024 08:18:38 +0000</pubDate>
      <link>https://forem.com/dee_codes/mobile-development-epa</link>
      <guid>https://forem.com/dee_codes/mobile-development-epa</guid>
      <description>&lt;p&gt;Hey there! Ever thought about creating cool apps for your phone? Here's your chance! Mobile development is an exciting space. Today, I want to share some insights about mobile development platforms, common software architecture patterns, and why I'm excited to join the HNG internship. Let's dive in and have some fun!&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile Development Platforms
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;React Native&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you ever considered building an app that works on iOS and Android without writing separate code for each? That’s where React Native comes in. Based on JavaScript and React, it allows you to develop cross-platform apps, by reusing a single codebase. If you’re familiar with React for web apps, it’s a smooth transition. However, achieving that perfect native feel sometimes requires extra effort and custom modules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flutter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s talk about Flutter, a framework created by Google. It uses a widget-based architecture, making it easy to design user interfaces. Flutter compiles directly to ARM, so it runs fast. Learning Dart can be challenging, but once mastered, it makes Flutter a powerful tool in your toolkit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Xamarin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Xamarin, developed by Microsoft, allows you to create apps using C#. If you're a fan of.NET, you'll feel right at home with Xamarin. It supports cross-platform development, enabling you to share a significant amount of code across iOS, Android, and Windows. Integrated with Visual Studio, it offers a dependable development environment. However, it may occasionally be slow to support the most recent platform features, and the apps created using Xamarin may be larger compared to native ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Software Architecture Patterns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MVC stands for Model-View-Controller. It's a way to organize apps. Imagine your app as a theater play: the Model is the script, the View is the stage, and the Controller is the director. It helps keep everything organized, but sometimes the controller can get overwhelmed, like a stressed-out director managing too many actors.&lt;/p&gt;

&lt;p&gt;MVVM (Model-View-Model) helps manage data and keep the view clean. It's great for maintainability and testability but can be challenging to learn.&lt;/p&gt;

&lt;p&gt;Clean architecture focuses on keeping code clean, modular, and manageable. It enforces separation of concerns and scalability for large projects, requiring a strong understanding of design principles.&lt;/p&gt;

&lt;p&gt;I'm excited to share that I've started the HNG Internship, which provides great learning opportunities with experienced developers, real-world projects, and skill enhancement. I'm looking forward to focusing on mobile development, collaborating with fellow interns, and learning from industry experts. The structured learning and practical experience will help me improve my skills. Being part of this community is very rewarding. If you're interested in the &lt;a href="https://hng.tech/internship"&gt;HNG Internship&lt;/a&gt;, check out their official &lt;a href="https://hng.tech/hire"&gt;website &lt;/a&gt;and explore the &lt;a href="https://hng.tech/premium"&gt;premium&lt;/a&gt; section for more information.&lt;/p&gt;

&lt;p&gt;Thanks for reading! I’d love to hear your thoughts and experiences, so feel free to drop a comment below. Let’s connect and support each other on this amazing journey!&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>reactnative</category>
      <category>xamarin</category>
      <category>flutter</category>
    </item>
    <item>
      <title>A difficult backend problem I had to solve</title>
      <dc:creator>Hadiza Mohammed</dc:creator>
      <pubDate>Mon, 01 Jul 2024 11:55:55 +0000</pubDate>
      <link>https://forem.com/dee_codes/a-difficult-backend-problem-i-had-to-solve-i3k</link>
      <guid>https://forem.com/dee_codes/a-difficult-backend-problem-i-had-to-solve-i3k</guid>
      <description>&lt;p&gt;Hey everyone! I recently faced a challenging backend problem while working on a project for my FreeCodeCamp certification. I want to share how I tackled it and why I'm excited about joining the HNG Internship.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Challenge: Associating Exercises with Users
&lt;/h4&gt;

&lt;p&gt;I was building an API that lets users create accounts, add exercises, and view their exercise logs. The tricky part was ensuring each exercise was correctly linked to the right user without creating duplicate data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Designing the Database Schema&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used MongoDB with Mongoose, creating separate schemas for users and exercises. The exercise schema included a reference to the user's ID, establishing a relationship between them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exerciseSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Implementing the Endpoint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, I created an endpoint to add exercises. It checked if the user existed, then added the exercise, linking it to the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/users/:_id/exercises&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exerciseDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newExercise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Exercise&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;exerciseDate&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;newExercise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exercise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to add exercise&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;exercise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;exercise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;exercise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDateString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Reflecting on the Experience
&lt;/h4&gt;

&lt;p&gt;This project taught me a lot about managing database relationships and handling asynchronous operations in NodeJS. It was a challenging but rewarding experience that boosted my confidence as a backend developer.&lt;/p&gt;

&lt;h4&gt;
  
  
  Joining the HNG Internship
&lt;/h4&gt;

&lt;p&gt;I’m super excited about the HNG Internship. It’s a fantastic opportunity to work on real-world projects, learn from experienced developers, and improve my skills. If you’re curious about the program, check out the &lt;a href="https://hng.tech/internship"&gt;internship page&lt;/a&gt; and their &lt;a href="https://hng.tech/premium"&gt;premium offerings&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Backend development can be tough, but solving these problems is incredibly fulfilling. I can’t wait to continue this journey with the HNG Internship and tackle even more exciting challenges. Thanks for reading, and I hope my experience inspires you to embrace the challenges you face in your development journey!&lt;/p&gt;

</description>
      <category>hng</category>
      <category>backend</category>
      <category>database</category>
      <category>node</category>
    </item>
    <item>
      <title>Turing Machine: Foundation of Computation</title>
      <dc:creator>Hadiza Mohammed</dc:creator>
      <pubDate>Fri, 21 Jun 2024 09:39:52 +0000</pubDate>
      <link>https://forem.com/dee_codes/turing-machine-foundation-of-computation-1144</link>
      <guid>https://forem.com/dee_codes/turing-machine-foundation-of-computation-1144</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/cs"&gt;DEV Computer Science Challenge v24.06.12: One Byte Explainer&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explainer
&lt;/h2&gt;

&lt;p&gt;The Turing Machine is a crucial and fundamental model of computation. It consists of an infinite tape and a read-and-write head for symbol manipulation. This powerful theoretical construct can simulate any algorithm, essential for understanding computability and complexity theory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Context
&lt;/h2&gt;

&lt;p&gt;The concept of Turing Machines was introduced by Alan Turing in 1936 to formalize the notion of algorithmic computation. Its simplicity and universality laid the groundwork for the theory of computability, influencing the development of modern computers and algorithms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://plato.stanford.edu/entries/turing-machine/"&gt;https://plato.stanford.edu/entries/turing-machine/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Turing_machine"&gt;https://en.wikipedia.org/wiki/Turing_machine&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>cschallenge</category>
      <category>computerscience</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
