<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stillnoturdad</title>
    <description>The latest articles on DEV Community by Stillnoturdad (@hopelesscoder).</description>
    <link>https://dev.to/hopelesscoder</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%2F1982449%2F0589dea2-b79d-4c73-888c-261a66d519b1.jpg</url>
      <title>DEV Community: Stillnoturdad</title>
      <link>https://dev.to/hopelesscoder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hopelesscoder"/>
    <language>en</language>
    <item>
      <title>Dive into Database Fun with Sequelize Migrations: Users, Vouchers, and Gifts, Oh My!</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Mon, 23 Sep 2024 02:30:26 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/dive-into-database-fun-with-sequelize-migrations-users-vouchers-and-gifts-oh-my-4p2g</link>
      <guid>https://dev.to/hopelesscoder/dive-into-database-fun-with-sequelize-migrations-users-vouchers-and-gifts-oh-my-4p2g</guid>
      <description>&lt;p&gt;Alright, grab your favorite beverage, kick back, and let’s take a stroll through the magical land of Sequelize migrations! You may think creating tables and handling data is dry, but trust me, this little piece of code is full of hidden treasures. Let's break it down and see what's really going on under the hood.&lt;/p&gt;

&lt;p&gt;-&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The User Table: Who Are You, Really?&lt;/strong&gt;&lt;br&gt;
First up, we’ve got our trusty Users table. This is where the magic happens for anyone signing up on your app. Every user gets an ID (because anonymity? Not in this database!), and it's auto-incremented because let's face it, counting is hard. Plus, we can’t have two users with the same email. So, the database is like, “Hey, email, you’re unique. Be proud of it.”&lt;/p&gt;

&lt;p&gt;The password is stored here too—though, hopefully, it's encrypted, because nobody wants to be that company with plain text passwords. Rounding things out, we have the timestamps for createdAt and updatedAt because, you know, little details kinda fun (yes its a bit confusing too but it's totally alright)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      email: {
        type: Sequelize.STRING,
        unique: true
      },
      password: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('Users');
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Another table for our beloved deals! Voucher!!&lt;/strong&gt;&lt;br&gt;
Now that we’ve got users, let’s sprinkle some fun with vouchers! Whether it’s 10% off your next pizza or a "buy one, get one" deal on sunglasses, this Vouchers table is where all the action is. Each voucher has a title (think: “Super Saver Deal”), a tag (for organizing all that goodness), and an image URL so you can gaze lovingly at the deal of the day.&lt;/p&gt;

&lt;p&gt;Once again, we’ve got those createdAt and updatedAt fields because, apparently, tracking is life&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('Vouchers', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      title: {
        type: Sequelize.STRING
      },
      tag: {
        type: Sequelize.STRING
      },
      imageUrl: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('Vouchers');
  }
};

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. AAAAND ANOTHER ONE!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Moving on to the Gifts table—because who doesn’t like to give (and receive) a little something special? This table connects users with vouchers in a delightful dance of generosity. Each gift has a message (probably something like “Here’s that pizza I owe you!”), and it links a sender and receiver (both users) with a fancy voucher.&lt;/p&gt;

&lt;p&gt;The database, being the responsible type, doesn’t let anything slide, so we’ve got references to both the Users and Vouchers tables to ensure everything matches up. And, of course, there’s a status field for when you want to know if your pizza coupon is still good or expired (tragic).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('Gifts', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      message: {
        type: Sequelize.STRING
      },
      senderId: {
        type: Sequelize.INTEGER,
        references: {
          model: "Users",
          key: "id"
        }
      },
      amount: {
        type: Sequelize.INTEGER
      },
      voucherId: {
        type: Sequelize.INTEGER,
        references: {
          model: "Vouchers",
          key: "id"
        }
      },
      receiverId: {
        type: Sequelize.INTEGER,
        references: {
          model: "Users",
          key: "id"
        }
      },
      status: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('Gifts');
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Seeding with Data: The Grand Finale&lt;/strong&gt;&lt;br&gt;
What’s a database without some actual data to play with? This is where the seeding part comes in. We’re pulling in some pre-made vouchers from a JSON file and injecting them right into the database. But wait, before doing that, we’re wiping out any existing IDs, so it feels fresh and clean. Then, we set the createdAt and updatedAt values to the current date because, well, we like to keep things real-time.&lt;/p&gt;

&lt;p&gt;With a flick of a command, we’ve bulk inserted our voucher data. And if you ever need to undo it? No problem. There’s a bulkDelete waiting in the wings to clean things up.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

'use strict';

/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up (queryInterface, Sequelize) {
    let data = require('../hacktiv_voucher.json').map(el =&amp;gt; {
      delete el.id
      el.createdAt = el.updatedAt = new Date()
      return el
    })
    await queryInterface.bulkInsert("Vouchers", data, {})
  },

  async down (queryInterface, Sequelize) {
    await queryInterface.bulkDelete("Vouchers", null, {})
  }
};



And There You Have It!
In just a few lines of code, we’ve built a mini ecosystem where users can grab some vouchers and send gifts to their friends. Each migration ensures the database is structured perfectly, and with the seed data, we’ve already got some vouchers to start the fun.

Now that our database is up and running, it’s time to go out there and treat yourself (and maybe a friend) to a gift!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>API OVERVIEW</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Sun, 22 Sep 2024 18:19:43 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/api-overview-3fa6</link>
      <guid>https://dev.to/hopelesscoder/api-overview-3fa6</guid>
      <description>&lt;p&gt;In this article, we’ll walk through a simple event ticketing system built with Node.js and Express. This system allows users to view discount codes, send event tickets, and manage tickets (such as claiming or deleting them). Let's break down how the API works!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get All Discount Codes (GET /discounts)
Imagine you have a bunch of discount codes for events, and you want users to be able to see them. This endpoint does exactly that by fetching all available discount codes from the database.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/discounts', async (req, res, next) =&amp;gt; {
    try {
        let discounts = await DiscountCode.findAll();
        res.status(200).json(discounts);
    } catch (error) {
        next(error);
    }
});

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

&lt;/div&gt;



&lt;p&gt;The GET /discounts route retrieves all discount codes from the DiscountCode model.&lt;br&gt;
If everything goes smoothly, it returns the discount codes in JSON format with a 200 OK status.&lt;br&gt;
In case of an error (e.g., database issues), it passes the error to the error-handling middleware.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send an Event Ticket (POST /tickets/:discountId)
This endpoint allows a user to send an event ticket to someone else, using a discount code. The user can send a custom message along with the ticket.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.post('/tickets/:discountId', async (req, res, next) =&amp;gt; {
    try {
        let { message, quantity, recipientId } = req.body;
        let { discountId } = req.params;
        let discount = await DiscountCode.findByPk(discountId);
        if (!discount) throw ({ name: "Custom", status: 404, message: "Discount not found" });

        let ticket = await EventTicket.create({
            message,
            senderId: req.member.id,
            quantity,
            discountId: discount.id,
            recipientId
        });
        res.status(201).json(ticket);
    } catch (error) {
        next(error);
    }
});

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

&lt;/div&gt;



&lt;p&gt;The user provides the discountId (via URL parameter), recipientId, a message, and the number of tickets (quantity) in the request body.&lt;br&gt;
The discount code is fetched from the database to ensure it exists. If not, the API throws an error.&lt;br&gt;
If everything checks out, the event ticket is created with the sender's ID, recipient's ID, and the associated discount code.&lt;br&gt;
The response contains the newly created ticket, with a 201 Created status.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get Event Tickets Received (GET /tickets)
This endpoint fetches all the event tickets a user has received. It also includes details about the discount associated with each ticket.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/tickets', async (req, res, next) =&amp;gt; {
    try {
        let tickets = await EventTicket.findAll({
            include: {
                model: DiscountCode,
                as: "discount",
                attributes: ["id", "title", "description"]
            },
            where: {
                recipientId: req.member.id
            }
        });
        if (tickets.length === 0) throw({ name: "Custom", status: 404, message: "Tickets not found" });
        res.status(200).json(tickets);
    } catch (error) {
        next(error);
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This route fetches all tickets where the current user is the recipient (recipientId matches the logged-in user).&lt;br&gt;
The response includes details about the discount code associated with each ticket (ID, title, and description).&lt;br&gt;
If no tickets are found, a 404 Not Found error is returned.&lt;br&gt;
Otherwise, the tickets are returned with a 200 OK status.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claim an Event Ticket (PATCH /tickets/:id/claim)
Once a user has received a ticket, they can claim it. This endpoint marks a ticket as "claimed."
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.patch('/tickets/:id/claim', authorization, async (req, res, next) =&amp;gt; {
    try {
        await EventTicket.update({ status: "claimed" }, {
            where: { id: req.params.id }
        });
        res.status(200).json({ message: "Ticket has been claimed" });
    } catch (error) {
        next(error);
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The route accepts a ticket ID (:id) and updates the status of that ticket to "claimed."&lt;br&gt;
The authorization middleware ensures the user is authorized to claim the ticket.&lt;br&gt;
After successfully updating the status, the server responds with a 200 OK and a success message.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Delete an Event Ticket (DELETE /tickets/:id)
This route allows the user to delete a specific event ticket.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Code:&lt;br&gt;
javascript&lt;br&gt;
Copy code&lt;br&gt;
app.delete('/tickets/:id', authorization, async (req, res, next) =&amp;gt; {&lt;br&gt;
    try {&lt;br&gt;
        await EventTicket.destroy({ where: { id: req.params.id } });&lt;br&gt;
        res.status(200).json({ message: "Ticket has been deleted" });&lt;br&gt;
    } catch (error) {&lt;br&gt;
        next(error);&lt;br&gt;
    }&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;The ticket is deleted based on its ID.&lt;br&gt;
The authorization middleware ensures that only the rightful owner of the ticket can delete it.&lt;br&gt;
After successful deletion, a 200 OK status is returned along with a confirmation message.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Middlewares For Baby Programmers</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Sun, 22 Sep 2024 18:15:13 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/middlewares-for-baby-programmers-1nb0</link>
      <guid>https://dev.to/hopelesscoder/middlewares-for-baby-programmers-1nb0</guid>
      <description>&lt;p&gt;In a secure web application, it's crucial to ensure that only authenticated users can access certain routes. Additionally, specific actions, such as modifying or deleting data, should only be allowed for users with proper permissions. This is where authentication and authorization come into play.&lt;/p&gt;

&lt;p&gt;In this article, we’ll break down a simple implementation of authentication and authorization middleware in a Node.js application using Express.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Authentication Middleware
&lt;/h2&gt;

&lt;p&gt;Authentication is the process of verifying that a user is who they claim to be. In this example, we use a JWT (JSON Web Token) to validate the user's identity before they can access protected routes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const authentication = async (req, res, next) =&amp;gt; {
    try {
        let { authorization } = req.headers;
        if (!authorization) throw { name: "InvalidToken" }; // No token provided

        const [bearer, token] = authorization.split(" ");
        if (bearer !== "Bearer") throw { name: "InvalidToken" }; // Invalid token format

        const payload = verifyToken(token); // Verify the token and get user data
        const member = await Member.findByPk(payload.id); // Find the user in the database

        if (!member) throw { name: "InvalidToken" }; // No matching user found

        req.member = { id: member.id }; // Attach user data to the request
        next(); // Pass to the next middleware or route handler
    } catch (error) {
        next(error); // Handle errors
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The token is expected to be in the Authorization header (formatted as Bearer token).&lt;br&gt;
The middleware verifies if the token is present and properly formatted.&lt;br&gt;
Using verifyToken(), it checks if the token is valid and decodes the user's data.&lt;br&gt;
The user's ID from the token payload is used to find them in the database.&lt;br&gt;
If successful, the user's ID is attached to the request (req.member), allowing other routes to know who the user is.&lt;br&gt;
If the token is missing, invalid, or the user doesn’t exist, an error is thrown.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Authorization Middleware
&lt;/h2&gt;

&lt;p&gt;Authorization controls what actions an authenticated user is allowed to perform. In this case, the authorization middleware ensures that a user can only interact with tickets they own.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const authorization = async (req, res, next) =&amp;gt; {
    try {
        let recipientId = req.member.id; // The authenticated user's ID
        let ticketId = req.params.id; // The ticket ID from the request

        let ticket = await EventTicket.findByPk(ticketId); // Find the ticket in the database
        if (!ticket) throw { name: "Custom", status: 404, message: "Ticket not found" }; // If ticket doesn't exist
        if (recipientId !== ticket.recipientId) throw { name: "Unauthorized" }; // If user doesn't own the ticket

        next(); // If authorized, proceed to the next middleware or route handler
    } catch (error) {
        next(error); // Handle errors
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The middleware retrieves the authenticated user’s ID (req.member.id) and the ticket ID from the request parameters (req.params.id).&lt;br&gt;
It checks if the ticket exists in the database.&lt;br&gt;
It ensures that the logged-in user (the recipient) is the owner of the ticket. If the user doesn’t own the ticket, an "Unauthorized" error is thrown.&lt;br&gt;
If the user is authorized, the middleware passes control to the next handler.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Error Handling Middleware
&lt;/h2&gt;

&lt;p&gt;The error-handling middleware ensures that errors caught during the request lifecycle are properly handled and returned as responses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use((error, req, res, next) =&amp;gt; {
    let status = error.status || 500; // Default to 500 if status isn't provided
    let message = error.message || "Internal server error"; // Default message

    switch (error.name) {
        case "SequelizeValidationError":
        case "SequelizeUniqueConstraintError":
            status = 400;
            message = error.errors[0].message; // Handle Sequelize validation errors
            break;
        case "InvalidToken":
        case "JsonWebTokenError":
            status = 401;
            message = "Invalid token"; // Handle token errors
            break;
        case "Unauthorized":
            status = 403;
            message = "You are not authorized"; // Handle unauthorized access
            break;
    }
    res.status(status).json({ message }); // Send error response
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How It Works:&lt;br&gt;
This middleware catches any errors passed down by the next(error) function.&lt;br&gt;
Depending on the error type, it sets the appropriate status code (e.g., 401 for invalid tokens, 403 for unauthorized actions, etc.).&lt;br&gt;
A relevant message is returned to the client, helping users understand what went wrong.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Implementing Registration and Login</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Sun, 22 Sep 2024 18:06:11 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/implementing-registration-and-login-10jf</link>
      <guid>https://dev.to/hopelesscoder/implementing-registration-and-login-10jf</guid>
      <description>&lt;p&gt;Implementing Member Registration and Login in a Node.js Application&lt;br&gt;
In modern web applications, user registration and authentication are fundamental functionalities. In this article, we'll go over how to implement member registration and login using a simple Node.js Express API. We'll be focusing on creating secure user accounts and handling authentication using JWT (JSON Web Token).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Member Registration (POST /register)
When a new user registers for your platform, the registration route is responsible for securely creating a new user record in the database. This involves capturing the user's details (such as email and password) and saving them after hashing the password for security purposes.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Member Registration: POST /register
app.post('/register', async (req, res, next) =&amp;gt; {
    try {
        let { email, password } = req.body;

        // Create new member with email and password
        let member = await Member.create({ email, password });

        // Return the new member's ID and email
        res.status(201).json({ id: member.id, email: member.email });
    } catch (error) {
        // Handle errors and pass to error middleware
        next(error);
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;How It Works:&lt;br&gt;
Request Body: The API expects an email and password in the request body.&lt;br&gt;
Member Creation: The Member.create() function creates a new user in the database with the provided email and password.&lt;br&gt;
Response: Upon successful registration, the response returns the new member's id and email with an HTTP status code of 201 (Created).&lt;br&gt;
This route ensures that user data is securely saved and password hashing is implemented behind the scenes (not shown here, but typically done using libraries like bcryptjs).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Member Login (POST /login)
The login route allows an existing user to authenticate by providing their email and password. After validating the credentials, a JWT token is generated and returned to the user, which they can use to authenticate subsequent requests.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Code Breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Member Login: POST /login
app.post('/login', async (req, res, next) =&amp;gt; {
    try {
        let { email, password } = req.body;

        // Check if email and password are provided
        if (!email) throw ({ name: "Custom", message: "Email is required" });
        if (!password) throw ({ name: "Custom", message: "Password is required" });

        // Find the member by email
        let member = await Member.findOne({ where: { email } });

        // Validate if the member exists and the password is correct
        if (!member || !comparePassword(password, member.password)) throw { name: "InvalidUser" };

        // Generate JWT token for the authenticated user
        res.status(200).json({ access_token: signToken({ id: member.id }) });
    } catch (error) {
        // Handle errors and pass to error middleware
        next(error);
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How It Works:&lt;/p&gt;

&lt;p&gt;Request Body: The API expects the email and password in the request body.&lt;/p&gt;

&lt;p&gt;Validation:&lt;br&gt;
The code checks whether both email and password fields are present in the request.&lt;br&gt;
It looks up the user in the database using the provided email. If no user is found or the password does not match, an error is thrown.&lt;/p&gt;

&lt;p&gt;Password Comparison: The comparePassword() function (typically using bcryptjs) checks whether the provided password matches the hashed password stored in the database.&lt;/p&gt;

&lt;p&gt;JWT Token Generation: If the credentials are valid, the signToken() function generates a JWT with the user's id as the payload. This token is sent back to the client in the response, and it can be used for subsequent authenticated requests.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ROUTER IS NOT THAT HARD THEY SAID</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Sun, 22 Sep 2024 18:01:23 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/router-is-not-that-hard-they-said-inj</link>
      <guid>https://dev.to/hopelesscoder/router-is-not-that-hard-they-said-inj</guid>
      <description>&lt;p&gt;Understanding app.js and router.js in a Node.js Application&lt;br&gt;
When building a Node.js application, especially with frameworks like Express, it's important to organize your project efficiently. Two critical components of this structure are the app.js file and the router system. These components help manage the flow of requests and improve the maintainability of the codebase.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore the roles of app.js and router.js, how they work together, and why they are important in building scalable and modular applications.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. What is app.js?
&lt;/h2&gt;

&lt;p&gt;The app.js file is the entry point of your Node.js application. It initializes the Express application, sets up middleware, and defines how requests are handled by routing them to different parts of the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const app = express();
const { Member, EventTicket, DiscountCode } = require("./models");
const { comparePassword } = require('./helpers/bcryptjs');
const { signToken, verifyToken } = require('./helpers/jwt');

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

// Root Endpoint
app.get('/', (req, res) =&amp;gt; {
  res.send('Welcome');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. What is router.js?
&lt;/h2&gt;

&lt;p&gt;The router.js file defines the application's routes and connects them to their respective controllers or handlers. This keeps the routing logic clean and modular, separating the core server logic (app.js) from the individual route definitions.&lt;br&gt;
**&lt;br&gt;
Key Responsibilities of router.js:**&lt;br&gt;
Define the endpoints (routes) of the application.&lt;br&gt;
Delegate the request handling to controllers or handler functions.&lt;br&gt;
Support different HTTP methods such as GET, POST, PUT, DELETE, etc.&lt;br&gt;
Enable modular routing by grouping related routes.&lt;/p&gt;

&lt;p&gt;Example of router.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// AUTH 
router.post('/register', UserController.register);
router.post('/login', UserController.login);

module.exports = router;

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

&lt;/div&gt;



&lt;p&gt;Route Delegation: app.js directs incoming requests to the appropriate route using app.use(). The routes are defined in router.js and specify how the requests are handled.&lt;/p&gt;

&lt;p&gt;Scalability: As your application grows, more routes and features will be added. Instead of placing all routes in app.js, they can be split into multiple files and grouped logically (e.g., userRouter.js, postRouter.js), improving maintainability and scalability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Benefits of Using app.js and router.js&lt;/strong&gt;&lt;br&gt;
Separation of Concerns: Keeping route definitions separate from application logic results in cleaner and more maintainable code.&lt;br&gt;
Easier Testing: With clear separation, it's easier to test routes independently without worrying about the rest of the application.&lt;br&gt;
Modular Routing: Group related routes together, which is especially helpful as the application grows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Both app.js and router.js are critical parts of a well-structured Node.js and Express application. app.js handles the initialization, middleware setup, and server configuration, while router.js defines the routing structure, connecting each endpoint to its corresponding controller or handler. This organization promotes cleaner, modular, and maintainable code that scales well as your application grows.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to: AUTHENTICATION</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Sun, 22 Sep 2024 17:40:05 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/how-to-authentication-26ma</link>
      <guid>https://dev.to/hopelesscoder/how-to-authentication-26ma</guid>
      <description>&lt;p&gt;When building web applications, it's important to manage user authentication securely. Two essential libraries for this are:&lt;/p&gt;

&lt;p&gt;bcryptjs – used to hash and compare passwords securely.&lt;br&gt;
JSON web token – used to sign and verify JWT tokens for user authentication.&lt;/p&gt;

&lt;p&gt;We will cover how to implement these two libraries in your Node.js application for secure password management and token-based authentication.&lt;/p&gt;

&lt;p&gt;How to: Use bcryptjs and jsonwebtoken in Node.js&lt;br&gt;
When building web applications, it's important to manage user authentication securely. Two essential libraries for this are:&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;1. Install the library:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Instal package&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install bcryptjs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now let me show you how to do the magic.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;2 . Hashing and Compare Password Like A Pro&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Same old, same old, make a new js file and always remember to require the package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { hashSync, compareSync } = require("bcryptjs");

module.exports = {
    hashPassword: (password) =&amp;gt; hashSync(password), 
    comparePassword: (password, hashed) =&amp;gt; compareSync(password, hashed
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;hashSync(password): Hashes the user's password.&lt;br&gt;
compareSync(password, hashedPassword): Compares the plain text password with the hashed version to validate user login.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Using jsonwebtoken for Token-Based Authentication
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Install the package:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install jsonwebtoken&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;jsonwebtoken allows us to create a secure token (JWT) for each authenticated user. This token is sent to the client and can be used to authenticate the user on subsequent requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { sign, verify } = require('jsonwebtoken');
const secretkey = "yoursecretkey"; // Secret key to sign the token

module.exports = {
    logToken: (payload) =&amp;gt; log(payload, secretkey), // Create JWT token
    verifyToken: (token) =&amp;gt; verify(token, secretkey)  // Verify JWT token
};

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;br&gt;
signToken(payload): Creates a signed JWT with the given payload (e.g., user data) using a secret key.&lt;/p&gt;

&lt;p&gt;verifyToken(token): Verifies the authenticity of the JWT token using the same secret key.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>helper</category>
    </item>
    <item>
      <title>basic image</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Fri, 13 Sep 2024 00:48:27 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/basic-image-ko4</link>
      <guid>https://dev.to/hopelesscoder/basic-image-ko4</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqxgzic5nwiq6xlb6oas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqxgzic5nwiq6xlb6oas.png" alt="Image description" width="647" height="625"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhncie04uvw4psy99lhkn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhncie04uvw4psy99lhkn.png" alt="Image description" width="746" height="745"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0kq4as4wdrcx9su4j53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0kq4as4wdrcx9su4j53.png" alt="Image description" width="794" height="788"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CRUD USING STATIC METHOD</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Wed, 04 Sep 2024 01:57:58 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/crud-using-static-method-4lig</link>
      <guid>https://dev.to/hopelesscoder/crud-using-static-method-4lig</guid>
      <description>&lt;p&gt;&lt;strong&gt;Read data from databases&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;static async getAllProdHouse() {
    try {
      const index = `
      SELECT cn.*, ph."name_fromnameTable"
      FROM "ClassName2" cn
      JOIN "ClassName1" cI
      ON cn."ClassName1Id" = cI.id
      ORDER BY cn.dateoryear DESC/ASC
    `
      const {rows} = await pool.query(index);
      const object = Factory.bulkname(rows);

      return object;
    } catch (error) {
      throw error;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create Data&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;static async createThings(name, Id) {
  try {
    let validation = this.validation(name);
    if (validation.length &amp;gt; 0) {
      throw validation;
    }
    const query = `
      INSERT INTO "ClassName2" ("name")
      VALUES ($1,) `;
    await pool.query(query, [name]);
  } catch (error) {
    throw error;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Delete Data&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;static async deleteTable(id) {
  try {
    const findCn = await this.findCnById(id);

    if (findCn.length === 0) {
      throw new Error("data cn not found");
    }

    const query = 'delete from "cn" where id = $1';

    await pool.query(query, [id]);
  } catch (error) {
    throw error;
  }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Find Data&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;static async findCnById(id) {
  try {
    const index = `
      SELECT cn.*, ph."name_fromnameTable"
      FROM "ClassName2" cn
      JOIN "ClassName1" cI
      ON cn."ClassName1Id" = cI.id
      WHERE cn.id = $1
    `;

    const { rows } = await pool.query(query, [id]);
    const instance = Factory.bulkCn(rows);

    return instance;
  } catch (error) {
    throw error;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Update Data&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;static async updateCn(id, name) {
  try {
    let validation = this.validation(name, date);

    if (validation.length &amp;gt; 0) {
      throw validation;
    }

    const query = `
      UPDATE "Cn"
      SET "name" = $1,
          "date" = $2,

      WHERE "id" = $5
    `;

    await pool.query(query, [name, date id]);
  } catch (error) {
    throw error;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Validation Data&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;static validation(name, date) {
  let errors = [];

  if (!name) {
    errors[0] = "name empty";
  }

  return errors;
}
}

Module.export = Model


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

&lt;/div&gt;



</description>
      <category>javascript</category>
    </item>
    <item>
      <title>How to read multiple value from web</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Tue, 03 Sep 2024 22:47:45 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/how-to-read-multiple-value-from-web-1pgo</link>
      <guid>https://dev.to/hopelesscoder/how-to-read-multiple-value-from-web-1pgo</guid>
      <description>&lt;p&gt;In Node.js, working with data often involves reading from files and inserting those data into databases. Below is how to read JSON data from a file, process it, and format it for a SQL INSERT statement:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using fs.readFile method to read the contents of a file&lt;/li&gt;
&lt;li&gt;Use JSON.parse to convert the JSON string into an object&lt;/li&gt;
&lt;li&gt;Iterates over each element in the JSON array using .map(). Inside the .map() function, specific fields from each JSON object are restructured.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example: &lt;br&gt;
&lt;code&gt;const dataEntries = JSON.parse(await fs.readFile('./filename.json', 'utf-8'))&lt;br&gt;
    .map(element =&amp;gt; {&lt;br&gt;
        const { value1, value2 } = element;&lt;br&gt;
        return&lt;/code&gt;('${value1}', '${value2}')&lt;code&gt;;&lt;br&gt;
    });&lt;/code&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>CONFIGURE EXPRESS WITH .EJS TEMPLATE</title>
      <dc:creator>Stillnoturdad</dc:creator>
      <pubDate>Sun, 01 Sep 2024 19:30:10 +0000</pubDate>
      <link>https://dev.to/hopelesscoder/configure-express-with-ejs-template-1ach</link>
      <guid>https://dev.to/hopelesscoder/configure-express-with-ejs-template-1ach</guid>
      <description>&lt;p&gt;Usually, I use the classic starter one.&lt;br&gt;
&lt;a href="https://expressjs.com/en/starter/hello-world.html#:~:text=const%20express%20%3D%20require(%27express%27)%0Aconst%20app%20%3D%20express()%0Aconst%20port%20%3D%203000" rel="noopener noreferrer"&gt;Expressjs.com&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const app = express()
const port = 3000

app.set('view engine', 'pug')
app.use(express.urlencoded({ extended: true }))
app.use('/', require("./routers"))

app.listen(port, () =&amp;gt; {
    console.log(`YOU'RE IN ${port}`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you use the &lt;code&gt;res.render('anyClassViewName')&lt;/code&gt; , Express will search for any .ejs file in your views directory and then render it. &lt;/p&gt;

&lt;p&gt;Express.urlencoded is made to handle urlencoded payloads. You can use the { extended: true } option to deal with complex objects, arrays, and nested objects, or you can set it to 'false' for simpler data parsing.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>basic</category>
    </item>
  </channel>
</rss>
